Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass features along during expansion #22383

Merged
merged 3 commits into from
Feb 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,10 @@ pub fn phase_2_configure_and_expand(sess: &Session,
new_path.extend(env::split_paths(&_old_path));
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
}
let features = sess.features.borrow();
let cfg = syntax::ext::expand::ExpansionConfig {
crate_name: crate_name.to_string(),
enable_quotes: sess.features.borrow().quote,
features: Some(&features),
recursion_limit: sess.recursion_limit.get(),
};
let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
Expand Down
7 changes: 7 additions & 0 deletions src/libsyntax/ext/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use codemap;
use codemap::Span;
use ext::base;
use ext::base::*;
use feature_gate;
use parse::token::InternedString;
use parse::token;
use ptr::P;
Expand Down Expand Up @@ -48,6 +49,12 @@ static OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];

pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> {
if !cx.ecfg.enable_asm() {
feature_gate::emit_feature_err(
&cx.parse_sess.span_diagnostic, "asm", sp, feature_gate::EXPLAIN_ASM);
return DummyResult::expr(sp);
}

let mut p = cx.new_parser_from_tts(tts);
let mut asm = InternedString::new("");
let mut asm_str_style = None;
Expand Down
9 changes: 5 additions & 4 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,8 @@ impl BlockInfo {

/// The base map of methods for expanding syntax extension
/// AST nodes into full ASTs
fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
-> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
NormalTT(box f, None)
Expand Down Expand Up @@ -470,7 +471,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
syntax_expanders.insert(intern("deriving"),
Decorator(box ext::deriving::expand_deprecated_deriving));

if ecfg.enable_quotes {
if ecfg.enable_quotes() {
// Quasi-quoting expanders
syntax_expanders.insert(intern("quote_tokens"),
builtin_normal_expander(
Expand Down Expand Up @@ -541,7 +542,7 @@ pub struct ExtCtxt<'a> {
pub parse_sess: &'a parse::ParseSess,
pub cfg: ast::CrateConfig,
pub backtrace: ExpnId,
pub ecfg: expand::ExpansionConfig,
pub ecfg: expand::ExpansionConfig<'a>,
pub use_std: bool,

pub mod_path: Vec<ast::Ident> ,
Expand All @@ -554,7 +555,7 @@ pub struct ExtCtxt<'a> {

impl<'a> ExtCtxt<'a> {
pub fn new(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> {
ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> {
let env = initial_syntax_expander_table(&ecfg);
ExtCtxt {
parse_sess: parse_sess,
Expand Down
9 changes: 9 additions & 0 deletions src/libsyntax/ext/concat_idents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
60 changes: 48 additions & 12 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use attr::AttrMetaMethods;
use codemap;
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
use ext::base::*;
use feature_gate::{Features};
use fold;
use fold::*;
use parse;
Expand Down Expand Up @@ -1407,28 +1408,63 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
}
}

pub struct ExpansionConfig {
pub struct ExpansionConfig<'feat> {
pub crate_name: String,
pub enable_quotes: bool,
pub features: Option<&'feat Features>,
pub recursion_limit: usize,
}

impl ExpansionConfig {
pub fn default(crate_name: String) -> ExpansionConfig {
impl<'feat> ExpansionConfig<'feat> {
pub fn default(crate_name: String) -> ExpansionConfig<'static> {
ExpansionConfig {
crate_name: crate_name,
enable_quotes: false,
features: None,
recursion_limit: 64,
}
}

pub fn enable_quotes(&self) -> bool {
match self.features {
Some(&Features { allow_quote: true, .. }) => true,
_ => false,
}
}

pub fn enable_asm(&self) -> bool {
match self.features {
Some(&Features { allow_asm: true, .. }) => true,
_ => 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(parse_sess: &parse::ParseSess,
cfg: ExpansionConfig,
// these are the macros being imported to this crate:
imported_macros: Vec<ast::MacroDef>,
user_exts: Vec<NamedSyntaxExtension>,
c: Crate) -> Crate {
pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,
cfg: ExpansionConfig<'feat>,
// these are the macros being imported to this crate:
imported_macros: Vec<ast::MacroDef>,
user_exts: Vec<NamedSyntaxExtension>,
c: Crate) -> Crate {
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
cx.use_std = std_inject::use_std(&c);

Expand Down Expand Up @@ -1597,7 +1633,7 @@ mod test {
// these following tests are quite fragile, in that they don't test what
// *kind* of failure occurs.

fn test_ecfg() -> ExpansionConfig {
fn test_ecfg() -> ExpansionConfig<'static> {
ExpansionConfig::default("test".to_string())
}

Expand Down
8 changes: 8 additions & 0 deletions src/libsyntax/ext/log_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
10 changes: 10 additions & 0 deletions src/libsyntax/ext/trace_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ use ast;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::base;
use feature_gate;
use parse::token::keywords;


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);
Expand Down
53 changes: 42 additions & 11 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,11 @@ pub struct Features {
pub unboxed_closures: bool,
pub rustc_diagnostic_macros: bool,
pub visible_private_types: bool,
pub quote: 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,
Expand All @@ -172,7 +176,11 @@ impl Features {
unboxed_closures: false,
rustc_diagnostic_macros: false,
visible_private_types: false,
quote: 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,
Expand Down Expand Up @@ -221,6 +229,18 @@ 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>
}
Expand All @@ -230,24 +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, "inline assembly is not \
stable enough for use and is subject to change");
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);
}
}
}
Expand Down Expand Up @@ -590,11 +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"),
quote: cx.has_feature("quote"),
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"),
Expand Down
15 changes: 15 additions & 0 deletions src/test/compile-fail/asm-gated2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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.

fn main() {
unsafe {
println!("{}", asm!("")); //~ ERROR inline assembly is not stable
}
}
19 changes: 19 additions & 0 deletions src/test/compile-fail/concat_idents-gate.rs
Original file line number Diff line number Diff line change
@@ -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);
}
17 changes: 17 additions & 0 deletions src/test/compile-fail/concat_idents-gate2.rs
Original file line number Diff line number Diff line change
@@ -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
}
13 changes: 13 additions & 0 deletions src/test/compile-fail/log-syntax-gate2.rs
Original file line number Diff line number Diff line change
@@ -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
}
Loading