about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-18 23:22:58 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-19 00:50:53 +0300
commitf74fe812fe802c71bd9f909cbce8a703a20ba479 (patch)
treeda48d032e8f0c44c925eab83b6a5fbe79356d1e8
parenta0d40f8bdfcc3c28355467973f97fd4c45ac5876 (diff)
downloadrust-f74fe812fe802c71bd9f909cbce8a703a20ba479.tar.gz
rust-f74fe812fe802c71bd9f909cbce8a703a20ba479.zip
resolve: Give derive helpers highest priority during resolution
-rw-r--r--src/librustc_resolve/macros.rs25
-rw-r--r--src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs12
-rw-r--r--src/test/ui/proc-macro/derive-helper-shadowing-2.rs16
-rw-r--r--src/test/ui/proc-macro/derive-helper-shadowing.rs4
-rw-r--r--src/test/ui/proc-macro/derive-helper-shadowing.stderr38
5 files changed, 47 insertions, 48 deletions
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 4f687b5ba92..8dc0fb9bd77 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -466,11 +466,12 @@ impl<'a> Resolver<'a> {
     ) -> Result<&'a NameBinding<'a>, Determinacy> {
         bitflags::bitflags! {
             struct Flags: u8 {
-                const MACRO_RULES        = 1 << 0;
-                const MODULE             = 1 << 1;
-                const MISC_SUGGEST_CRATE = 1 << 2;
-                const MISC_SUGGEST_SELF  = 1 << 3;
-                const MISC_FROM_PRELUDE  = 1 << 4;
+                const MACRO_RULES          = 1 << 0;
+                const MODULE               = 1 << 1;
+                const DERIVE_HELPER_COMPAT = 1 << 2;
+                const MISC_SUGGEST_CRATE   = 1 << 3;
+                const MISC_SUGGEST_SELF    = 1 << 4;
+                const MISC_FROM_PRELUDE    = 1 << 5;
             }
         }
 
@@ -528,8 +529,10 @@ impl<'a> Resolver<'a> {
                         match this.resolve_macro_path(derive, Some(MacroKind::Derive),
                                                       parent_scope, true, force) {
                             Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) {
-                                let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
-                                result = ok(res, derive.span, this.arenas);
+                                let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
+                                               ty::Visibility::Public, derive.span, ExpnId::root())
+                                               .to_name_binding(this.arenas);
+                                result = Ok((binding, Flags::DERIVE_HELPER_COMPAT));
                                 break;
                             }
                             Ok(_) | Err(Determinacy::Determined) => {}
@@ -659,13 +662,17 @@ impl<'a> Resolver<'a> {
                         let (res, innermost_res) = (binding.res(), innermost_binding.res());
                         if res != innermost_res {
                             let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
-                            let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
+                            let is_derive_helper_compat = |res, flags: Flags| {
+                                res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper) &&
+                                flags.contains(Flags::DERIVE_HELPER_COMPAT)
+                            };
 
                             let ambiguity_error_kind = if is_import {
                                 Some(AmbiguityKind::Import)
                             } else if innermost_res == builtin || res == builtin {
                                 Some(AmbiguityKind::BuiltinAttr)
-                            } else if innermost_res == derive_helper || res == derive_helper {
+                            } else if is_derive_helper_compat(innermost_res, innermost_flags) ||
+                                      is_derive_helper_compat(res, flags) {
                                 Some(AmbiguityKind::DeriveHelper)
                             } else if innermost_flags.contains(Flags::MACRO_RULES) &&
                                       flags.contains(Flags::MODULE) &&
diff --git a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs
new file mode 100644
index 00000000000..370a1a2794d
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro_derive(same_name, attributes(same_name))]
+pub fn derive_a(_: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
diff --git a/src/test/ui/proc-macro/derive-helper-shadowing-2.rs b/src/test/ui/proc-macro/derive-helper-shadowing-2.rs
new file mode 100644
index 00000000000..5204d72b980
--- /dev/null
+++ b/src/test/ui/proc-macro/derive-helper-shadowing-2.rs
@@ -0,0 +1,16 @@
+// If a derive macro introduces a helper attribute with the same name as that macro,
+// then make sure that it's usable without ambiguities.
+
+// check-pass
+// aux-build:derive-helper-shadowing-2.rs
+
+#[macro_use]
+extern crate derive_helper_shadowing_2;
+
+#[derive(same_name)]
+struct S {
+    #[same_name] // OK, no ambiguity, derive helpers have highest priority
+    field: u8,
+}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs
index f0ca34db414..6147e96a74b 100644
--- a/src/test/ui/proc-macro/derive-helper-shadowing.rs
+++ b/src/test/ui/proc-macro/derive-helper-shadowing.rs
@@ -19,11 +19,11 @@ macro_rules! gen_helper_use {
 #[empty_helper] //~ ERROR `empty_helper` is ambiguous
 #[derive(Empty)]
 struct S {
-    #[empty_helper] //~ ERROR `empty_helper` is ambiguous
+    #[empty_helper] // OK, no ambiguity, derive helpers have highest priority
     field: [u8; {
         use empty_helper; //~ ERROR `empty_helper` is ambiguous
 
-        #[empty_helper] //~ ERROR `empty_helper` is ambiguous
+        #[empty_helper] // OK, no ambiguity, derive helpers have highest priority
         struct U;
 
         mod inner {
diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr
index 9048830bee2..76434860a49 100644
--- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr
+++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr
@@ -61,42 +61,6 @@ LL | use test_macros::empty_attr as empty_helper;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
 
-error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
-  --> $DIR/derive-helper-shadowing.rs:22:7
-   |
-LL |     #[empty_helper]
-   |       ^^^^^^^^^^^^ ambiguous name
-   |
-note: `empty_helper` could refer to the derive helper attribute defined here
-  --> $DIR/derive-helper-shadowing.rs:20:10
-   |
-LL | #[derive(Empty)]
-   |          ^^^^^
-note: `empty_helper` could also refer to the attribute macro imported here
-  --> $DIR/derive-helper-shadowing.rs:10:5
-   |
-LL | use test_macros::empty_attr as empty_helper;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
-
-error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
-  --> $DIR/derive-helper-shadowing.rs:26:11
-   |
-LL |         #[empty_helper]
-   |           ^^^^^^^^^^^^ ambiguous name
-   |
-note: `empty_helper` could refer to the derive helper attribute defined here
-  --> $DIR/derive-helper-shadowing.rs:20:10
-   |
-LL | #[derive(Empty)]
-   |          ^^^^^
-note: `empty_helper` could also refer to the attribute macro imported here
-  --> $DIR/derive-helper-shadowing.rs:10:5
-   |
-LL | use test_macros::empty_attr as empty_helper;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
-
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0659`.