about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-09-15 23:46:54 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-10-05 11:40:19 +0400
commitdd6347a6b930850557d61fa3f230476ffaf5630f (patch)
tree7ecc69197c1dcc3b90898d262fc27d7a088063db
parentb8bea5a0a6aef3966008787a25949344f8cf6942 (diff)
downloadrust-dd6347a6b930850557d61fa3f230476ffaf5630f.tar.gz
rust-dd6347a6b930850557d61fa3f230476ffaf5630f.zip
resolve: Integrate inert attributes registererd by legacy plugins into macro resolution
-rw-r--r--src/librustc/hir/def.rs3
-rw-r--r--src/librustc/ich/impls_hir.rs1
-rw-r--r--src/librustc_resolve/macros.rs42
3 files changed, 35 insertions, 11 deletions
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 4286b0628f5..5d9d4deb0ab 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 23533b7a4c3..a4386c6cbfd 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 ff6e8a96f30..44f95dd307e 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,