Rollup merge of #66529 - petrochenkov:reshelp2, r=davidtwco
resolve: Give derive helpers highest priority during resolution So they just shadow everything else and don't create ambiguity errors. This matches the old pre-#64694 behavior most closely. --- The change doesn't apply to this "compatibility" case ```rust #[trait_helper] // The helper attribute is used before it introduced. // Sadly, compiles on stable, supported via hacks. // I plan to make a compatibility warning for this. #[derive(Trait)] struct S; ``` , such attributes still create ambiguities, but #64694 didn't change anything for this case. Fixes https://github.com/rust-lang/rust/issues/66508 Fixes https://github.com/rust-lang/rust/issues/66525
This commit is contained in:
commit
1f0f0adbf4
@ -466,11 +466,12 @@ pub fn resolve_macro_path(
|
||||
) -> 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 @@ struct Flags: u8 {
|
||||
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 @@ struct Flags: u8 {
|
||||
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) &&
|
||||
|
@ -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()
|
||||
}
|
16
src/test/ui/proc-macro/derive-helper-shadowing-2.rs
Normal file
16
src/test/ui/proc-macro/derive-helper-shadowing-2.rs
Normal file
@ -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() {}
|
@ -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 {
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user