resolve: Do not block derive helper resolutions on single import resolutions
Derive helpers conflict currently conflict with anything else, so if some resolution from a single import appears later, it will result in error anyway
This commit is contained in:
parent
31789a658b
commit
ee05f6eef4
7 changed files with 90 additions and 21 deletions
|
@ -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,
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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() {}
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue