Skip to content

Commit f74fe81

Browse files
committed
resolve: Give derive helpers highest priority during resolution
1 parent a0d40f8 commit f74fe81

File tree

5 files changed

+47
-48
lines changed

5 files changed

+47
-48
lines changed

src/librustc_resolve/macros.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -466,11 +466,12 @@ impl<'a> Resolver<'a> {
466466
) -> Result<&'a NameBinding<'a>, Determinacy> {
467467
bitflags::bitflags! {
468468
struct Flags: u8 {
469-
const MACRO_RULES = 1 << 0;
470-
const MODULE = 1 << 1;
471-
const MISC_SUGGEST_CRATE = 1 << 2;
472-
const MISC_SUGGEST_SELF = 1 << 3;
473-
const MISC_FROM_PRELUDE = 1 << 4;
469+
const MACRO_RULES = 1 << 0;
470+
const MODULE = 1 << 1;
471+
const DERIVE_HELPER_COMPAT = 1 << 2;
472+
const MISC_SUGGEST_CRATE = 1 << 3;
473+
const MISC_SUGGEST_SELF = 1 << 4;
474+
const MISC_FROM_PRELUDE = 1 << 5;
474475
}
475476
}
476477

@@ -528,8 +529,10 @@ impl<'a> Resolver<'a> {
528529
match this.resolve_macro_path(derive, Some(MacroKind::Derive),
529530
parent_scope, true, force) {
530531
Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) {
531-
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
532-
result = ok(res, derive.span, this.arenas);
532+
let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
533+
ty::Visibility::Public, derive.span, ExpnId::root())
534+
.to_name_binding(this.arenas);
535+
result = Ok((binding, Flags::DERIVE_HELPER_COMPAT));
533536
break;
534537
}
535538
Ok(_) | Err(Determinacy::Determined) => {}
@@ -659,13 +662,17 @@ impl<'a> Resolver<'a> {
659662
let (res, innermost_res) = (binding.res(), innermost_binding.res());
660663
if res != innermost_res {
661664
let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
662-
let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
665+
let is_derive_helper_compat = |res, flags: Flags| {
666+
res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper) &&
667+
flags.contains(Flags::DERIVE_HELPER_COMPAT)
668+
};
663669

664670
let ambiguity_error_kind = if is_import {
665671
Some(AmbiguityKind::Import)
666672
} else if innermost_res == builtin || res == builtin {
667673
Some(AmbiguityKind::BuiltinAttr)
668-
} else if innermost_res == derive_helper || res == derive_helper {
674+
} else if is_derive_helper_compat(innermost_res, innermost_flags) ||
675+
is_derive_helper_compat(res, flags) {
669676
Some(AmbiguityKind::DeriveHelper)
670677
} else if innermost_flags.contains(Flags::MACRO_RULES) &&
671678
flags.contains(Flags::MODULE) &&
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
6+
extern crate proc_macro;
7+
use proc_macro::*;
8+
9+
#[proc_macro_derive(same_name, attributes(same_name))]
10+
pub fn derive_a(_: TokenStream) -> TokenStream {
11+
TokenStream::new()
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// If a derive macro introduces a helper attribute with the same name as that macro,
2+
// then make sure that it's usable without ambiguities.
3+
4+
// check-pass
5+
// aux-build:derive-helper-shadowing-2.rs
6+
7+
#[macro_use]
8+
extern crate derive_helper_shadowing_2;
9+
10+
#[derive(same_name)]
11+
struct S {
12+
#[same_name] // OK, no ambiguity, derive helpers have highest priority
13+
field: u8,
14+
}
15+
16+
fn main() {}

src/test/ui/proc-macro/derive-helper-shadowing.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ macro_rules! gen_helper_use {
1919
#[empty_helper] //~ ERROR `empty_helper` is ambiguous
2020
#[derive(Empty)]
2121
struct S {
22-
#[empty_helper] //~ ERROR `empty_helper` is ambiguous
22+
#[empty_helper] // OK, no ambiguity, derive helpers have highest priority
2323
field: [u8; {
2424
use empty_helper; //~ ERROR `empty_helper` is ambiguous
2525

26-
#[empty_helper] //~ ERROR `empty_helper` is ambiguous
26+
#[empty_helper] // OK, no ambiguity, derive helpers have highest priority
2727
struct U;
2828

2929
mod inner {

src/test/ui/proc-macro/derive-helper-shadowing.stderr

+1-37
Original file line numberDiff line numberDiff line change
@@ -61,42 +61,6 @@ LL | use test_macros::empty_attr as empty_helper;
6161
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6262
= help: use `crate::empty_helper` to refer to this attribute macro unambiguously
6363

64-
error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
65-
--> $DIR/derive-helper-shadowing.rs:22:7
66-
|
67-
LL | #[empty_helper]
68-
| ^^^^^^^^^^^^ ambiguous name
69-
|
70-
note: `empty_helper` could refer to the derive helper attribute defined here
71-
--> $DIR/derive-helper-shadowing.rs:20:10
72-
|
73-
LL | #[derive(Empty)]
74-
| ^^^^^
75-
note: `empty_helper` could also refer to the attribute macro imported here
76-
--> $DIR/derive-helper-shadowing.rs:10:5
77-
|
78-
LL | use test_macros::empty_attr as empty_helper;
79-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
80-
= help: use `crate::empty_helper` to refer to this attribute macro unambiguously
81-
82-
error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
83-
--> $DIR/derive-helper-shadowing.rs:26:11
84-
|
85-
LL | #[empty_helper]
86-
| ^^^^^^^^^^^^ ambiguous name
87-
|
88-
note: `empty_helper` could refer to the derive helper attribute defined here
89-
--> $DIR/derive-helper-shadowing.rs:20:10
90-
|
91-
LL | #[derive(Empty)]
92-
| ^^^^^
93-
note: `empty_helper` could also refer to the attribute macro imported here
94-
--> $DIR/derive-helper-shadowing.rs:10:5
95-
|
96-
LL | use test_macros::empty_attr as empty_helper;
97-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
98-
= help: use `crate::empty_helper` to refer to this attribute macro unambiguously
99-
100-
error: aborting due to 7 previous errors
64+
error: aborting due to 5 previous errors
10165

10266
For more information about this error, try `rustc --explain E0659`.

0 commit comments

Comments
 (0)