about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_metadata/decoder.rs18
-rw-r--r--src/libsyntax/ext/base.rs67
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs70
-rw-r--r--src/test/ui/proc-macro/attributes-on-definitions.rs12
-rw-r--r--src/test/ui/proc-macro/attributes-on-definitions.stderr8
-rw-r--r--src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs23
6 files changed, 131 insertions, 67 deletions
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5b9cb966af2..fffeee82d8d 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -530,7 +530,6 @@ impl<'a, 'tcx> CrateMetadata {
                         id: DefIndex,
                         sess: &Session)
                         -> FullProcMacro {
-
         let raw_macro = self.raw_proc_macro(id);
         let (name, kind, helper_attrs) = match *raw_macro {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
@@ -551,16 +550,19 @@ impl<'a, 'tcx> CrateMetadata {
                 name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
             )
         };
-
-        let span = self.get_span(id, sess);
+        let name = Symbol::intern(name);
 
         FullProcMacro {
-            name: Symbol::intern(name),
-            ext: Lrc::new(SyntaxExtension {
-                span,
+            name,
+            ext: Lrc::new(SyntaxExtension::new(
+                &sess.parse_sess,
+                kind,
+                self.get_span(id, sess),
                 helper_attrs,
-                ..SyntaxExtension::default(kind, root.edition)
-            })
+                root.edition,
+                name,
+                &self.get_attributes(&self.entry(id), sess),
+            )),
         }
     }
 
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index a63c4181d5e..10ff1b17285 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1,11 +1,11 @@
 use crate::ast::{self, NodeId, Attribute, Name, PatKind};
-use crate::attr::{HasAttrs, Stability, Deprecation};
+use crate::attr::{self, HasAttrs, Stability, Deprecation};
 use crate::source_map::SourceMap;
 use crate::edition::Edition;
 use crate::ext::expand::{self, AstFragment, Invocation};
 use crate::ext::hygiene::{ExpnId, Transparency};
 use crate::mut_visit::{self, MutVisitor};
-use crate::parse::{self, parser, DirectoryOwnership};
+use crate::parse::{self, parser, ParseSess, DirectoryOwnership};
 use crate::parse::token;
 use crate::ptr::P;
 use crate::symbol::{kw, sym, Ident, Symbol};
@@ -601,6 +601,69 @@ impl SyntaxExtension {
         }
     }
 
+    /// Constructs a syntax extension with the given properties
+    /// and other properties converted from attributes.
+    pub fn new(
+        sess: &ParseSess,
+        kind: SyntaxExtensionKind,
+        span: Span,
+        helper_attrs: Vec<Symbol>,
+        edition: Edition,
+        name: Name,
+        attrs: &[ast::Attribute],
+    ) -> SyntaxExtension {
+        let allow_internal_unstable =
+            attr::find_by_name(attrs, sym::allow_internal_unstable).map(|attr| {
+                attr.meta_item_list()
+                    .map(|list| {
+                        list.iter()
+                            .filter_map(|it| {
+                                let name = it.ident().map(|ident| ident.name);
+                                if name.is_none() {
+                                    sess.span_diagnostic.span_err(
+                                        it.span(), "allow internal unstable expects feature names"
+                                    )
+                                }
+                                name
+                            })
+                            .collect::<Vec<Symbol>>()
+                            .into()
+                    })
+                    .unwrap_or_else(|| {
+                        sess.span_diagnostic.span_warn(
+                            attr.span,
+                            "allow_internal_unstable expects list of feature names. In the future \
+                             this will become a hard error. Please use `allow_internal_unstable(\
+                             foo, bar)` to only allow the `foo` and `bar` features",
+                        );
+                        vec![sym::allow_internal_unstable_backcompat_hack].into()
+                    })
+            });
+
+        let mut local_inner_macros = false;
+        if let Some(macro_export) = attr::find_by_name(attrs, sym::macro_export) {
+            if let Some(l) = macro_export.meta_item_list() {
+                local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
+            }
+        }
+
+        let is_builtin = attr::contains_name(attrs, sym::rustc_builtin_macro);
+
+        SyntaxExtension {
+            kind,
+            span,
+            allow_internal_unstable,
+            allow_internal_unsafe: attr::contains_name(attrs, sym::allow_internal_unsafe),
+            local_inner_macros,
+            stability: attr::find_stability(&sess, attrs, span),
+            deprecation: attr::find_deprecation(&sess, attrs, span),
+            helper_attrs,
+            edition,
+            is_builtin,
+            is_derive_copy: is_builtin && name == sym::Copy,
+        }
+    }
+
     pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
         fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree])
                          -> Box<dyn MacResult + 'cx> {
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 37cb8467ff5..46ffa52f7f5 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,3 +1,5 @@
+use crate::ast;
+use crate::attr::{self, TransparencyError};
 use crate::edition::Edition;
 use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
 use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind};
@@ -15,7 +17,6 @@ use crate::parse::token::{self, NtTT, Token};
 use crate::parse::{Directory, ParseSess};
 use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
-use crate::{ast, attr, attr::TransparencyError};
 
 use errors::{DiagnosticBuilder, FatalError};
 use log::debug;
@@ -290,6 +291,7 @@ pub fn compile(
     def: &ast::Item,
     edition: Edition,
 ) -> SyntaxExtension {
+    let diag = &sess.span_diagnostic;
     let lhs_nm = ast::Ident::new(sym::lhs, def.span);
     let rhs_nm = ast::Ident::new(sym::rhs, def.span);
     let tt_spec = ast::Ident::new(sym::tt, def.span);
@@ -423,13 +425,9 @@ pub fn compile(
     let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy);
     match transparency_error {
         Some(TransparencyError::UnknownTransparency(value, span)) =>
-            sess.span_diagnostic.span_err(
-                span, &format!("unknown macro transparency: `{}`", value)
-            ),
+            diag.span_err(span, &format!("unknown macro transparency: `{}`", value)),
         Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) =>
-            sess.span_diagnostic.span_err(
-                vec![old_span, new_span], "multiple macro transparency attributes"
-            ),
+            diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"),
         None => {}
     }
 
@@ -437,57 +435,15 @@ pub fn compile(
         name: def.ident, span: def.span, transparency, lhses, rhses, valid
     });
 
-    let allow_internal_unstable =
-        attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
-            attr.meta_item_list()
-                .map(|list| {
-                    list.iter()
-                        .filter_map(|it| {
-                            let name = it.ident().map(|ident| ident.name);
-                            if name.is_none() {
-                                sess.span_diagnostic.span_err(
-                                    it.span(),
-                                    "allow internal unstable expects feature names",
-                                )
-                            }
-                            name
-                        })
-                        .collect::<Vec<Symbol>>()
-                        .into()
-                })
-                .unwrap_or_else(|| {
-                    sess.span_diagnostic.span_warn(
-                        attr.span,
-                        "allow_internal_unstable expects list of feature names. In the \
-                         future this will become a hard error. Please use `allow_internal_unstable(\
-                         foo, bar)` to only allow the `foo` and `bar` features",
-                    );
-                    vec![sym::allow_internal_unstable_backcompat_hack].into()
-                })
-        });
-
-    let mut local_inner_macros = false;
-    if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
-        if let Some(l) = macro_export.meta_item_list() {
-            local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
-        }
-    }
-
-    let is_builtin = attr::contains_name(&def.attrs, sym::rustc_builtin_macro);
-
-    SyntaxExtension {
-        kind: SyntaxExtensionKind::LegacyBang(expander),
-        span: def.span,
-        allow_internal_unstable,
-        allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
-        local_inner_macros,
-        stability: attr::find_stability(&sess, &def.attrs, def.span),
-        deprecation: attr::find_deprecation(&sess, &def.attrs, def.span),
-        helper_attrs: Vec::new(),
+    SyntaxExtension::new(
+        sess,
+        SyntaxExtensionKind::LegacyBang(expander),
+        def.span,
+        Vec::new(),
         edition,
-        is_builtin,
-        is_derive_copy: is_builtin && def.ident.name == sym::Copy,
-    }
+        def.ident.name,
+        &def.attrs,
+    )
 }
 
 fn check_lhs_nt_follows(
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.rs b/src/test/ui/proc-macro/attributes-on-definitions.rs
new file mode 100644
index 00000000000..055781d2c60
--- /dev/null
+++ b/src/test/ui/proc-macro/attributes-on-definitions.rs
@@ -0,0 +1,12 @@
+// check-pass
+// aux-build:attributes-on-definitions.rs
+
+#![forbid(unsafe_code)]
+
+extern crate attributes_on_definitions;
+
+attributes_on_definitions::with_attrs!();
+//~^ WARN use of deprecated item
+// No errors about the use of unstable and unsafe code inside the macro.
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.stderr b/src/test/ui/proc-macro/attributes-on-definitions.stderr
new file mode 100644
index 00000000000..c61e043b229
--- /dev/null
+++ b/src/test/ui/proc-macro/attributes-on-definitions.stderr
@@ -0,0 +1,8 @@
+warning: use of deprecated item 'attributes_on_definitions::with_attrs': test
+  --> $DIR/attributes-on-definitions.rs:8:1
+   |
+LL | attributes_on_definitions::with_attrs!();
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(deprecated)]` on by default
+
diff --git a/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs
new file mode 100644
index 00000000000..93a339840d6
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs
@@ -0,0 +1,23 @@
+// force-host
+// no-prefer-dynamic
+
+#![feature(allow_internal_unsafe)]
+#![feature(allow_internal_unstable)]
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+#[allow_internal_unstable(proc_macro_internals)]
+#[allow_internal_unsafe]
+#[deprecated(since = "1.0.0", note = "test")]
+pub fn with_attrs(_: TokenStream) -> TokenStream {
+    "
+    extern crate proc_macro;
+    use ::proc_macro::bridge;
+
+    fn contains_unsafe() { unsafe {} }
+    ".parse().unwrap()
+}