Skip to content

Commit

Permalink
resolve: Do not block derive helper resolutions on single import reso…
Browse files Browse the repository at this point in the history
…lutions

Derive helpers conflict currently conflict with anything else, so if some resolution from a single import appears later, it will result in error anyway
  • Loading branch information
petrochenkov committed Sep 25, 2018
1 parent 31789a6 commit ee05f6e
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 21 deletions.
20 changes: 10 additions & 10 deletions src/librustc_resolve/macros.rs
Expand Up @@ -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).
Expand All @@ -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`
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
Expand Up @@ -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)]
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs
Expand Up @@ -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
}
@@ -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() {}
@@ -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`.
@@ -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() {}
13 changes: 6 additions & 7 deletions src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr
Expand Up @@ -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

Expand Down

0 comments on commit ee05f6e

Please sign in to comment.