]> git.lizzy.rs Git - rust.git/commitdiff
Hide the quote_*! macros when the feature gate is off
authorKeegan McAllister <kmcallister@mozilla.com>
Sat, 27 Sep 2014 00:14:23 +0000 (17:14 -0700)
committerKeegan McAllister <kmcallister@mozilla.com>
Sat, 27 Sep 2014 00:17:14 +0000 (17:17 -0700)
This makes it easier to experiment with improved quasiquoting as an ordinary
plugin library.

The list of quote macros in feature_gate.rs was already out of sync;
this commit also prevents that problem in the future.

src/librustc/driver/driver.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/feature_gate.rs
src/libsyntax/test.rs
src/test/run-pass/non-built-in-quote.rs [new file with mode: 0644]

index 33e6579fb87dc7b8fd051b05079c8242a7e62346..05d83e5fc0fbfbd831a264d43587926c6d3c53ff 100644 (file)
@@ -288,8 +288,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
                 os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap());
             }
             let cfg = syntax::ext::expand::ExpansionConfig {
-                deriving_hash_type_parameter: sess.features.borrow().default_type_params,
                 crate_name: crate_name.to_string(),
+                deriving_hash_type_parameter: sess.features.borrow().default_type_params,
+                enable_quotes: sess.features.borrow().quote,
             };
             let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
                                               cfg,
index b35a945675761364e600015bba6224871f566dc1..f340849759ef8bf0bdddaeb7b5113a73d98e16cd 100644 (file)
@@ -344,7 +344,7 @@ pub fn new() -> BlockInfo {
 
 /// The base map of methods for expanding syntax extension
 /// AST nodes into full ASTs
-fn initial_syntax_expander_table() -> SyntaxEnv {
+fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
     // utility function to simplify creating NormalTT syntax extensions
     fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
         NormalTT(box f, None)
@@ -383,31 +383,33 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
     syntax_expanders.insert(intern("deriving"),
                             Decorator(box ext::deriving::expand_meta_deriving));
 
-    // Quasi-quoting expanders
-    syntax_expanders.insert(intern("quote_tokens"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_tokens));
-    syntax_expanders.insert(intern("quote_expr"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_expr));
-    syntax_expanders.insert(intern("quote_ty"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_ty));
-    syntax_expanders.insert(intern("quote_method"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_method));
-    syntax_expanders.insert(intern("quote_item"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_item));
-    syntax_expanders.insert(intern("quote_pat"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_pat));
-    syntax_expanders.insert(intern("quote_arm"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_arm));
-    syntax_expanders.insert(intern("quote_stmt"),
-                       builtin_normal_expander(
-                            ext::quote::expand_quote_stmt));
+    if ecfg.enable_quotes {
+        // Quasi-quoting expanders
+        syntax_expanders.insert(intern("quote_tokens"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_tokens));
+        syntax_expanders.insert(intern("quote_expr"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_expr));
+        syntax_expanders.insert(intern("quote_ty"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_ty));
+        syntax_expanders.insert(intern("quote_method"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_method));
+        syntax_expanders.insert(intern("quote_item"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_item));
+        syntax_expanders.insert(intern("quote_pat"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_pat));
+        syntax_expanders.insert(intern("quote_arm"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_arm));
+        syntax_expanders.insert(intern("quote_stmt"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_stmt));
+    }
 
     syntax_expanders.insert(intern("line"),
                             builtin_normal_expander(
@@ -464,6 +466,7 @@ pub struct ExtCtxt<'a> {
 impl<'a> ExtCtxt<'a> {
     pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
                    ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> {
+        let env = initial_syntax_expander_table(&ecfg);
         ExtCtxt {
             parse_sess: parse_sess,
             cfg: cfg,
@@ -472,7 +475,7 @@ pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
             ecfg: ecfg,
             trace_mac: false,
             exported_macros: Vec::new(),
-            syntax_env: initial_syntax_expander_table(),
+            syntax_env: env,
         }
     }
 
index 70cf41d5e171dc6e6ba9d85b79a873c864d0b2f2..9f3df1a762398223a5c9f6c8e978415baf40f45d 100644 (file)
@@ -975,8 +975,19 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
 }
 
 pub struct ExpansionConfig {
-    pub deriving_hash_type_parameter: bool,
     pub crate_name: String,
+    pub deriving_hash_type_parameter: bool,
+    pub enable_quotes: bool,
+}
+
+impl ExpansionConfig {
+    pub fn default(crate_name: String) -> ExpansionConfig {
+        ExpansionConfig {
+            crate_name: crate_name,
+            deriving_hash_type_parameter: false,
+            enable_quotes: false,
+        }
+    }
 }
 
 pub struct ExportedMacros {
@@ -1106,7 +1117,7 @@ fn visit_mac(&mut self, macro: &ast::Mac) {
 #[cfg(test)]
 mod test {
     use super::{pattern_bindings, expand_crate, contains_macro_escape};
-    use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer};
+    use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
     use ast;
     use ast::{Attribute_, AttrOuter, MetaWord, Name};
     use attr;
@@ -1171,6 +1182,10 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
     // these following tests are quite fragile, in that they don't test what
     // *kind* of failure occurs.
 
+    fn test_ecfg() -> ExpansionConfig {
+        ExpansionConfig::default("test".to_string())
+    }
+
     // make sure that macros can't escape fns
     #[should_fail]
     #[test] fn macros_cant_escape_fns_test () {
@@ -1182,11 +1197,7 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
             src,
             Vec::new(), &sess);
         // should fail:
-        let cfg = ::syntax::ext::expand::ExpansionConfig {
-            deriving_hash_type_parameter: false,
-            crate_name: "test".to_string(),
-        };
-        expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
+        expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
     }
 
     // make sure that macros can't escape modules
@@ -1199,11 +1210,7 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
             "<test>".to_string(),
             src,
             Vec::new(), &sess);
-        let cfg = ::syntax::ext::expand::ExpansionConfig {
-            deriving_hash_type_parameter: false,
-            crate_name: "test".to_string(),
-        };
-        expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
+        expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
     }
 
     // macro_escape modules should allow macros to escape
@@ -1215,11 +1222,7 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
             "<test>".to_string(),
             src,
             Vec::new(), &sess);
-        let cfg = ::syntax::ext::expand::ExpansionConfig {
-            deriving_hash_type_parameter: false,
-            crate_name: "test".to_string(),
-        };
-        expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
+        expand_crate(&sess, test_ecfg(), vec!(), vec!(), crate_ast);
     }
 
     #[test] fn test_contains_flatten (){
@@ -1252,11 +1255,7 @@ fn expand_crate_str(crate_str: String) -> ast::Crate {
         let ps = parse::new_parse_sess();
         let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
         // the cfg argument actually does matter, here...
-        let cfg = ::syntax::ext::expand::ExpansionConfig {
-            deriving_hash_type_parameter: false,
-            crate_name: "test".to_string(),
-        };
-        expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
+        expand_crate(&ps,test_ecfg(),vec!(),vec!(),crate_ast)
     }
 
     // find the pat_ident paths in a crate
index cd0fa184a09dc26245f9a62cacf41a40aaea6183..1c6ee8acc94a59077a2054fa2b9920288c183b7e 100644 (file)
@@ -102,6 +102,7 @@ pub struct Features {
     pub rustc_diagnostic_macros: bool,
     pub import_shadowing: bool,
     pub visible_private_types: bool,
+    pub quote: bool,
 }
 
 impl Features {
@@ -112,6 +113,7 @@ pub fn new() -> Features {
             rustc_diagnostic_macros: false,
             import_shadowing: false,
             visible_private_types: false,
+            quote: false,
         }
     }
 }
@@ -282,10 +284,6 @@ fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
     fn visit_mac(&mut self, macro: &ast::Mac) {
         let ast::MacInvocTT(ref path, _, _) = macro.node;
         let id = path.segments.last().unwrap().identifier;
-        let quotes = ["quote_tokens", "quote_expr", "quote_ty",
-                      "quote_item", "quote_pat", "quote_stmt"];
-        let msg = " is not stable enough for use and are subject to change";
-
 
         if id == token::str_to_ident("macro_rules") {
             self.gate_feature("macro_rules", path.span, "macro definitions are \
@@ -311,16 +309,6 @@ fn visit_mac(&mut self, macro: &ast::Mac) {
             self.gate_feature("concat_idents", path.span, "`concat_idents` is not \
                 stable enough for use and is subject to change");
         }
-
-        else {
-            for &quote in quotes.iter() {
-                if id == token::str_to_ident(quote) {
-                  self.gate_feature("quote",
-                                    path.span,
-                                    format!("{}{}", quote, msg).as_slice());
-                }
-            }
-        }
     }
 
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
@@ -483,6 +471,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features,
         rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
         import_shadowing: cx.has_feature("import_shadowing"),
         visible_private_types: cx.has_feature("visible_private_types"),
+        quote: cx.has_feature("quote"),
     },
     unknown_features)
 }
index f0e697127149f3ab924631837432d2f663df94ce..fdaf9df0150fd4350ac625f96c978cdb23b0c01d 100644 (file)
@@ -235,10 +235,7 @@ fn generate_test_harness(sess: &ParseSess,
         sess: sess,
         span_diagnostic: sd,
         ext_cx: ExtCtxt::new(sess, cfg.clone(),
-                             ExpansionConfig {
-                                 deriving_hash_type_parameter: false,
-                                 crate_name: "test".to_string(),
-                             }),
+                             ExpansionConfig::default("test".to_string())),
         path: Vec::new(),
         testfns: Vec::new(),
         reexport_test_harness_main: reexport_test_harness_main,
diff --git a/src/test/run-pass/non-built-in-quote.rs b/src/test/run-pass/non-built-in-quote.rs
new file mode 100644 (file)
index 0000000..c6dd373
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 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.
+
+#![feature(macro_rules)]
+
+macro_rules! quote_tokens ( () => (()) )
+
+pub fn main() {
+    quote_tokens!();
+}