From 84b060ce29bf7dd65fc23e855ad7c5a8748d806c Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 1 Mar 2015 14:09:28 +1100 Subject: Add #[allow_internal_unstable] to track stability for macros better. Unstable items used in a macro expansion will now always trigger stability warnings, *unless* the unstable items are directly inside a macro marked with `#[allow_internal_unstable]`. IOW, the compiler warns unless the span of the unstable item is a subspan of the definition of a macro marked with that attribute. E.g. #[allow_internal_unstable] macro_rules! foo { ($e: expr) => {{ $e; unstable(); // no warning only_called_by_foo!(); }} } macro_rules! only_called_by_foo { () => { unstable() } // warning } foo!(unstable()) // warning The unstable inside `foo` is fine, due to the attribute. But the `unstable` inside `only_called_by_foo` is not, since that macro doesn't have the attribute, and the `unstable` passed into `foo` is also not fine since it isn't contained in the macro itself (that is, even though it is only used directly in the macro). In the process this makes the stability tracking much more precise, e.g. previously `println!("{}", unstable())` got no warning, but now it does. As such, this is a bug fix that may cause [breaking-change]s. The attribute is definitely feature gated, since it explicitly allows side-stepping the feature gating system. --- src/libsyntax/ext/base.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/libsyntax/ext/base.rs') 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, Option), + /// + /// The `bool` dictates whether the contents of the macro can + /// directly use `#[unstable]` things (true == yes). + NormalTT(Box, Option, bool), /// A function-like syntax extension that has an extra ident before /// the block. /// - IdentTT(Box, Option), + IdentTT(Box, Option, 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)); -- cgit 1.4.1-3-g733a5