about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-19 06:49:13 +0000
committerbors <bors@rust-lang.org>2019-06-19 06:49:13 +0000
commita6cbf2d1344418cd2807cc5380ef1247647a1e12 (patch)
treecd2c5efba7fae486762161de293c684b1d66d962 /src/libsyntax
parent605ea9d05c48957a291eec11eb7339788c3140ed (diff)
parentfde341a4ef6a5728dfd1acb5de0b238918a2dd44 (diff)
downloadrust-a6cbf2d1344418cd2807cc5380ef1247647a1e12.tar.gz
rust-a6cbf2d1344418cd2807cc5380ef1247647a1e12.zip
Auto merge of #61945 - Centril:rollup-xdqo2mn, r=Centril
Rollup of 11 pull requests

Successful merges:

 - #61505 (Only show methods that appear in `impl` blocks in the Implementors sections of trait doc pages)
 - #61701 (move stray run-pass const tests into const/ folder)
 - #61748 (Tweak transparent enums and unions diagnostic spans)
 - #61802 (Make MaybeUninit #[repr(transparent)])
 - #61839 (ci: Add a script for generating CPU usage graphs)
 - #61842 (Remove unnecessary lift calls)
 - #61843 (Turn down the myriad-closures test)
 - #61896 (rustc_typeck: correctly compute `Substs` for `Res::SelfCtor`.)
 - #61898 (syntax: Factor out common fields from `SyntaxExtension` variants)
 - #61938 (create an issue for miri even in status test-fail)
 - #61941 (Preserve generator and yield source for error messages)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/base.rs174
-rw-r--r--src/libsyntax/ext/derive.rs13
-rw-r--r--src/libsyntax/ext/expand.rs180
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs12
-rw-r--r--src/libsyntax/std_inject.rs12
-rw-r--r--src/libsyntax/test.rs13
6 files changed, 141 insertions, 263 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 38b7dee40c4..318a5a3a82a 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -15,6 +15,7 @@ use crate::tokenstream::{self, TokenStream};
 use errors::{DiagnosticBuilder, DiagnosticId};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{Span, MultiSpan, DUMMY_SP};
+use syntax_pos::hygiene::{ExpnInfo, ExpnFormat};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
@@ -548,37 +549,19 @@ impl MacroKind {
     }
 }
 
-/// An enum representing the different kinds of syntax extensions.
-pub enum SyntaxExtension {
+/// A syntax extension kind.
+pub enum SyntaxExtensionKind {
     /// A token-based function-like macro.
-    Bang {
+    Bang(
         /// An expander with signature TokenStream -> TokenStream.
-        expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
-        /// Whitelist of unstable features that are treated as stable inside this macro.
-        allow_internal_unstable: Option<Lrc<[Symbol]>>,
-        /// Edition of the crate in which this macro is defined.
-        edition: Edition,
-    },
+        Box<dyn ProcMacro + sync::Sync + sync::Send>,
+    ),
 
     /// An AST-based function-like macro.
-    LegacyBang {
+    LegacyBang(
         /// An expander with signature TokenStream -> AST.
-        expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
-        /// Some info about the macro's definition point.
-        def_info: Option<(ast::NodeId, Span)>,
-        /// Hygienic properties of identifiers produced by this macro.
-        transparency: Transparency,
-        /// Whitelist of unstable features that are treated as stable inside this macro.
-        allow_internal_unstable: Option<Lrc<[Symbol]>>,
-        /// Suppresses the `unsafe_code` lint for code produced by this macro.
-        allow_internal_unsafe: bool,
-        /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
-        local_inner_macros: bool,
-        /// The macro's feature name and tracking issue number if it is unstable.
-        unstable_feature: Option<(Symbol, u32)>,
-        /// Edition of the crate in which this macro is defined.
-        edition: Edition,
-    },
+        Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
+    ),
 
     /// A token-based attribute macro.
     Attr(
@@ -586,8 +569,6 @@ pub enum SyntaxExtension {
         /// The first TokenSteam is the attribute itself, the second is the annotated item.
         /// The produced TokenSteam replaces the input TokenSteam.
         Box<dyn AttrProcMacro + sync::Sync + sync::Send>,
-        /// Edition of the crate in which this macro is defined.
-        Edition,
     ),
 
     /// An AST-based attribute macro.
@@ -599,7 +580,8 @@ pub enum SyntaxExtension {
     ),
 
     /// A trivial attribute "macro" that does nothing,
-    /// only keeps the attribute and marks it as known.
+    /// only keeps the attribute and marks it as inert,
+    /// thus making it ineligible for further expansion.
     NonMacroAttr {
         /// Suppresses the `unused_attributes` lint for this attribute.
         mark_used: bool,
@@ -610,10 +592,6 @@ pub enum SyntaxExtension {
         /// An expander with signature TokenStream -> TokenStream (not yet).
         /// The produced TokenSteam is appended to the input TokenSteam.
         Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
-        /// Names of helper attributes registered by this macro.
-        Vec<Symbol>,
-        /// Edition of the crate in which this macro is defined.
-        Edition,
     ),
 
     /// An AST-based derive macro.
@@ -624,42 +602,91 @@ pub enum SyntaxExtension {
     ),
 }
 
+/// A struct representing a macro definition in "lowered" form ready for expansion.
+pub struct SyntaxExtension {
+    /// A syntax extension kind.
+    pub kind: SyntaxExtensionKind,
+    /// Some info about the macro's definition point.
+    pub def_info: Option<(ast::NodeId, Span)>,
+    /// Hygienic properties of spans produced by this macro by default.
+    pub default_transparency: Transparency,
+    /// Whitelist of unstable features that are treated as stable inside this macro.
+    pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
+    /// Suppresses the `unsafe_code` lint for code produced by this macro.
+    pub allow_internal_unsafe: bool,
+    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
+    pub local_inner_macros: bool,
+    /// The macro's feature name and tracking issue number if it is unstable.
+    pub unstable_feature: Option<(Symbol, u32)>,
+    /// Names of helper attributes registered by this macro.
+    pub helper_attrs: Vec<Symbol>,
+    /// Edition of the crate in which this macro is defined.
+    pub edition: Edition,
+}
+
+impl SyntaxExtensionKind {
+    /// When a syntax extension is constructed,
+    /// its transparency can often be inferred from its kind.
+    fn default_transparency(&self) -> Transparency {
+        match self {
+            SyntaxExtensionKind::Bang(..) |
+            SyntaxExtensionKind::Attr(..) |
+            SyntaxExtensionKind::Derive(..) |
+            SyntaxExtensionKind::NonMacroAttr { .. } => Transparency::Opaque,
+            SyntaxExtensionKind::LegacyBang(..) |
+            SyntaxExtensionKind::LegacyAttr(..) |
+            SyntaxExtensionKind::LegacyDerive(..) => Transparency::SemiTransparent,
+        }
+    }
+}
+
 impl SyntaxExtension {
     /// Returns which kind of macro calls this syntax extension.
-    pub fn kind(&self) -> MacroKind {
-        match *self {
-            SyntaxExtension::Bang { .. } |
-            SyntaxExtension::LegacyBang { .. } => MacroKind::Bang,
-            SyntaxExtension::Attr(..) |
-            SyntaxExtension::LegacyAttr(..) |
-            SyntaxExtension::NonMacroAttr { .. } => MacroKind::Attr,
-            SyntaxExtension::Derive(..) |
-            SyntaxExtension::LegacyDerive(..) => MacroKind::Derive,
+    pub fn macro_kind(&self) -> MacroKind {
+        match self.kind {
+            SyntaxExtensionKind::Bang(..) |
+            SyntaxExtensionKind::LegacyBang(..) => MacroKind::Bang,
+            SyntaxExtensionKind::Attr(..) |
+            SyntaxExtensionKind::LegacyAttr(..) |
+            SyntaxExtensionKind::NonMacroAttr { .. } => MacroKind::Attr,
+            SyntaxExtensionKind::Derive(..) |
+            SyntaxExtensionKind::LegacyDerive(..) => MacroKind::Derive,
         }
     }
 
-    pub fn default_transparency(&self) -> Transparency {
-        match *self {
-            SyntaxExtension::LegacyBang { transparency, .. } => transparency,
-            SyntaxExtension::Bang { .. } |
-            SyntaxExtension::Attr(..) |
-            SyntaxExtension::Derive(..) |
-            SyntaxExtension::NonMacroAttr { .. } => Transparency::Opaque,
-            SyntaxExtension::LegacyAttr(..) |
-            SyntaxExtension::LegacyDerive(..) => Transparency::SemiTransparent,
+    /// Constructs a syntax extension with default properties.
+    pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
+        SyntaxExtension {
+            def_info: None,
+            default_transparency: kind.default_transparency(),
+            allow_internal_unstable: None,
+            allow_internal_unsafe: false,
+            local_inner_macros: false,
+            unstable_feature: None,
+            helper_attrs: Vec::new(),
+            edition,
+            kind,
         }
     }
 
-    pub fn edition(&self, default_edition: Edition) -> Edition {
-        match *self {
-            SyntaxExtension::Bang { edition, .. } |
-            SyntaxExtension::LegacyBang { edition, .. } |
-            SyntaxExtension::Attr(.., edition) |
-            SyntaxExtension::Derive(.., edition) => edition,
-            // Unstable legacy stuff
-            SyntaxExtension::NonMacroAttr { .. } |
-            SyntaxExtension::LegacyAttr(..) |
-            SyntaxExtension::LegacyDerive(..) => default_edition,
+    fn expn_format(&self, symbol: Symbol) -> ExpnFormat {
+        match self.kind {
+            SyntaxExtensionKind::Bang(..) |
+            SyntaxExtensionKind::LegacyBang(..) => ExpnFormat::MacroBang(symbol),
+            _ => ExpnFormat::MacroAttribute(symbol),
+        }
+    }
+
+    pub fn expn_info(&self, call_site: Span, format: &str) -> ExpnInfo {
+        ExpnInfo {
+            call_site,
+            format: self.expn_format(Symbol::intern(format)),
+            def_site: self.def_info.map(|(_, span)| span),
+            default_transparency: self.default_transparency,
+            allow_internal_unstable: self.allow_internal_unstable.clone(),
+            allow_internal_unsafe: self.allow_internal_unsafe,
+            local_inner_macros: self.local_inner_macros,
+            edition: self.edition,
         }
     }
 }
@@ -699,31 +726,6 @@ impl Determinacy {
     }
 }
 
-pub struct DummyResolver;
-
-impl Resolver for DummyResolver {
-    fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
-
-    fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
-
-    fn resolve_dollar_crates(&mut self, _fragment: &AstFragment) {}
-    fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
-                                            _derives: &[Mark]) {}
-    fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
-
-    fn resolve_imports(&mut self) {}
-    fn resolve_macro_invocation(&mut self, _invoc: &Invocation, _invoc_id: Mark, _force: bool)
-                                -> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
-        Err(Determinacy::Determined)
-    }
-    fn resolve_macro_path(&mut self, _path: &ast::Path, _kind: MacroKind, _invoc_id: Mark,
-                          _derives_in_scope: Vec<ast::Path>, _force: bool)
-                          -> Result<Lrc<SyntaxExtension>, Determinacy> {
-        Err(Determinacy::Determined)
-    }
-    fn check_unused_macros(&self) {}
-}
-
 #[derive(Clone)]
 pub struct ModuleData {
     pub mod_path: Vec<ast::Ident>,
diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs
index a2cf4a2a82d..abc451c96ae 100644
--- a/src/libsyntax/ext/derive.rs
+++ b/src/libsyntax/ext/derive.rs
@@ -60,15 +60,10 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
     }
     pretty_name.push(')');
 
-    cx.current_expansion.mark.set_expn_info(ExpnInfo {
-        call_site: span,
-        def_site: None,
-        format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
-        allow_internal_unstable: Some(vec![sym::rustc_attrs, sym::structural_match].into()),
-        allow_internal_unsafe: false,
-        local_inner_macros: false,
-        edition: cx.parse_sess.edition,
-    });
+    cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable(
+        ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)), span, cx.parse_sess.edition,
+        &[sym::rustc_attrs, sym::structural_match],
+    ));
 
     let span = span.with_ctxt(cx.backtrace());
     item.visit_attrs(|attrs| {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index d433e6c5a89..be90def0bdd 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1,7 +1,7 @@
 use crate::ast::{self, Block, Ident, LitKind, NodeId, PatKind, Path};
 use crate::ast::{MacStmtStyle, StmtKind, ItemKind};
 use crate::attr::{self, HasAttrs};
-use crate::source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
+use crate::source_map::{dummy_spanned, respan};
 use crate::config::StripUnconfigured;
 use crate::ext::base::*;
 use crate::ext::derive::{add_derived_markers, collect_derives};
@@ -22,7 +22,6 @@ use crate::util::map_in_place::MapInPlace;
 use errors::{Applicability, FatalError};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{Span, DUMMY_SP, FileName};
-use syntax_pos::hygiene::ExpnFormat;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
@@ -189,23 +188,6 @@ impl AstFragmentKind {
     }
 }
 
-fn macro_bang_format(path: &ast::Path) -> ExpnFormat {
-    // We don't want to format a path using pretty-printing,
-    // `format!("{}", path)`, because that tries to insert
-    // line-breaks and is slow.
-    let mut path_str = String::with_capacity(64);
-    for (i, segment) in path.segments.iter().enumerate() {
-        if i != 0 {
-            path_str.push_str("::");
-        }
-        if segment.ident.name != kw::PathRoot {
-            path_str.push_str(&segment.ident.as_str())
-        }
-    }
-
-    MacroBang(Symbol::intern(&path_str))
-}
-
 pub struct Invocation {
     pub kind: InvocationKind,
     fragment_kind: AstFragmentKind,
@@ -388,8 +370,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         derives.push(mark);
                         let item = match self.cx.resolver.resolve_macro_path(
                                 path, MacroKind::Derive, Mark::root(), Vec::new(), false) {
-                            Ok(ext) => match *ext {
-                                SyntaxExtension::LegacyDerive(..) => item_with_markers.clone(),
+                            Ok(ext) => match ext.kind {
+                                SyntaxExtensionKind::LegacyDerive(..) => item_with_markers.clone(),
                                 _ => item.clone(),
                             },
                             _ => item.clone(),
@@ -509,7 +491,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
     fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<AstFragment> {
         if invoc.fragment_kind == AstFragmentKind::ForeignItems &&
            !self.cx.ecfg.macros_in_extern_enabled() {
-            if let SyntaxExtension::NonMacroAttr { .. } = *ext {} else {
+            if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else {
                 emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern,
                                  invoc.span(), GateIssue::Language,
                                  "macro invocations in `extern {}` blocks are experimental");
@@ -548,34 +530,22 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             _ => unreachable!(),
         };
 
-        if let SyntaxExtension::NonMacroAttr { mark_used: false } = *ext {} else {
-            // Macro attrs are always used when expanded,
-            // non-macro attrs are considered used when the field says so.
-            attr::mark_used(&attr);
-        }
-        invoc.expansion_data.mark.set_expn_info(ExpnInfo {
-            call_site: attr.span,
-            def_site: None,
-            format: MacroAttribute(Symbol::intern(&attr.path.to_string())),
-            allow_internal_unstable: None,
-            allow_internal_unsafe: false,
-            local_inner_macros: false,
-            edition: ext.edition(self.cx.parse_sess.edition),
-        });
-
-        match *ext {
-            SyntaxExtension::NonMacroAttr { .. } => {
+        match &ext.kind {
+            SyntaxExtensionKind::NonMacroAttr { mark_used } => {
                 attr::mark_known(&attr);
+                if *mark_used {
+                    attr::mark_used(&attr);
+                }
                 item.visit_attrs(|attrs| attrs.push(attr));
                 Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item)))
             }
-            SyntaxExtension::LegacyAttr(ref mac) => {
+            SyntaxExtensionKind::LegacyAttr(expander) => {
                 let meta = attr.parse_meta(self.cx.parse_sess)
                                .map_err(|mut e| { e.emit(); }).ok()?;
-                let item = mac.expand(self.cx, attr.span, &meta, item);
+                let item = expander.expand(self.cx, attr.span, &meta, item);
                 Some(invoc.fragment_kind.expect_from_annotatables(item))
             }
-            SyntaxExtension::Attr(ref mac, ..) => {
+            SyntaxExtensionKind::Attr(expander) => {
                 self.gate_proc_macro_attr_item(attr.span, &item);
                 let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item {
                     Annotatable::Item(item) => token::NtItem(item),
@@ -586,13 +556,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     Annotatable::Expr(expr) => token::NtExpr(expr),
                 })), DUMMY_SP).into();
                 let input = self.extract_proc_macro_attr_input(attr.tokens, attr.span);
-                let tok_result = mac.expand(self.cx, attr.span, input, item_tok);
+                let tok_result = expander.expand(self.cx, attr.span, input, item_tok);
                 let res = self.parse_ast_fragment(tok_result, invoc.fragment_kind,
                                                   &attr.path, attr.span);
                 self.gate_proc_macro_expansion(attr.span, &res);
                 res
             }
-            SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => {
+            SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
                 self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path));
                 self.cx.trace_macros_diag();
                 invoc.fragment_kind.dummy(attr.span)
@@ -693,7 +663,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                          invoc: Invocation,
                          ext: &SyntaxExtension)
                          -> Option<AstFragment> {
-        let (mark, kind) = (invoc.expansion_data.mark, invoc.fragment_kind);
+        let kind = invoc.fragment_kind;
         let (mac, ident, span) = match invoc.kind {
             InvocationKind::Bang { mac, ident, span } => (mac, ident, span),
             _ => unreachable!(),
@@ -701,21 +671,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         let path = &mac.node.path;
 
         let ident = ident.unwrap_or_else(|| Ident::invalid());
-        let validate_and_set_expn_info = |this: &mut Self, // arg instead of capture
-                                          def_site_span: Option<Span>,
-                                          allow_internal_unstable,
-                                          allow_internal_unsafe,
-                                          local_inner_macros,
-                                          // can't infer this type
-                                          unstable_feature: Option<(Symbol, u32)>,
-                                          edition| {
-
+        let validate = |this: &mut Self| {
             // feature-gate the macro invocation
-            if let Some((feature, issue)) = unstable_feature {
+            if let Some((feature, issue)) = ext.unstable_feature {
                 let crate_span = this.cx.current_expansion.crate_span.unwrap();
                 // don't stability-check macros in the same crate
                 // (the only time this is null is for syntax extensions registered as macros)
-                if def_site_span.map_or(false, |def_span| !crate_span.contains(def_span))
+                if ext.def_info.map_or(false, |(_, def_span)| !crate_span.contains(def_span))
                     && !span.allows_unstable(feature)
                     && this.cx.ecfg.features.map_or(true, |feats| {
                     // macro features will count as lib features
@@ -734,62 +696,39 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 this.cx.trace_macros_diag();
                 return Err(kind.dummy(span));
             }
-            mark.set_expn_info(ExpnInfo {
-                call_site: span,
-                def_site: def_site_span,
-                format: macro_bang_format(path),
-                allow_internal_unstable,
-                allow_internal_unsafe,
-                local_inner_macros,
-                edition,
-            });
             Ok(())
         };
 
-        let opt_expanded = match *ext {
-            SyntaxExtension::LegacyBang {
-                ref expander,
-                def_info,
-                ref allow_internal_unstable,
-                allow_internal_unsafe,
-                local_inner_macros,
-                unstable_feature,
-                edition,
-                ..
-            } => {
-                if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s),
-                                                                    allow_internal_unstable.clone(),
-                                                                    allow_internal_unsafe,
-                                                                    local_inner_macros,
-                                                                    unstable_feature,
-                                                                    edition) {
+        let opt_expanded = match &ext.kind {
+            SyntaxExtensionKind::LegacyBang(expander) => {
+                if let Err(dummy_span) = validate(self) {
                     dummy_span
                 } else {
                     kind.make_from(expander.expand(
                         self.cx,
                         span,
                         mac.node.stream(),
-                        def_info.map(|(_, s)| s),
+                        ext.def_info.map(|(_, s)| s),
                     ))
                 }
             }
 
-            SyntaxExtension::Attr(..) |
-            SyntaxExtension::LegacyAttr(..) |
-            SyntaxExtension::NonMacroAttr { .. } => {
+            SyntaxExtensionKind::Attr(..) |
+            SyntaxExtensionKind::LegacyAttr(..) |
+            SyntaxExtensionKind::NonMacroAttr { .. } => {
                 self.cx.span_err(path.span,
                                  &format!("`{}` can only be used in attributes", path));
                 self.cx.trace_macros_diag();
                 kind.dummy(span)
             }
 
-            SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => {
+            SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
                 self.cx.span_err(path.span, &format!("`{}` is a derive macro", path));
                 self.cx.trace_macros_diag();
                 kind.dummy(span)
             }
 
-            SyntaxExtension::Bang { ref expander, ref allow_internal_unstable, edition } => {
+            SyntaxExtensionKind::Bang(expander) => {
                 if ident.name != kw::Invalid {
                     let msg =
                         format!("macro {}! expects no ident argument, given '{}'", path, ident);
@@ -798,19 +737,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     kind.dummy(span)
                 } else {
                     self.gate_proc_macro_expansion_kind(span, kind);
-                    invoc.expansion_data.mark.set_expn_info(ExpnInfo {
-                        call_site: span,
-                        // FIXME procedural macros do not have proper span info
-                        // yet, when they do, we should use it here.
-                        def_site: None,
-                        format: macro_bang_format(path),
-                        // FIXME probably want to follow macro_rules macros here.
-                        allow_internal_unstable: allow_internal_unstable.clone(),
-                        allow_internal_unsafe: false,
-                        local_inner_macros: false,
-                        edition,
-                    });
-
                     let tok_result = expander.expand(self.cx, span, mac.node.stream());
                     let result = self.parse_ast_fragment(tok_result, kind, path, span);
                     self.gate_proc_macro_expansion(span, &result);
@@ -867,55 +793,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             return None;
         }
 
-        let pretty_name = Symbol::intern(&format!("derive({})", path));
-        let span = path.span;
-        let attr = ast::Attribute {
-            path, span,
-            tokens: TokenStream::empty(),
-            // irrelevant:
-            id: ast::AttrId(0), style: ast::AttrStyle::Outer, is_sugared_doc: false,
-        };
-
-        let mut expn_info = ExpnInfo {
-            call_site: span,
-            def_site: None,
-            format: MacroAttribute(pretty_name),
-            allow_internal_unstable: None,
-            allow_internal_unsafe: false,
-            local_inner_macros: false,
-            edition: ext.edition(self.cx.parse_sess.edition),
-        };
-
-        match ext {
-            SyntaxExtension::Derive(expander, ..) | SyntaxExtension::LegacyDerive(expander) => {
-                let meta = match ext {
-                    SyntaxExtension::Derive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this
-                        path: Path::from_ident(Ident::invalid()),
-                        span: DUMMY_SP,
-                        node: ast::MetaItemKind::Word,
-                    },
-                    _ => {
-                        expn_info.allow_internal_unstable = Some(vec![
-                            sym::rustc_attrs,
-                            Symbol::intern("derive_clone_copy"),
-                            Symbol::intern("derive_eq"),
-                            // RustcDeserialize and RustcSerialize
-                            Symbol::intern("libstd_sys_internals"),
-                        ].into());
-                        attr.meta()?
-                    }
-                };
-
-                invoc.expansion_data.mark.set_expn_info(expn_info);
-                let span = span.with_ctxt(self.cx.backtrace());
+        match &ext.kind {
+            SyntaxExtensionKind::Derive(expander) |
+            SyntaxExtensionKind::LegacyDerive(expander) => {
+                let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span: path.span, path };
+                let span = meta.span.with_ctxt(self.cx.backtrace());
                 let items = expander.expand(self.cx, span, &meta, item);
                 Some(invoc.fragment_kind.expect_from_annotatables(items))
             }
             _ => {
-                let msg = &format!("macro `{}` may not be used for derive attributes", attr.path);
-                self.cx.span_err(span, msg);
+                let msg = &format!("macro `{}` may not be used for derive attributes", path);
+                self.cx.span_err(path.span, msg);
                 self.cx.trace_macros_diag();
-                invoc.fragment_kind.dummy(span)
+                invoc.fragment_kind.dummy(path.span)
             }
         }
     }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 22745a1a76d..7f051c260ec 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,6 +1,7 @@
 use crate::{ast, attr};
 use crate::edition::Edition;
-use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension, TTMacroExpander};
+use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind};
+use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
 use crate::ext::expand::{AstFragment, AstFragmentKind};
 use crate::ext::hygiene::Transparency;
 use crate::ext::tt::macro_parser::{Success, Error, Failure};
@@ -376,7 +377,7 @@ pub fn compile(
         valid,
     });
 
-    let transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) {
+    let default_transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) {
         Transparency::Transparent
     } else if body.legacy {
         Transparency::SemiTransparent
@@ -426,14 +427,15 @@ pub fn compile(
         }
     });
 
-    SyntaxExtension::LegacyBang {
-        expander,
+    SyntaxExtension {
+        kind: SyntaxExtensionKind::LegacyBang(expander),
         def_info: Some((def.id, def.span)),
-        transparency,
+        default_transparency,
         allow_internal_unstable,
         allow_internal_unsafe,
         local_inner_macros,
         unstable_feature,
+        helper_attrs: Vec::new(),
         edition,
     }
 }
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index eea94f0d194..6630bf90815 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -16,15 +16,9 @@ use syntax_pos::{DUMMY_SP, Span};
 /// The expanded code uses the unstable `#[prelude_import]` attribute.
 fn ignored_span(sp: Span, edition: Edition) -> Span {
     let mark = Mark::fresh(Mark::root());
-    mark.set_expn_info(ExpnInfo {
-        call_site: DUMMY_SP,
-        def_site: None,
-        format: MacroAttribute(Symbol::intern("std_inject")),
-        allow_internal_unstable: Some(vec![sym::prelude_import].into()),
-        allow_internal_unsafe: false,
-        local_inner_macros: false,
-        edition,
-    });
+    mark.set_expn_info(ExpnInfo::with_unstable(
+        MacroAttribute(Symbol::intern("std_inject")), sp, edition, &[sym::prelude_import]
+    ));
     sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
 }
 
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index cbaf12529c1..f90b76721ee 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -280,15 +280,10 @@ fn generate_test_harness(sess: &ParseSess,
         test_runner
     };
 
-    mark.set_expn_info(ExpnInfo {
-        call_site: DUMMY_SP,
-        def_site: None,
-        format: MacroAttribute(sym::test_case),
-        allow_internal_unstable: Some(vec![sym::main, sym::test, sym::rustc_attrs].into()),
-        allow_internal_unsafe: false,
-        local_inner_macros: false,
-        edition: sess.edition,
-    });
+    mark.set_expn_info(ExpnInfo::with_unstable(
+        MacroAttribute(sym::test_case), DUMMY_SP, sess.edition,
+        &[sym::main, sym::test, sym::rustc_attrs],
+    ));
 
     TestHarnessGenerator {
         cx,