diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f76de96cd10da..31025a01a366c 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -61,6 +61,7 @@ use syntax::ast; use syntax::ptr::P as AstP; use syntax::ast::*; use syntax::errors; +use syntax::ext::base::SpecialDerives; use syntax::ext::hygiene::ExpnId; use syntax::print::pprust; use syntax::source_map::{respan, ExpnInfo, ExpnKind, DesugaringKind, Spanned}; @@ -176,6 +177,8 @@ pub trait Resolver { components: &[Symbol], is_value: bool, ) -> (ast::Path, Res); + + fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool; } /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, @@ -1329,13 +1332,17 @@ impl<'a> LoweringContext<'a> { } } - fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec { + fn lower_attrs_extendable(&mut self, attrs: &[Attribute]) -> Vec { attrs .iter() .map(|a| self.lower_attr(a)) .collect() } + fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec { + self.lower_attrs_extendable(attrs).into() + } + fn lower_attr(&mut self, attr: &Attribute) -> Attribute { // Note that we explicitly do not walk the path. Since we don't really // lower attributes (we use the AST version) there is nowhere to keep @@ -4028,7 +4035,14 @@ impl<'a> LoweringContext<'a> { pub fn lower_item(&mut self, i: &Item) -> Option { let mut ident = i.ident; let mut vis = self.lower_visibility(&i.vis, None); - let attrs = self.lower_attrs(&i.attrs); + let mut attrs = self.lower_attrs_extendable(&i.attrs); + if self.resolver.has_derives(i.id, SpecialDerives::PARTIAL_EQ | SpecialDerives::EQ) { + // Add `#[structural_match]` if the item derived both `PartialEq` and `Eq`. + let ident = Ident::new(sym::structural_match, i.span); + attrs.push(attr::mk_attr_outer(attr::mk_word_item(ident))); + } + let attrs = attrs.into(); + if let ItemKind::MacroDef(ref def) = i.node { if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) { let body = self.lower_token_stream(def.stream()); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a49be7c27c94a..67db509eab2de 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -38,8 +38,7 @@ use rustc_metadata::cstore::CStore; use syntax::source_map::SourceMap; use syntax::ext::hygiene::{ExpnId, Transparency, SyntaxContext}; use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy}; -use syntax::ext::base::SyntaxExtension; -use syntax::ext::base::MacroKind; +use syntax::ext::base::{SyntaxExtension, MacroKind, SpecialDerives}; use syntax::symbol::{Symbol, kw, sym}; use syntax::util::lev_distance::find_best_match_for_name; @@ -1685,6 +1684,12 @@ pub struct Resolver<'a> { local_macro_def_scopes: FxHashMap>, unused_macros: NodeMap, proc_macro_stubs: NodeSet, + /// Some built-in derives mark items they are applied to so they are treated specially later. + /// Derive macros cannot modify the item themselves and have to store the markers in the global + /// context, so they attach the markers to derive container IDs using this resolver table. + /// FIXME: Find a way for `PartialEq` and `Eq` to emulate `#[structural_match]` + /// by marking the produced impls rather than the original items. + special_derives: FxHashMap, /// Maps the `ExpnId` of an expansion to its containing module or block. invocations: FxHashMap>, @@ -1813,6 +1818,12 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { fn definitions(&mut self) -> &mut Definitions { &mut self.definitions } + + fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool { + let def_id = self.definitions.local_def_id(node_id); + let expn_id = self.definitions.expansion_that_defined(def_id.index); + self.has_derives(expn_id, derives) + } } impl<'a> Resolver<'a> { @@ -2031,6 +2042,7 @@ impl<'a> Resolver<'a> { struct_constructors: Default::default(), unused_macros: Default::default(), proc_macro_stubs: Default::default(), + special_derives: Default::default(), current_type_ascription: Vec::new(), injected_crate: None, active_features: @@ -2077,6 +2089,10 @@ impl<'a> Resolver<'a> { } } + fn has_derives(&self, expn_id: ExpnId, markers: SpecialDerives) -> bool { + self.special_derives.get(&expn_id).map_or(false, |m| m.contains(markers)) + } + /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { ImportResolver { resolver: self }.finalize_imports(); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 88850c5988b7b..1f534bc41fe6f 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -14,7 +14,7 @@ use rustc::{ty, lint, span_bug}; use syntax::ast::{self, Ident, ItemKind}; use syntax::attr::{self, StabilityLevel}; use syntax::edition::Edition; -use syntax::ext::base::{self, Indeterminate}; +use syntax::ext::base::{self, Indeterminate, SpecialDerives}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, ExpnId, ExpnInfo, ExpnKind}; @@ -203,8 +203,28 @@ impl<'a> base::Resolver for Resolver<'a> { (&mac.node.path, MacroKind::Bang, Vec::new(), false), InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive, Vec::new(), false), - InvocationKind::DeriveContainer { .. } => - return Ok(None), + InvocationKind::DeriveContainer { ref derives, .. } => { + // Block expansion of derives in the container until we know whether one of them + // is a built-in `Copy`. Skip the resolution if there's only one derive - either + // it's not a `Copy` and we don't need to do anything, or it's a `Copy` and it + // will automatically knows about itself. + let mut result = Ok(None); + if derives.len() > 1 { + let parent_scope = self.invoc_parent_scope(invoc_id, Vec::new()); + for path in derives { + match self.resolve_macro_path(path, Some(MacroKind::Derive), + &parent_scope, true, force) { + Ok((Some(ref ext), _)) if ext.is_derive_copy => { + self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY); + return Ok(None); + } + Err(Determinacy::Undetermined) => result = Err(Indeterminate), + _ => {} + } + } + } + return result; + } }; let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope); @@ -234,6 +254,14 @@ impl<'a> base::Resolver for Resolver<'a> { ); } } + + fn has_derives(&self, expn_id: ExpnId, derives: SpecialDerives) -> bool { + self.has_derives(expn_id, derives) + } + + fn add_derives(&mut self, expn_id: ExpnId, derives: SpecialDerives) { + *self.special_derives.entry(expn_id).or_default() |= derives; + } } impl<'a> Resolver<'a> { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index bb7834a133f03..5e1cc70784eac 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -595,6 +595,8 @@ pub struct SyntaxExtension { /// Built-in macros have a couple of special properties (meaning of `$crate`, /// availability in `#[no_implicit_prelude]` modules), so we have to keep this flag. pub is_builtin: bool, + /// We have to identify macros providing a `Copy` impl early for compatibility reasons. + pub is_derive_copy: bool, } impl SyntaxExtensionKind { @@ -640,6 +642,7 @@ impl SyntaxExtension { helper_attrs: Vec::new(), edition, is_builtin: false, + is_derive_copy: false, kind, } } @@ -683,6 +686,16 @@ pub type NamedSyntaxExtension = (Name, SyntaxExtension); /// Error type that denotes indeterminacy. pub struct Indeterminate; +bitflags::bitflags! { + /// Built-in derives that need some extra tracking beyond the usual macro functionality. + #[derive(Default)] + pub struct SpecialDerives: u8 { + const PARTIAL_EQ = 1 << 0; + const EQ = 1 << 1; + const COPY = 1 << 2; + } +} + pub trait Resolver { fn next_node_id(&mut self) -> ast::NodeId; @@ -699,6 +712,9 @@ pub trait Resolver { -> Result>, Indeterminate>; fn check_unused_macros(&self); + + fn has_derives(&self, expn_id: ExpnId, derives: SpecialDerives) -> bool; + fn add_derives(&mut self, expn_id: ExpnId, derives: SpecialDerives); } #[derive(Clone)] @@ -725,7 +741,6 @@ pub struct ExtCtxt<'a> { pub resolver: &'a mut dyn Resolver, pub current_expansion: ExpansionData, pub expansions: FxHashMap>, - pub allow_derive_markers: Lrc<[Symbol]>, } impl<'a> ExtCtxt<'a> { @@ -745,7 +760,6 @@ impl<'a> ExtCtxt<'a> { directory_ownership: DirectoryOwnership::Owned { relative: None }, }, expansions: FxHashMap::default(), - allow_derive_markers: [sym::rustc_attrs, sym::structural_match][..].into(), } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 1e9e16d72f829..c16e772d1cc2a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -4,7 +4,7 @@ use crate::attr::{self, HasAttrs}; use crate::source_map::{dummy_spanned, respan}; use crate::config::StripUnconfigured; use crate::ext::base::*; -use crate::ext::proc_macro::{add_derived_markers, collect_derives}; +use crate::ext::proc_macro::collect_derives; use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind}; use crate::ext::placeholders::{placeholder, PlaceholderExpander}; use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; @@ -209,7 +209,6 @@ pub enum InvocationKind { Derive { path: Path, item: Annotatable, - item_with_markers: Annotatable, }, /// "Invocation" that contains all derives from an item, /// broken into multiple `Derive` invocations when expanded. @@ -360,8 +359,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let mut item = self.fully_configure(item); item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive)); - let mut item_with_markers = item.clone(); - add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers); let derives = derives.entry(invoc.expansion_data.id).or_default(); derives.reserve(traits.len()); @@ -370,11 +367,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let expn_id = ExpnId::fresh(self.cx.current_expansion.id, None); derives.push(expn_id); invocations.push(Invocation { - kind: InvocationKind::Derive { - path, - item: item.clone(), - item_with_markers: item_with_markers.clone(), - }, + kind: InvocationKind::Derive { path, item: item.clone() }, fragment_kind: invoc.fragment_kind, expansion_data: ExpansionData { id: expn_id, @@ -383,7 +376,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }); } let fragment = invoc.fragment_kind - .expect_from_annotatables(::std::iter::once(item_with_markers)); + .expect_from_annotatables(::std::iter::once(item)); self.collect_invocations(fragment, derives) } else { unreachable!() @@ -569,13 +562,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => unreachable!() } - InvocationKind::Derive { path, item, item_with_markers } => match ext { + InvocationKind::Derive { path, item } => match ext { SyntaxExtensionKind::Derive(expander) | SyntaxExtensionKind::LegacyDerive(expander) => { - let (path, item) = match ext { - SyntaxExtensionKind::LegacyDerive(..) => (path, item_with_markers), - _ => (path, item), - }; if !item.derive_allowed() { return fragment_kind.dummy(span); } diff --git a/src/libsyntax/ext/proc_macro.rs b/src/libsyntax/ext/proc_macro.rs index ec708994fad86..c17b6f6b4248a 100644 --- a/src/libsyntax/ext/proc_macro.rs +++ b/src/libsyntax/ext/proc_macro.rs @@ -1,17 +1,15 @@ use crate::ast::{self, ItemKind, Attribute, Mac}; -use crate::attr::{mark_used, mark_known, HasAttrs}; +use crate::attr::{mark_used, mark_known}; use crate::errors::{Applicability, FatalError}; use crate::ext::base::{self, *}; use crate::ext::proc_macro_server; use crate::parse::{self, token}; use crate::parse::parser::PathStyle; -use crate::symbol::{sym, Symbol}; +use crate::symbol::sym; use crate::tokenstream::{self, TokenStream}; use crate::visit::Visitor; -use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; -use syntax_pos::hygiene::{ExpnInfo, ExpnKind}; use syntax_pos::{Span, DUMMY_SP}; const EXEC_STRATEGY: proc_macro::bridge::server::SameThread = @@ -217,32 +215,3 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) }); result } - -crate fn add_derived_markers( - cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::Path], item: &mut T -) { - let (mut names, mut pretty_name) = (FxHashSet::default(), String::new()); - for (i, path) in traits.iter().enumerate() { - if i > 0 { - pretty_name.push_str(", "); - } - pretty_name.push_str(&path.to_string()); - names.insert(unwrap_or!(path.segments.get(0), continue).ident.name); - } - - let span = span.fresh_expansion(cx.current_expansion.id, ExpnInfo::allow_unstable( - ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span, - cx.parse_sess.edition, cx.allow_derive_markers.clone(), - )); - - item.visit_attrs(|attrs| { - if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) { - let meta = cx.meta_word(span, sym::structural_match); - attrs.push(cx.attribute(meta)); - } - if names.contains(&sym::Copy) { - let meta = cx.meta_word(span, sym::rustc_copy_clone_marker); - attrs.push(cx.attribute(meta)); - } - }); -} diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index ce695df777572..4ca2971dbbce4 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -429,6 +429,8 @@ pub fn compile( } } + let is_builtin = attr::contains_name(&def.attrs, sym::rustc_builtin_macro); + SyntaxExtension { kind: SyntaxExtensionKind::LegacyBang(expander), span: def.span, @@ -440,7 +442,8 @@ pub fn compile( deprecation: attr::find_deprecation(&sess, &def.attrs, def.span), helper_attrs: Vec::new(), edition, - is_builtin: attr::contains_name(&def.attrs, sym::rustc_builtin_macro), + is_builtin, + is_derive_copy: is_builtin && def.ident.name == sym::Copy, } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 33d10b269e1e3..261214ff87354 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1329,11 +1329,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ /*opt*/ attributes(name1, name2, ...)"), Ungated), - (sym::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal implementation detail", - cfg_fn!(rustc_attrs))), - (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, sym::rustc_attrs, "internal implementation detail", diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index 2340238aaea41..3b1edf90d6bf2 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -3,8 +3,7 @@ use crate::deriving::generic::*; use crate::deriving::generic::ty::*; use syntax::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData}; -use syntax::attr; -use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::ext::base::{Annotatable, ExtCtxt, SpecialDerives}; use syntax::ptr::P; use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; @@ -36,7 +35,8 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, match annitem.node { ItemKind::Struct(_, Generics { ref params, .. }) | ItemKind::Enum(_, Generics { ref params, .. }) => { - if attr::contains_name(&annitem.attrs, sym::rustc_copy_clone_marker) && + let container_id = cx.current_expansion.id.parent(); + if cx.resolver.has_derives(container_id, SpecialDerives::COPY) && !params.iter().any(|param| match param.kind { ast::GenericParamKind::Type { .. } => true, _ => false, diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 0c34599814a79..1909729f4a941 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -3,7 +3,7 @@ use crate::deriving::generic::*; use crate::deriving::generic::ty::*; use syntax::ast::{self, Expr, MetaItem, GenericArg}; -use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::ext::base::{Annotatable, ExtCtxt, SpecialDerives}; use syntax::ptr::P; use syntax::symbol::{sym, Symbol}; use syntax_pos::Span; @@ -13,6 +13,8 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { + cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::EQ); + let inline = cx.meta_word(span, sym::inline); let hidden = cx.meta_list_item_word(span, sym::hidden); let doc = cx.meta_list(span, sym::doc, vec![hidden]); diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 337f7c5cfe238..7d7c4ae22a8a6 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -3,7 +3,7 @@ use crate::deriving::generic::*; use crate::deriving::generic::ty::*; use syntax::ast::{BinOpKind, Expr, MetaItem}; -use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::ext::base::{Annotatable, ExtCtxt, SpecialDerives}; use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos::Span; @@ -13,6 +13,8 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { + cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::PARTIAL_EQ); + // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different fn cs_op(cx: &mut ExtCtxt<'_>, diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 4a0c4a39f785b..d236f31f36fa4 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -186,7 +186,7 @@ use rustc_target::spec::abi::Abi; use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind}; use syntax::ast::{VariantData, GenericParamKind, GenericArg}; use syntax::attr; -use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::ext::base::{Annotatable, ExtCtxt, SpecialDerives}; use syntax::source_map::{self, respan}; use syntax::util::map_in_place::MapInPlace; use syntax::ptr::P; @@ -425,8 +425,9 @@ impl<'a> TraitDef<'a> { return; } }; + let container_id = cx.current_expansion.id.parent(); let is_always_copy = - attr::contains_name(&item.attrs, sym::rustc_copy_clone_marker) && + cx.resolver.has_derives(container_id, SpecialDerives::COPY) && has_no_type_params; let use_temporaries = is_packed && is_always_copy; diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 12c4ba059feb6..f7e1b983e5446 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -565,7 +565,6 @@ symbols! { rustc_clean, rustc_const_unstable, rustc_conversion_suggestion, - rustc_copy_clone_marker, rustc_def_path, rustc_deprecated, rustc_diagnostic_macros, diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout index 72b02ebcb76f4..da1d7549d0750 100644 --- a/src/test/ui/proc-macro/dollar-crate.stdout +++ b/src/test/ui/proc-macro/dollar-crate.stdout @@ -124,40 +124,40 @@ PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ; PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "M", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Joint, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "S", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ], - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ';', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ] PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S); @@ -165,40 +165,40 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "A", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Joint, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "S", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ], - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ';', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ] PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S); @@ -206,39 +206,39 @@ PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ($crate :: S) ; PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "D", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Joint, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "S", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ], - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ';', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ] diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index e6017dc4d1163..b2f124788286d 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -46,18 +46,6 @@ error: expected attribute, found derive macro `MyTrait` LL | #[MyTrait] | ^^^^^^^ not an attribute -error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:49:10 - | -LL | #[derive(crate::my_macro)] - | ^^^^^^^^^^^^^^^ - -error: expected derive macro, found macro `crate::my_macro` - --> $DIR/macro-namespace-reserved-2.rs:49:10 - | -LL | #[derive(crate::my_macro)] - | ^^^^^^^^^^^^^^^ not a derive macro - error: can't use a procedural macro from the same crate that defines it --> $DIR/macro-namespace-reserved-2.rs:52:10 | @@ -88,6 +76,18 @@ error: expected attribute, found macro `crate::my_macro` LL | #[crate::my_macro] | ^^^^^^^^^^^^^^^ not an attribute +error: can't use a procedural macro from the same crate that defines it + --> $DIR/macro-namespace-reserved-2.rs:49:10 + | +LL | #[derive(crate::my_macro)] + | ^^^^^^^^^^^^^^^ + +error: expected derive macro, found macro `crate::my_macro` + --> $DIR/macro-namespace-reserved-2.rs:49:10 + | +LL | #[derive(crate::my_macro)] + | ^^^^^^^^^^^^^^^ not a derive macro + error: cannot find attribute macro `my_macro` in this scope --> $DIR/macro-namespace-reserved-2.rs:38:3 | diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.rs b/src/test/ui/span/issue-43927-non-ADT-derive.rs index add1758dddfb6..8f1599a5abcb0 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.rs +++ b/src/test/ui/span/issue-43927-non-ADT-derive.rs @@ -2,6 +2,9 @@ #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! //~^ ERROR `derive` may only be applied to structs, enums and unions +//~| ERROR cannot determine resolution for the derive macro `Debug` +//~| ERROR cannot determine resolution for the derive macro `PartialEq` +//~| ERROR cannot determine resolution for the derive macro `Eq` struct DerivedOn; fn main() {} diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.stderr b/src/test/ui/span/issue-43927-non-ADT-derive.stderr index e09a8a0e8fb93..47ce718600cec 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.stderr +++ b/src/test/ui/span/issue-43927-non-ADT-derive.stderr @@ -4,5 +4,29 @@ error: `derive` may only be applied to structs, enums and unions LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try an outer attribute: `#[derive(Debug, PartialEq, Eq)]` -error: aborting due to previous error +error: cannot determine resolution for the derive macro `Debug` + --> $DIR/issue-43927-non-ADT-derive.rs:3:11 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: cannot determine resolution for the derive macro `PartialEq` + --> $DIR/issue-43927-non-ADT-derive.rs:3:18 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^^^^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: cannot determine resolution for the derive macro `Eq` + --> $DIR/issue-43927-non-ADT-derive.rs:3:29 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: aborting due to 4 previous errors