Skip to content

Commit

Permalink
Hide the quote_*! macros when the feature gate is off
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Keegan McAllister committed Sep 27, 2014
1 parent 5d653c1 commit fc1b908
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 68 deletions.
3 changes: 2 additions & 1 deletion src/librustc/driver/driver.rs
Expand Up @@ -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,
Expand Down
57 changes: 30 additions & 27 deletions src/libsyntax/ext/base.rs
Expand Up @@ -344,7 +344,7 @@ impl 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)
Expand Down Expand Up @@ -383,31 +383,33 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
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(
Expand Down Expand Up @@ -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,
Expand All @@ -472,7 +475,7 @@ impl<'a> ExtCtxt<'a> {
ecfg: ecfg,
trace_mac: false,
exported_macros: Vec::new(),
syntax_env: initial_syntax_expander_table(),
syntax_env: env,
}
}

Expand Down
43 changes: 21 additions & 22 deletions src/libsyntax/ext/expand.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -1106,7 +1117,7 @@ impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> {
#[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;
Expand Down Expand Up @@ -1171,6 +1182,10 @@ mod test {
// 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 () {
Expand All @@ -1182,11 +1197,7 @@ mod test {
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
Expand All @@ -1199,11 +1210,7 @@ mod test {
"<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
Expand All @@ -1215,11 +1222,7 @@ mod test {
"<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 (){
Expand Down Expand Up @@ -1252,11 +1255,7 @@ mod test {
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
Expand Down
17 changes: 3 additions & 14 deletions src/libsyntax/feature_gate.rs
Expand Up @@ -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 {
Expand All @@ -112,6 +113,7 @@ impl Features {
rustc_diagnostic_macros: false,
import_shadowing: false,
visible_private_types: false,
quote: false,
}
}
}
Expand Down Expand Up @@ -282,10 +284,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
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 \
Expand All @@ -311,16 +309,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
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) {
Expand Down Expand Up @@ -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)
}
Expand Down
5 changes: 1 addition & 4 deletions src/libsyntax/test.rs
Expand Up @@ -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,
Expand Down
17 changes: 17 additions & 0 deletions src/test/run-pass/non-built-in-quote.rs
@@ -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!();
}

1 comment on commit fc1b908

@alexcrichton
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+

Please sign in to comment.