Skip to content

Commit

Permalink
In feature_gate::MacroVisitor, find feature occurrences within macro …
Browse files Browse the repository at this point in the history
…arguments.

Fix rust-lang#22234
  • Loading branch information
pnkfelix committed Feb 12, 2015
1 parent cca1cf6 commit 9f78885
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 21 deletions.
58 changes: 37 additions & 21 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ use attr;
use attr::AttrMetaMethods;
use codemap::{CodeMap, Span};
use diagnostic::SpanHandler;
use ext::tt;
use visit;
use visit::Visitor;
use parse::token::{self, InternedString};
use parse::token::{self, InternedString, IdentStyle};

use std::slice;
use std::ascii::AsciiExt;
Expand Down Expand Up @@ -225,29 +226,44 @@ struct MacroVisitor<'a> {
context: &'a Context<'a>
}

impl<'a> MacroVisitor<'a> {
fn check_ident(&self, id: ast::Ident, span: Span) {
for &(s, readable) in &[("asm", "inline assembly"),
("log_syntax", "`log_syntax!`"),
("trace_macros", "`trace_macros`"),
("concat_idents", "`concat_idents`")] {
if id.as_str() == s {
self.context.gate_feature(
s, span, &format!("{} is not stable enough for use \
and is subject to change", readable));
}
}
}
}

impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
fn visit_mac(&mut self, mac: &ast::Mac) {
let ast::MacInvocTT(ref path, _, _) = mac.node;
let ast::MacInvocTT(ref path, ref tts, _) = mac.node;
let id = path.segments.last().unwrap().identifier;

if id == token::str_to_ident("asm") {
self.context.gate_feature("asm", path.span, "inline assembly is not \
stable enough for use and is subject to change");
}

else if id == token::str_to_ident("log_syntax") {
self.context.gate_feature("log_syntax", path.span, "`log_syntax!` is not \
stable enough for use and is subject to change");
}

else if id == token::str_to_ident("trace_macros") {
self.context.gate_feature("trace_macros", path.span, "`trace_macros` is not \
stable enough for use and is subject to change");
}

else if id == token::str_to_ident("concat_idents") {
self.context.gate_feature("concat_idents", path.span, "`concat_idents` is not \
stable enough for use and is subject to change");
self.check_ident(id, path.span);

// Issue 22234: process arguments to macro invocation as well,
// searching for use of feature-gated macros there.
let mut tt_reader = tt::transcribe::new_tt_reader(
self.context.span_handler, None, None, tts.clone());
let mut curr = tt::transcribe::tt_next_token(&mut tt_reader);
if curr.tok != token::Eof {
loop {
let next = tt::transcribe::tt_next_token(&mut tt_reader);
if next.tok == token::Eof { break; }
if next.tok == token::Whitespace { continue; }
if next.tok == token::Not {
if let token::Ident(id, IdentStyle::Plain) = curr.tok {
self.check_ident(id, curr.sp);
}
}
curr = next;
}
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/test/compile-fail/issue-22234.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Check that macro-invocations within macro-invocations still cause
// feature-gate checks to fire.

fn main() {
unsafe {
print!("Hello {:?}", asm!("")); //~ ERROR inline assembly is not stable
}
}

0 comments on commit 9f78885

Please sign in to comment.