From dd6347a6b930850557d61fa3f230476ffaf5630f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 15 Sep 2018 23:46:54 +0300 Subject: [PATCH] resolve: Integrate inert attributes registererd by legacy plugins into macro resolution --- src/librustc/hir/def.rs | 3 +++ src/librustc/ich/impls_hir.rs | 1 + src/librustc_resolve/macros.rs | 42 +++++++++++++++++++++++++--------- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 4286b0628f5f..5d9d4deb0abc 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -36,6 +36,8 @@ pub enum NonMacroAttrKind { Tool, /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`). DeriveHelper, + /// Single-segment custom attriubte registered by a legacy plugin (`register_attribute`). + LegacyPluginHelper, /// Single-segment custom attribute not registered in any way (`#[my_attr]`). Custom, } @@ -259,6 +261,7 @@ impl NonMacroAttrKind { NonMacroAttrKind::Builtin => "built-in attribute", NonMacroAttrKind::Tool => "tool attribute", NonMacroAttrKind::DeriveHelper => "derive helper attribute", + NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute", NonMacroAttrKind::Custom => "custom attribute", } } diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 23533b7a4c39..a4386c6cbfd4 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1012,6 +1012,7 @@ impl_stable_hash_for!(enum hir::def::NonMacroAttrKind { Builtin, Tool, DeriveHelper, + LegacyPluginHelper, Custom, }); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index ff6e8a96f30b..44f95dd307e1 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -248,11 +248,6 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { for i in 0..attrs.len() { let name = attrs[i].name(); - if self.session.plugin_attributes.borrow().iter() - .any(|&(ref attr_nm, _)| name == &**attr_nm) { - attr::mark_known(&attrs[i]); - } - match self.builtin_macros.get(&name).cloned() { Some(binding) => match *binding.get_macro(self) { MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => { @@ -591,6 +586,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled) // 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins). // 4. Language prelude: builtin attributes (closed, controlled). + // N (unordered). Derive helpers (open, not controlled). All ambiguities with other names + // are currently reported as errors. They should be higher in priority than preludes + // and maybe even names in modules according to the "general principles" above. They + // also should be subject to restricted shadowing because are effectively produced by + // derives (you need to resolve the derive first to add helpers into scope), but they + // should be available before the derive is expanded for compatibility. + // It's mess in general, so we are being conservative for now. + // N (unordered). Legacy plugin helpers (open, not controlled). Similar to derive helpers, + // but introduced by legacy plugins using `register_attribute`. assert!(ns == TypeNS || ns == MacroNS); assert!(force || !record_used); // `record_used` implies `force` @@ -615,6 +619,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { BuiltinMacros, BuiltinAttrs, DeriveHelpers, + LegacyPluginHelpers, ExternPrelude, ToolPrelude, StdLibPrelude, @@ -681,6 +686,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } result } + WhereToResolve::LegacyPluginHelpers => { + if self.session.plugin_attributes.borrow().iter() + .any(|(name, _)| ident.name == &**name) { + let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper), + ty::Visibility::Public, ident.span, Mark::root()) + .to_name_binding(self.arenas); + Ok((binding, FromPrelude(false))) + } else { + Err(Determinacy::Determined) + } + } WhereToResolve::ExternPrelude => { if use_prelude && self.session.extern_prelude.contains(&ident.name) { let crate_id = @@ -752,8 +768,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros, WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs, - WhereToResolve::BuiltinAttrs => break, // nowhere else to search - WhereToResolve::DeriveHelpers => WhereToResolve::Module(parent_scope.module), + WhereToResolve::BuiltinAttrs => WhereToResolve::DeriveHelpers, + WhereToResolve::DeriveHelpers => WhereToResolve::LegacyPluginHelpers, + WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes, @@ -775,12 +792,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if let Some(innermost_result) = innermost_result { // Found another solution, if the first one was "weak", report an error. - let (def, innermost_def) = (result.0.def(), innermost_result.0.def()); - if def != innermost_def && + let prohibit_ambiguities = |def| { + def == Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper) || + def == Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper) + }; + if result.0.def() != innermost_result.0.def() && (innermost_result.0.is_glob_import() || innermost_result.0.may_appear_after(parent_scope.expansion, result.0) || - innermost_def == Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper) || - def == Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper)) { + prohibit_ambiguities(innermost_result.0.def()) || + prohibit_ambiguities(result.0.def())) { self.ambiguity_errors.push(AmbiguityError { ident, b1: innermost_result.0,