diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index a9ba7334d930e..8f09389b2e7e9 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -23,6 +23,7 @@ extern crate proc_macro; use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; use rustc_span::symbol::sym; +use smallvec::smallvec; use crate::deriving::*; @@ -66,8 +67,16 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { macro register_attr($($name:ident: $f:expr,)*) { $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)* } - macro register_derive($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)* + macro_rules! register_derive { + ($name:ident: $f:expr, $($rest:tt)*) => { + register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f)), smallvec![])); + register_derive!($($rest)*); + }; + ($name:ident[$($attr:ident),+]: $f:expr, $($rest:tt)*) => { + register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f)), smallvec![$(sym::$attr),*])); + register_derive!($($rest)*); + }; + () => {}; } register_bang! { @@ -128,7 +137,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { PartialOrd: partial_ord::expand_deriving_partial_ord, RustcDecodable: decodable::expand_deriving_rustc_decodable, RustcEncodable: encodable::expand_deriving_rustc_encodable, - SmartPointer: smart_ptr::expand_deriving_smart_ptr, + SmartPointer[pointee]: smart_ptr::expand_deriving_smart_ptr, } let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index c195d69258899..7172e74388f92 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -714,6 +714,8 @@ pub enum SyntaxExtensionKind { /// An expander with signature AST -> AST. /// The produced AST fragment is appended to the input AST fragment. Box, + /// Helper attributes + SmallVec<[Symbol; 1]>, ), /// A glob delegation. diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index d8cb367e3face..a61b3389e678c 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -781,7 +781,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }, InvocationKind::Derive { path, item, is_const } => match ext { SyntaxExtensionKind::Derive(expander) - | SyntaxExtensionKind::LegacyDerive(expander) => { + | SyntaxExtensionKind::LegacyDerive(expander, _) => { if let SyntaxExtensionKind::Derive(..) = ext { self.gate_proc_macro_input(&item); } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 6f177107e7025..fc0c328819caf 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -366,14 +366,14 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>( // // Holy self-referential! -/// Converts a macro item into a syntax extension. +/// Converts a macro item `def` into a syntax extension. +#[instrument(level = "debug", skip(sess, features))] pub fn compile_declarative_macro( sess: &Session, features: &Features, def: &ast::Item, edition: Edition, ) -> (SyntaxExtension, Vec<(usize, Span)>) { - debug!("compile_declarative_macro: {:?}", def); let mk_syn_ext = |expander| { SyntaxExtension::new( sess, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 72ea55d5999a2..bb0e989bd812a 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -578,12 +578,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, coroutines, experimental!(coroutines) ), - // `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro - gated!( - pointee, Normal, template!(Word), ErrorFollowing, - EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) - ), - // RFC 3543 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index da7278175e93a..4b5919f8365f3 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -34,6 +34,7 @@ use rustc_span::edition::Edition; use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use tracing::instrument; use crate::errors::{ self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope, @@ -1117,6 +1118,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Compile the macro into a `SyntaxExtension` and its rule spans. /// /// Possibly replace its expander to a pre-defined one for built-in macros. + #[instrument(level = "debug", skip(self))] pub(crate) fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> MacroData { let (mut ext, mut rule_spans) = compile_declarative_macro(self.tcx.sess, self.tcx.features(), item, edition); @@ -1129,6 +1131,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'. match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) { BuiltinMacroState::NotYetSeen(builtin_ext) => { + if let SyntaxExtensionKind::LegacyDerive(_expander, helper_attrs) = + &builtin_ext + { + ext.helper_attrs.extend(helper_attrs.iter().copied()); + } ext.kind = builtin_ext; rule_spans = Vec::new(); }