diff options
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/asm.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 58 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 2 |
5 files changed, 61 insertions, 16 deletions
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index e58a3de41c0..d256698b885 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -214,6 +214,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) name: "asm".to_string(), format: codemap::MacroBang, span: None, + allow_internal_unstable: false, }, }); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f6bdd693cfa..80b86507f6e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -430,12 +430,15 @@ pub enum SyntaxExtension { /// A normal, function-like syntax extension. /// /// `bytes!` is a `NormalTT`. - NormalTT(Box<TTMacroExpander + 'static>, Option<Span>), + /// + /// The `bool` dictates whether the contents of the macro can + /// directly use `#[unstable]` things (true == yes). + NormalTT(Box<TTMacroExpander + 'static>, Option<Span>, bool), /// A function-like syntax extension that has an extra ident before /// the block. /// - IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>), + IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>, bool), /// Represents `macro_rules!` itself. MacroRulesTT, @@ -465,14 +468,14 @@ 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::new(f), None) + NormalTT(Box::new(f), None, false) } let mut syntax_expanders = SyntaxEnv::new(); syntax_expanders.insert(intern("macro_rules"), MacroRulesTT); syntax_expanders.insert(intern("format_args"), - builtin_normal_expander( - ext::format::expand_format_args)); + // format_args uses `unstable` things internally. + NormalTT(Box::new(ext::format::expand_format_args), None, true)); syntax_expanders.insert(intern("env"), builtin_normal_expander( ext::env::expand_env)); diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index a36d3a155b8..9cd965a8138 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -1216,7 +1216,8 @@ impl<'a> TraitDef<'a> { callee: codemap::NameAndSpan { name: format!("derive({})", trait_name), format: codemap::MacroAttribute, - span: Some(self.span) + span: Some(self.span), + allow_internal_unstable: false, } }); to_set diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index bea57ae14e4..8953689a0c2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -22,7 +22,7 @@ use attr::AttrMetaMethods; use codemap; use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute}; use ext::base::*; -use feature_gate::{Features}; +use feature_gate::{self, Features}; use fold; use fold::*; use parse; @@ -395,13 +395,14 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span, None } Some(rc) => match *rc { - NormalTT(ref expandfun, exp_span) => { + NormalTT(ref expandfun, exp_span, allow_internal_unstable) => { fld.cx.bt_push(ExpnInfo { call_site: span, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, span: exp_span, + allow_internal_unstable: allow_internal_unstable, }, }); let fm = fresh_mark(); @@ -530,6 +531,9 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) name: mname.to_string(), format: MacroAttribute, span: None, + // attributes can do whatever they like, + // for now + allow_internal_unstable: true, } }); it = mac.expand(fld.cx, attr.span, &*attr.node.value, it); @@ -614,7 +618,7 @@ pub fn expand_item_mac(it: P<ast::Item>, } Some(rc) => match *rc { - NormalTT(ref expander, span) => { + NormalTT(ref expander, span, allow_internal_unstable) => { if it.ident.name != parse::token::special_idents::invalid.name { fld.cx .span_err(path_span, @@ -628,14 +632,15 @@ pub fn expand_item_mac(it: P<ast::Item>, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, - span: span + span: span, + allow_internal_unstable: allow_internal_unstable, } }); // mark before expansion: let marked_before = mark_tts(&tts[..], fm); expander.expand(fld.cx, it.span, &marked_before[..]) } - IdentTT(ref expander, span) => { + IdentTT(ref expander, span, allow_internal_unstable) => { if it.ident.name == parse::token::special_idents::invalid.name { fld.cx.span_err(path_span, &format!("macro {}! expects an ident argument", @@ -647,7 +652,8 @@ pub fn expand_item_mac(it: P<ast::Item>, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, - span: span + span: span, + allow_internal_unstable: allow_internal_unstable, } }); // mark before expansion: @@ -661,16 +667,35 @@ pub fn expand_item_mac(it: P<ast::Item>, ); return SmallVector::zero(); } + fld.cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, span: None, + // `macro_rules!` doesn't directly allow + // unstable (this is orthogonal to whether + // the macro it creates allows it) + allow_internal_unstable: false, } }); // DON'T mark before expansion. + let allow_internal_unstable = attr::contains_name(&it.attrs, + "allow_internal_unstable"); + + // ensure any #[allow_internal_unstable]s are + // detected (including nested macro definitions + // etc.) + if allow_internal_unstable && !fld.cx.ecfg.enable_allow_internal_unstable() { + feature_gate::emit_feature_err( + &fld.cx.parse_sess.span_diagnostic, + "allow_internal_unstable", + it.span, + feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE) + } + let def = ast::MacroDef { ident: it.ident, attrs: it.attrs.clone(), @@ -679,6 +704,7 @@ pub fn expand_item_mac(it: P<ast::Item>, imported_from: None, export: attr::contains_name(&it.attrs, "macro_export"), use_locally: true, + allow_internal_unstable: allow_internal_unstable, body: tts, }; fld.cx.insert_macro(def); @@ -959,13 +985,14 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> { } Some(rc) => match *rc { - NormalTT(ref expander, tt_span) => { + NormalTT(ref expander, tt_span, allow_internal_unstable) => { fld.cx.bt_push(ExpnInfo { call_site: span, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, - span: tt_span + span: tt_span, + allow_internal_unstable: allow_internal_unstable, } }); @@ -1094,7 +1121,10 @@ fn expand_annotatable(a: Annotatable, callee: NameAndSpan { name: mname.to_string(), format: MacroAttribute, - span: None + span: None, + // attributes can do whatever they like, + // for now. + allow_internal_unstable: true, } }); @@ -1244,6 +1274,9 @@ fn expand_item_multi_modifier(mut it: Annotatable, name: mname.to_string(), format: MacroAttribute, span: None, + // attributes can do whatever they like, + // for now + allow_internal_unstable: true, } }); it = mac.expand(fld.cx, attr.span, &*attr.node.value, it); @@ -1457,6 +1490,13 @@ impl<'feat> ExpansionConfig<'feat> { _ => false, } } + + pub fn enable_allow_internal_unstable(&self) -> bool { + match self.features { + Some(&Features { allow_internal_unstable: true, .. }) => true, + _ => false + } + } } pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess, diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index d15eb3df639..644c6cd7e28 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -267,7 +267,7 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt, rhses: rhses, }; - NormalTT(exp, Some(def.span)) + NormalTT(exp, Some(def.span), def.allow_internal_unstable) } fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &NamedMatch, sp: Span) { |
