about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2015-02-15 23:49:55 +0100
committerFelix S. Klock II <pnkfelix@pnkfx.org>2015-02-16 01:36:06 +0100
commitdc0797c0c99e7079170d0e09f82fc6f66b721932 (patch)
tree5b0e828bc786427580c67ade6f7a26f1390997a3
parent52bdda778ad595e661d06b16a193b3affe443d41 (diff)
downloadrust-dc0797c0c99e7079170d0e09f82fc6f66b721932.tar.gz
rust-dc0797c0c99e7079170d0e09f82fc6f66b721932.zip
Address the other cases of #22234; fix #22234.
The other cases: `concat_idents!`, `log_syntax!`, and `trace_macros!`,
(these macros, with `asm!`, are handled (eagerly) in feature_gate.rs).
-rw-r--r--src/libsyntax/ext/concat_idents.rs9
-rw-r--r--src/libsyntax/ext/expand.rs21
-rw-r--r--src/libsyntax/ext/log_syntax.rs8
-rw-r--r--src/libsyntax/ext/trace_macros.rs10
-rw-r--r--src/libsyntax/feature_gate.rs38
-rw-r--r--src/test/compile-fail/concat_idents-gate.rs19
-rw-r--r--src/test/compile-fail/concat_idents-gate2.rs17
-rw-r--r--src/test/compile-fail/log-syntax-gate2.rs13
-rw-r--r--src/test/compile-fail/trace_macros-gate.rs30
-rw-r--r--src/test/compile-fail/trace_macros-gate2.rs20
-rw-r--r--src/test/compile-fail/trace_macros-gate3.rs20
11 files changed, 199 insertions, 6 deletions
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 364cacd735c..63a8bd9ddf1 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -12,12 +12,21 @@ use ast;
 use codemap::Span;
 use ext::base::*;
 use ext::base;
+use feature_gate;
 use parse::token;
 use parse::token::{str_to_ident};
 use ptr::P;
 
 pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
+    if !cx.ecfg.enable_concat_idents() {
+        feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+                                       "concat_idents",
+                                       sp,
+                                       feature_gate::EXPLAIN_CONCAT_IDENTS);
+        return base::DummyResult::expr(sp);
+    }
+
     let mut res_str = String::new();
     for (i, e) in tts.iter().enumerate() {
         if i & 1 == 1 {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index e31c1a32749..72dc717910b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1436,6 +1436,27 @@ impl<'feat> ExpansionConfig<'feat> {
             _ => false,
         }
     }
+
+    pub fn enable_log_syntax(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_log_syntax: true, .. }) => true,
+            _ => false,
+        }
+    }
+
+    pub fn enable_concat_idents(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_concat_idents: true, .. }) => true,
+            _ => false,
+        }
+    }
+
+    pub fn enable_trace_macros(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_trace_macros: true, .. }) => true,
+            _ => false,
+        }
+    }
 }
 
 pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,
diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs
index 30301e3b8cc..8173dd93f74 100644
--- a/src/libsyntax/ext/log_syntax.rs
+++ b/src/libsyntax/ext/log_syntax.rs
@@ -11,12 +11,20 @@
 use ast;
 use codemap;
 use ext::base;
+use feature_gate;
 use print;
 
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
                               sp: codemap::Span,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
+    if !cx.ecfg.enable_log_syntax() {
+        feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+                                       "log_syntax",
+                                       sp,
+                                       feature_gate::EXPLAIN_LOG_SYNTAX);
+        return base::DummyResult::any(sp);
+    }
 
     cx.print_backtrace();
 
diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs
index 76f7b7b0d7b..3fcc6a8d692 100644
--- a/src/libsyntax/ext/trace_macros.rs
+++ b/src/libsyntax/ext/trace_macros.rs
@@ -12,6 +12,7 @@ use ast;
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::base;
+use feature_gate;
 use parse::token::keywords;
 
 
@@ -19,6 +20,15 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
                            sp: Span,
                            tt: &[ast::TokenTree])
                            -> Box<base::MacResult+'static> {
+    if !cx.ecfg.enable_trace_macros() {
+        feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+                                       "trace_macros",
+                                       sp,
+                                       feature_gate::EXPLAIN_TRACE_MACROS);
+        return base::DummyResult::any(sp);
+    }
+
+
     match tt {
         [ast::TtToken(_, ref tok)] if tok.is_keyword(keywords::True) => {
             cx.set_trace_macros(true);
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 9d14f894a46..5e29f3a6b69 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -158,6 +158,9 @@ pub struct Features {
     pub visible_private_types: bool,
     pub allow_quote: bool,
     pub allow_asm: bool,
+    pub allow_log_syntax: bool,
+    pub allow_concat_idents: bool,
+    pub allow_trace_macros: bool,
     pub old_orphan_check: bool,
     pub simd_ffi: bool,
     pub unmarked_api: bool,
@@ -175,6 +178,9 @@ impl Features {
             visible_private_types: false,
             allow_quote: false,
             allow_asm: false,
+            allow_log_syntax: false,
+            allow_concat_idents: false,
+            allow_trace_macros: false,
             old_orphan_check: false,
             simd_ffi: false,
             unmarked_api: false,
@@ -226,6 +232,15 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain:
 pub const EXPLAIN_ASM: &'static str =
     "inline assembly is not stable enough for use and is subject to change";
 
+pub const EXPLAIN_LOG_SYNTAX: &'static str =
+    "`log_syntax!` is not stable enough for use and is subject to change";
+
+pub const EXPLAIN_CONCAT_IDENTS: &'static str =
+    "`concat_idents` is not stable enough for use and is subject to change";
+
+pub const EXPLAIN_TRACE_MACROS: &'static str =
+    "`trace_macros` is not stable enough for use and is subject to change";
+
 struct MacroVisitor<'a> {
     context: &'a Context<'a>
 }
@@ -235,23 +250,28 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
         let ast::MacInvocTT(ref path, _, _) = mac.node;
         let id = path.segments.last().unwrap().identifier;
 
+        // Issue 22234: If you add a new case here, make sure to also
+        // add code to catch the macro during or after expansion.
+        //
+        // We still keep this MacroVisitor (rather than *solely*
+        // relying on catching cases during or after expansion) to
+        // catch uses of these macros within conditionally-compiled
+        // code, e.g. `#[cfg]`-guarded functions.
+
         if id == token::str_to_ident("asm") {
             self.context.gate_feature("asm", path.span, EXPLAIN_ASM);
         }
 
         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");
+            self.context.gate_feature("log_syntax", path.span, EXPLAIN_LOG_SYNTAX);
         }
 
         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");
+            self.context.gate_feature("trace_macros", path.span, EXPLAIN_TRACE_MACROS);
         }
 
         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.context.gate_feature("concat_idents", path.span, EXPLAIN_CONCAT_IDENTS);
         }
     }
 }
@@ -594,12 +614,18 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
 
     check(&mut cx, krate);
 
+    // FIXME (pnkfelix): Before adding the 99th entry below, change it
+    // to a single-pass (instead of N calls to `.has_feature`).
+
     Features {
         unboxed_closures: cx.has_feature("unboxed_closures"),
         rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
         visible_private_types: cx.has_feature("visible_private_types"),
         allow_quote: cx.has_feature("quote"),
         allow_asm: cx.has_feature("asm"),
+        allow_log_syntax: cx.has_feature("log_syntax"),
+        allow_concat_idents: cx.has_feature("concat_idents"),
+        allow_trace_macros: cx.has_feature("trace_macros"),
         old_orphan_check: cx.has_feature("old_orphan_check"),
         simd_ffi: cx.has_feature("simd_ffi"),
         unmarked_api: cx.has_feature("unmarked_api"),
diff --git a/src/test/compile-fail/concat_idents-gate.rs b/src/test/compile-fail/concat_idents-gate.rs
new file mode 100644
index 00000000000..f4d97445725
--- /dev/null
+++ b/src/test/compile-fail/concat_idents-gate.rs
@@ -0,0 +1,19 @@
+// 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.
+
+const XY_1: i32 = 10;
+
+fn main() {
+    const XY_2: i32 = 20;
+    let a = concat_idents!(X, Y_1); //~ ERROR `concat_idents` is not stable
+    let b = concat_idents!(X, Y_2); //~ ERROR `concat_idents` is not stable
+    assert_eq!(a, 10);
+    assert_eq!(b, 20);
+}
diff --git a/src/test/compile-fail/concat_idents-gate2.rs b/src/test/compile-fail/concat_idents-gate2.rs
new file mode 100644
index 00000000000..d8f8f803edc
--- /dev/null
+++ b/src/test/compile-fail/concat_idents-gate2.rs
@@ -0,0 +1,17 @@
+// 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.
+
+const XY_1: i32 = 10;
+
+fn main() {
+    const XY_2: i32 = 20;
+    assert_eq!(10, concat_idents!(X, Y_1)); //~ ERROR `concat_idents` is not stable
+    assert_eq!(20, concat_idents!(X, Y_2)); //~ ERROR `concat_idents` is not stable
+}
diff --git a/src/test/compile-fail/log-syntax-gate2.rs b/src/test/compile-fail/log-syntax-gate2.rs
new file mode 100644
index 00000000000..bb19e97ab0f
--- /dev/null
+++ b/src/test/compile-fail/log-syntax-gate2.rs
@@ -0,0 +1,13 @@
+// Copyright 2012 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.
+
+fn main() {
+    println!("{}", log_syntax!()); //~ ERROR `log_syntax!` is not stable
+}
diff --git a/src/test/compile-fail/trace_macros-gate.rs b/src/test/compile-fail/trace_macros-gate.rs
new file mode 100644
index 00000000000..6473bcece91
--- /dev/null
+++ b/src/test/compile-fail/trace_macros-gate.rs
@@ -0,0 +1,30 @@
+// 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.
+
+// Test that the trace_macros feature gate is on.
+
+fn main() {
+    trace_macros!(); //~ ERROR `trace_macros` is not stable
+    trace_macros!(1); //~ ERROR `trace_macros` is not stable
+    trace_macros!(ident); //~ ERROR `trace_macros` is not stable
+    trace_macros!(for); //~ ERROR `trace_macros` is not stable
+    trace_macros!(true,); //~ ERROR `trace_macros` is not stable
+    trace_macros!(false 1); //~ ERROR `trace_macros` is not stable
+
+    // Errors are signalled early for the above, before expansion.
+    // See trace_macros-gate2 and trace_macros-gate3. for examples
+    // of the below being caught.
+
+    macro_rules! expando {
+        ($x: ident) => { trace_macros!($x) }
+    }
+
+    expando!(true);
+}
diff --git a/src/test/compile-fail/trace_macros-gate2.rs b/src/test/compile-fail/trace_macros-gate2.rs
new file mode 100644
index 00000000000..71cc45e132d
--- /dev/null
+++ b/src/test/compile-fail/trace_macros-gate2.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// Test that the trace_macros feature gate is on.
+
+fn main() {
+    // (Infrastructure does not attempt to detect uses in macro definitions.)
+    macro_rules! expando {
+        ($x: ident) => { trace_macros!($x) }
+    }
+
+    expando!(true); //~ ERROR `trace_macros` is not stable
+}
diff --git a/src/test/compile-fail/trace_macros-gate3.rs b/src/test/compile-fail/trace_macros-gate3.rs
new file mode 100644
index 00000000000..66d03cf9d80
--- /dev/null
+++ b/src/test/compile-fail/trace_macros-gate3.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// Test that the trace_macros feature gate is on.
+
+pub fn main() {
+    println!("arg: {}", trace_macros!()); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(1)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(ident)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(for)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(true,)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(false 1)); //~ ERROR `trace_macros` is not stable
+}