]> git.lizzy.rs Git - rust.git/commitdiff
resolve: Integrate inert attributes registererd by legacy plugins into macro resolution
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 15 Sep 2018 20:46:54 +0000 (23:46 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Fri, 5 Oct 2018 07:40:19 +0000 (11:40 +0400)
src/librustc/hir/def.rs
src/librustc/ich/impls_hir.rs
src/librustc_resolve/macros.rs

index 4286b0628f5fff76f7054e69d74650287483850e..5d9d4deb0abc9e95793aa303ce1a621980cc0b1c 100644 (file)
@@ -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 @@ fn descr(self) -> &'static str {
             NonMacroAttrKind::Builtin => "built-in attribute",
             NonMacroAttrKind::Tool => "tool attribute",
             NonMacroAttrKind::DeriveHelper => "derive helper attribute",
+            NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute",
             NonMacroAttrKind::Custom => "custom attribute",
         }
     }
index 23533b7a4c3901f9f38587d7b36d2dd7e410af67..a4386c6cbfd43e54d12c4c75f3480421b9b84d17 100644 (file)
@@ -1012,6 +1012,7 @@ fn to_stable_hash_key(&self,
     Builtin,
     Tool,
     DeriveHelper,
+    LegacyPluginHelper,
     Custom,
 });
 
index ff6e8a96f30ba645be1452eb36f39f374b9f6387..44f95dd307e1ead978577a9ae3917617c62aa2a2 100644 (file)
@@ -248,11 +248,6 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_deri
         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 @@ pub fn resolve_macro_to_def_inner(
         // 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 @@ enum WhereToResolve<'a> {
             BuiltinMacros,
             BuiltinAttrs,
             DeriveHelpers,
+            LegacyPluginHelpers,
             ExternPrelude,
             ToolPrelude,
             StdLibPrelude,
@@ -681,6 +686,17 @@ enum WhereToResolve<'a> {
                     }
                     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 @@ macro_rules! continue_search { () => {
                     }
                     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 @@ macro_rules! continue_search { () => {
 
                     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,