Skip to content

Commit 9f78885

Browse files
committed
In feature_gate::MacroVisitor, find feature occurrences within macro arguments.
Fix #22234
1 parent cca1cf6 commit 9f78885

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

src/libsyntax/feature_gate.rs

+37-21
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ use attr;
3131
use attr::AttrMetaMethods;
3232
use codemap::{CodeMap, Span};
3333
use diagnostic::SpanHandler;
34+
use ext::tt;
3435
use visit;
3536
use visit::Visitor;
36-
use parse::token::{self, InternedString};
37+
use parse::token::{self, InternedString, IdentStyle};
3738

3839
use std::slice;
3940
use std::ascii::AsciiExt;
@@ -225,29 +226,44 @@ struct MacroVisitor<'a> {
225226
context: &'a Context<'a>
226227
}
227228

229+
impl<'a> MacroVisitor<'a> {
230+
fn check_ident(&self, id: ast::Ident, span: Span) {
231+
for &(s, readable) in &[("asm", "inline assembly"),
232+
("log_syntax", "`log_syntax!`"),
233+
("trace_macros", "`trace_macros`"),
234+
("concat_idents", "`concat_idents`")] {
235+
if id.as_str() == s {
236+
self.context.gate_feature(
237+
s, span, &format!("{} is not stable enough for use \
238+
and is subject to change", readable));
239+
}
240+
}
241+
}
242+
}
243+
228244
impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
229245
fn visit_mac(&mut self, mac: &ast::Mac) {
230-
let ast::MacInvocTT(ref path, _, _) = mac.node;
246+
let ast::MacInvocTT(ref path, ref tts, _) = mac.node;
231247
let id = path.segments.last().unwrap().identifier;
232-
233-
if id == token::str_to_ident("asm") {
234-
self.context.gate_feature("asm", path.span, "inline assembly is not \
235-
stable enough for use and is subject to change");
236-
}
237-
238-
else if id == token::str_to_ident("log_syntax") {
239-
self.context.gate_feature("log_syntax", path.span, "`log_syntax!` is not \
240-
stable enough for use and is subject to change");
241-
}
242-
243-
else if id == token::str_to_ident("trace_macros") {
244-
self.context.gate_feature("trace_macros", path.span, "`trace_macros` is not \
245-
stable enough for use and is subject to change");
246-
}
247-
248-
else if id == token::str_to_ident("concat_idents") {
249-
self.context.gate_feature("concat_idents", path.span, "`concat_idents` is not \
250-
stable enough for use and is subject to change");
248+
self.check_ident(id, path.span);
249+
250+
// Issue 22234: process arguments to macro invocation as well,
251+
// searching for use of feature-gated macros there.
252+
let mut tt_reader = tt::transcribe::new_tt_reader(
253+
self.context.span_handler, None, None, tts.clone());
254+
let mut curr = tt::transcribe::tt_next_token(&mut tt_reader);
255+
if curr.tok != token::Eof {
256+
loop {
257+
let next = tt::transcribe::tt_next_token(&mut tt_reader);
258+
if next.tok == token::Eof { break; }
259+
if next.tok == token::Whitespace { continue; }
260+
if next.tok == token::Not {
261+
if let token::Ident(id, IdentStyle::Plain) = curr.tok {
262+
self.check_ident(id, curr.sp);
263+
}
264+
}
265+
curr = next;
266+
}
251267
}
252268
}
253269
}

src/test/compile-fail/issue-22234.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Check that macro-invocations within macro-invocations still cause
12+
// feature-gate checks to fire.
13+
14+
fn main() {
15+
unsafe {
16+
print!("Hello {:?}", asm!("")); //~ ERROR inline assembly is not stable
17+
}
18+
}

0 commit comments

Comments
 (0)