Skip to content

Commit dc0797c

Browse files
committed
Address the other cases of rust-lang#22234; fix rust-lang#22234.
The other cases: `concat_idents!`, `log_syntax!`, and `trace_macros!`, (these macros, with `asm!`, are handled (eagerly) in feature_gate.rs).
1 parent 52bdda7 commit dc0797c

11 files changed

+199
-6
lines changed

src/libsyntax/ext/concat_idents.rs

+9
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@ use ast;
1212
use codemap::Span;
1313
use ext::base::*;
1414
use ext::base;
15+
use feature_gate;
1516
use parse::token;
1617
use parse::token::{str_to_ident};
1718
use ptr::P;
1819

1920
pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
2021
-> Box<base::MacResult+'cx> {
22+
if !cx.ecfg.enable_concat_idents() {
23+
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
24+
"concat_idents",
25+
sp,
26+
feature_gate::EXPLAIN_CONCAT_IDENTS);
27+
return base::DummyResult::expr(sp);
28+
}
29+
2130
let mut res_str = String::new();
2231
for (i, e) in tts.iter().enumerate() {
2332
if i & 1 == 1 {

src/libsyntax/ext/expand.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,27 @@ impl<'feat> ExpansionConfig<'feat> {
14361436
_ => false,
14371437
}
14381438
}
1439+
1440+
pub fn enable_log_syntax(&self) -> bool {
1441+
match self.features {
1442+
Some(&Features { allow_log_syntax: true, .. }) => true,
1443+
_ => false,
1444+
}
1445+
}
1446+
1447+
pub fn enable_concat_idents(&self) -> bool {
1448+
match self.features {
1449+
Some(&Features { allow_concat_idents: true, .. }) => true,
1450+
_ => false,
1451+
}
1452+
}
1453+
1454+
pub fn enable_trace_macros(&self) -> bool {
1455+
match self.features {
1456+
Some(&Features { allow_trace_macros: true, .. }) => true,
1457+
_ => false,
1458+
}
1459+
}
14391460
}
14401461

14411462
pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,

src/libsyntax/ext/log_syntax.rs

+8
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,20 @@
1111
use ast;
1212
use codemap;
1313
use ext::base;
14+
use feature_gate;
1415
use print;
1516

1617
pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
1718
sp: codemap::Span,
1819
tts: &[ast::TokenTree])
1920
-> Box<base::MacResult+'cx> {
21+
if !cx.ecfg.enable_log_syntax() {
22+
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
23+
"log_syntax",
24+
sp,
25+
feature_gate::EXPLAIN_LOG_SYNTAX);
26+
return base::DummyResult::any(sp);
27+
}
2028

2129
cx.print_backtrace();
2230

src/libsyntax/ext/trace_macros.rs

+10
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,23 @@ use ast;
1212
use codemap::Span;
1313
use ext::base::ExtCtxt;
1414
use ext::base;
15+
use feature_gate;
1516
use parse::token::keywords;
1617

1718

1819
pub fn expand_trace_macros(cx: &mut ExtCtxt,
1920
sp: Span,
2021
tt: &[ast::TokenTree])
2122
-> Box<base::MacResult+'static> {
23+
if !cx.ecfg.enable_trace_macros() {
24+
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
25+
"trace_macros",
26+
sp,
27+
feature_gate::EXPLAIN_TRACE_MACROS);
28+
return base::DummyResult::any(sp);
29+
}
30+
31+
2232
match tt {
2333
[ast::TtToken(_, ref tok)] if tok.is_keyword(keywords::True) => {
2434
cx.set_trace_macros(true);

src/libsyntax/feature_gate.rs

+32-6
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ pub struct Features {
158158
pub visible_private_types: bool,
159159
pub allow_quote: bool,
160160
pub allow_asm: bool,
161+
pub allow_log_syntax: bool,
162+
pub allow_concat_idents: bool,
163+
pub allow_trace_macros: bool,
161164
pub old_orphan_check: bool,
162165
pub simd_ffi: bool,
163166
pub unmarked_api: bool,
@@ -175,6 +178,9 @@ impl Features {
175178
visible_private_types: false,
176179
allow_quote: false,
177180
allow_asm: false,
181+
allow_log_syntax: false,
182+
allow_concat_idents: false,
183+
allow_trace_macros: false,
178184
old_orphan_check: false,
179185
simd_ffi: false,
180186
unmarked_api: false,
@@ -226,6 +232,15 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain:
226232
pub const EXPLAIN_ASM: &'static str =
227233
"inline assembly is not stable enough for use and is subject to change";
228234

235+
pub const EXPLAIN_LOG_SYNTAX: &'static str =
236+
"`log_syntax!` is not stable enough for use and is subject to change";
237+
238+
pub const EXPLAIN_CONCAT_IDENTS: &'static str =
239+
"`concat_idents` is not stable enough for use and is subject to change";
240+
241+
pub const EXPLAIN_TRACE_MACROS: &'static str =
242+
"`trace_macros` is not stable enough for use and is subject to change";
243+
229244
struct MacroVisitor<'a> {
230245
context: &'a Context<'a>
231246
}
@@ -235,23 +250,28 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
235250
let ast::MacInvocTT(ref path, _, _) = mac.node;
236251
let id = path.segments.last().unwrap().identifier;
237252

253+
// Issue 22234: If you add a new case here, make sure to also
254+
// add code to catch the macro during or after expansion.
255+
//
256+
// We still keep this MacroVisitor (rather than *solely*
257+
// relying on catching cases during or after expansion) to
258+
// catch uses of these macros within conditionally-compiled
259+
// code, e.g. `#[cfg]`-guarded functions.
260+
238261
if id == token::str_to_ident("asm") {
239262
self.context.gate_feature("asm", path.span, EXPLAIN_ASM);
240263
}
241264

242265
else if id == token::str_to_ident("log_syntax") {
243-
self.context.gate_feature("log_syntax", path.span, "`log_syntax!` is not \
244-
stable enough for use and is subject to change");
266+
self.context.gate_feature("log_syntax", path.span, EXPLAIN_LOG_SYNTAX);
245267
}
246268

247269
else if id == token::str_to_ident("trace_macros") {
248-
self.context.gate_feature("trace_macros", path.span, "`trace_macros` is not \
249-
stable enough for use and is subject to change");
270+
self.context.gate_feature("trace_macros", path.span, EXPLAIN_TRACE_MACROS);
250271
}
251272

252273
else if id == token::str_to_ident("concat_idents") {
253-
self.context.gate_feature("concat_idents", path.span, "`concat_idents` is not \
254-
stable enough for use and is subject to change");
274+
self.context.gate_feature("concat_idents", path.span, EXPLAIN_CONCAT_IDENTS);
255275
}
256276
}
257277
}
@@ -594,12 +614,18 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
594614

595615
check(&mut cx, krate);
596616

617+
// FIXME (pnkfelix): Before adding the 99th entry below, change it
618+
// to a single-pass (instead of N calls to `.has_feature`).
619+
597620
Features {
598621
unboxed_closures: cx.has_feature("unboxed_closures"),
599622
rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
600623
visible_private_types: cx.has_feature("visible_private_types"),
601624
allow_quote: cx.has_feature("quote"),
602625
allow_asm: cx.has_feature("asm"),
626+
allow_log_syntax: cx.has_feature("log_syntax"),
627+
allow_concat_idents: cx.has_feature("concat_idents"),
628+
allow_trace_macros: cx.has_feature("trace_macros"),
603629
old_orphan_check: cx.has_feature("old_orphan_check"),
604630
simd_ffi: cx.has_feature("simd_ffi"),
605631
unmarked_api: cx.has_feature("unmarked_api"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
const XY_1: i32 = 10;
12+
13+
fn main() {
14+
const XY_2: i32 = 20;
15+
let a = concat_idents!(X, Y_1); //~ ERROR `concat_idents` is not stable
16+
let b = concat_idents!(X, Y_2); //~ ERROR `concat_idents` is not stable
17+
assert_eq!(a, 10);
18+
assert_eq!(b, 20);
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
const XY_1: i32 = 10;
12+
13+
fn main() {
14+
const XY_2: i32 = 20;
15+
assert_eq!(10, concat_idents!(X, Y_1)); //~ ERROR `concat_idents` is not stable
16+
assert_eq!(20, concat_idents!(X, Y_2)); //~ ERROR `concat_idents` is not stable
17+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2012 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+
fn main() {
12+
println!("{}", log_syntax!()); //~ ERROR `log_syntax!` is not stable
13+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
// Test that the trace_macros feature gate is on.
12+
13+
fn main() {
14+
trace_macros!(); //~ ERROR `trace_macros` is not stable
15+
trace_macros!(1); //~ ERROR `trace_macros` is not stable
16+
trace_macros!(ident); //~ ERROR `trace_macros` is not stable
17+
trace_macros!(for); //~ ERROR `trace_macros` is not stable
18+
trace_macros!(true,); //~ ERROR `trace_macros` is not stable
19+
trace_macros!(false 1); //~ ERROR `trace_macros` is not stable
20+
21+
// Errors are signalled early for the above, before expansion.
22+
// See trace_macros-gate2 and trace_macros-gate3. for examples
23+
// of the below being caught.
24+
25+
macro_rules! expando {
26+
($x: ident) => { trace_macros!($x) }
27+
}
28+
29+
expando!(true);
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
// Test that the trace_macros feature gate is on.
12+
13+
fn main() {
14+
// (Infrastructure does not attempt to detect uses in macro definitions.)
15+
macro_rules! expando {
16+
($x: ident) => { trace_macros!($x) }
17+
}
18+
19+
expando!(true); //~ ERROR `trace_macros` is not stable
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
// Test that the trace_macros feature gate is on.
12+
13+
pub fn main() {
14+
println!("arg: {}", trace_macros!()); //~ ERROR `trace_macros` is not stable
15+
println!("arg: {}", trace_macros!(1)); //~ ERROR `trace_macros` is not stable
16+
println!("arg: {}", trace_macros!(ident)); //~ ERROR `trace_macros` is not stable
17+
println!("arg: {}", trace_macros!(for)); //~ ERROR `trace_macros` is not stable
18+
println!("arg: {}", trace_macros!(true,)); //~ ERROR `trace_macros` is not stable
19+
println!("arg: {}", trace_macros!(false 1)); //~ ERROR `trace_macros` is not stable
20+
}

0 commit comments

Comments
 (0)