about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2018-09-25 22:34:43 +0200
committerGitHub <noreply@github.com>2018-09-25 22:34:43 +0200
commitcf3c385fef4d8bc071f51ecdb1004e73c7fe8a9b (patch)
treee2b627785c1a3a26104ac74b71c4e749fc525cbd /src
parent4720126c16b4cc961b04942a30d5d6db86edfaeb (diff)
parentee05f6eef4f97188a94874eacf2dad59f9f11f47 (diff)
downloadrust-cf3c385fef4d8bc071f51ecdb1004e73c7fe8a9b.tar.gz
rust-cf3c385fef4d8bc071f51ecdb1004e73c7fe8a9b.zip
Rollup merge of #54518 - petrochenkov:regr130, r=alexcrichton
resolve: Do not block derive helper resolutions on single import resolutions

Derive helpers currently conflict with anything else, so if some resolution from a single import appears later, it will result in error anyway.

Fixes https://github.com/rust-lang/rust/issues/54471 (stable-to-beta regression)

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/macros.rs20
-rw-r--r--src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs6
-rw-r--r--src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs10
-rw-r--r--src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs13
-rw-r--r--src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr20
-rw-r--r--src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs29
-rw-r--r--src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr13
7 files changed, 90 insertions, 21 deletions
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 35d96b9302b..89bc2f2709a 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -575,6 +575,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
         // 5. Standard library prelude (de-facto closed, controlled).
         // 6. Language prelude (closed, controlled).
         // (Macro NS)
+        // 0. Derive helpers (open, not controlled). All ambiguities with other names
+        //    are currently reported as errors. They should be higher in priority than preludes
+        //    and probably 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.
         // 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
         //    (open, not controlled).
         // 2. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
@@ -583,13 +590,6 @@ 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.
 
         assert!(ns == TypeNS  || ns == MacroNS);
         assert!(force || !record_used); // `record_used` implies `force`
@@ -621,7 +621,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
         }
 
         // Go through all the scopes and try to resolve the name.
-        let mut where_to_resolve = WhereToResolve::Module(parent_scope.module);
+        let mut where_to_resolve = WhereToResolve::DeriveHelpers;
         let mut use_prelude = !parent_scope.module.no_implicit_prelude;
         loop {
             let result = match where_to_resolve {
@@ -751,8 +751,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     }
                     WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
                     WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
-                    WhereToResolve::BuiltinAttrs => WhereToResolve::DeriveHelpers,
-                    WhereToResolve::DeriveHelpers => break, // nowhere else to search
+                    WhereToResolve::BuiltinAttrs => break, // nowhere else to search
+                    WhereToResolve::DeriveHelpers => WhereToResolve::Module(parent_scope.module),
                     WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
                     WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
                     WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes,
diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs
index 83bbb7c13c4..d0aed8b1624 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs
+++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs
@@ -11,13 +11,11 @@
 // aux-build:derive-b.rs
 // ignore-stage1
 
-#![allow(warnings)]
-
 #[macro_use]
 extern crate derive_b;
 
-#[B] //~ ERROR `B` is a derive mode
-#[C]
+#[B]
+#[C] //~ ERROR attribute `C` is currently unknown to the compiler
 #[B(D)]
 #[B(E = "foo")]
 #[B(arbitrary tokens)]
diff --git a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs b/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs
index 7be909c3c9e..124bc05b7a3 100644
--- a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs
+++ b/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs
@@ -25,3 +25,13 @@ pub fn derive_foo(input: TokenStream) -> TokenStream {
 pub fn derive_bar(input: TokenStream) -> TokenStream {
     panic!("lolnope");
 }
+
+#[proc_macro_derive(WithHelper, attributes(helper))]
+pub fn with_helper(input: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
+
+#[proc_macro_attribute]
+pub fn helper(_: TokenStream, input: TokenStream) -> TokenStream {
+    input
+}
diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs
new file mode 100644
index 00000000000..b750a8bb0d9
--- /dev/null
+++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs
@@ -0,0 +1,13 @@
+// aux-build:plugin.rs
+// ignore-stage1
+
+#[macro_use(WithHelper)]
+extern crate plugin;
+
+use plugin::helper;
+
+#[derive(WithHelper)]
+#[helper] //~ ERROR `helper` is ambiguous
+struct S;
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr
new file mode 100644
index 00000000000..059629c0b62
--- /dev/null
+++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr
@@ -0,0 +1,20 @@
+error[E0659]: `helper` is ambiguous
+  --> $DIR/helper-attr-blocked-by-import-ambig.rs:10:3
+   |
+LL | #[helper] //~ ERROR `helper` is ambiguous
+   |   ^^^^^^ ambiguous name
+   |
+note: `helper` could refer to the name defined here
+  --> $DIR/helper-attr-blocked-by-import-ambig.rs:9:10
+   |
+LL | #[derive(WithHelper)]
+   |          ^^^^^^^^^^
+note: `helper` could also refer to the name imported here
+  --> $DIR/helper-attr-blocked-by-import-ambig.rs:7:5
+   |
+LL | use plugin::helper;
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs
new file mode 100644
index 00000000000..03b774f6c64
--- /dev/null
+++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs
@@ -0,0 +1,29 @@
+// compile-pass
+// aux-build:plugin.rs
+// ignore-stage1
+
+#[macro_use(WithHelper)]
+extern crate plugin;
+
+use self::one::*;
+use self::two::*;
+
+mod helper {}
+
+mod one {
+    use helper;
+
+    #[derive(WithHelper)]
+    #[helper]
+    struct One;
+}
+
+mod two {
+    use helper;
+
+    #[derive(WithHelper)]
+    #[helper]
+    struct Two;
+}
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr
index cdfecb3d101..e0aeae4ba6c 100644
--- a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr
+++ b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr
@@ -4,17 +4,16 @@ error[E0659]: `my_attr` is ambiguous
 LL | #[my_attr] //~ ERROR `my_attr` is ambiguous
    |   ^^^^^^^ ambiguous name
    |
-note: `my_attr` could refer to the name imported here
-  --> $DIR/derive-helper-shadowing.rs:4:5
-   |
-LL | use derive_helper_shadowing::*;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `my_attr` could also refer to the name defined here
+note: `my_attr` could refer to the name defined here
   --> $DIR/derive-helper-shadowing.rs:7:10
    |
 LL | #[derive(MyTrait)]
    |          ^^^^^^^
-   = note: consider adding an explicit import of `my_attr` to disambiguate
+note: `my_attr` could also refer to the name imported here
+  --> $DIR/derive-helper-shadowing.rs:4:5
+   |
+LL | use derive_helper_shadowing::*;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error