Skip to content

Commit 8085228

Browse files
committed
expand: Stop marking derive helper attributes as known
Pass them through name resolution instead
1 parent a3126a5 commit 8085228

File tree

5 files changed

+49
-41
lines changed

5 files changed

+49
-41
lines changed

src/librustc_resolve/macros.rs

+3
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ impl<'a> base::Resolver for Resolver<'a> {
247247
helper_attrs.extend(
248248
ext.helper_attrs.iter().map(|name| Ident::new(*name, span))
249249
);
250+
if ext.is_derive_copy {
251+
self.add_derive_copy(invoc_id);
252+
}
250253
ext
251254
}
252255
Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive),

src/libsyntax_expand/expand.rs

+4-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::base::*;
2-
use crate::proc_macro::{collect_derives, MarkAttrs};
2+
use crate::proc_macro::collect_derives;
33
use crate::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind};
44
use crate::mbe::macro_rules::annotate_err_with_kind;
55
use crate::placeholders::{placeholder, PlaceholderExpander};
@@ -394,7 +394,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
394394
let fragment = self.expand_invoc(invoc, &ext.kind);
395395
self.collect_invocations(fragment, &[])
396396
}
397-
InvocationRes::DeriveContainer(exts) => {
397+
InvocationRes::DeriveContainer(_exts) => {
398+
// FIXME: Consider using the derive resolutions (`_exts`) immediately,
399+
// instead of enqueuing the derives to be resolved again later.
398400
let (derives, item) = match invoc.kind {
399401
InvocationKind::DeriveContainer { derives, item } => (derives, item),
400402
_ => unreachable!(),
@@ -421,20 +423,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
421423

422424
let mut item = self.fully_configure(item);
423425
item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
424-
let mut helper_attrs = Vec::new();
425-
let mut has_copy = false;
426-
for ext in exts {
427-
helper_attrs.extend(&ext.helper_attrs);
428-
has_copy |= ext.is_derive_copy;
429-
}
430-
// Mark derive helpers inside this item as known and used.
431-
// FIXME: This is a hack, derive helpers should be integrated with regular name
432-
// resolution instead. For example, helpers introduced by a derive container
433-
// can be in scope for all code produced by that container's expansion.
434-
item.visit_with(&mut MarkAttrs(&helper_attrs));
435-
if has_copy {
436-
self.cx.resolver.add_derive_copy(invoc.expansion_data.id);
437-
}
438426

439427
let mut derive_placeholders = Vec::with_capacity(derives.len());
440428
invocations.reserve(derives.len());

src/libsyntax_expand/proc_macro.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
use crate::base::{self, *};
22
use crate::proc_macro_server;
33

4-
use syntax::ast::{self, ItemKind, Attribute, Mac};
5-
use syntax::attr::{mark_used, mark_known};
4+
use syntax::ast::{self, ItemKind};
65
use syntax::errors::{Applicability, FatalError};
76
use syntax::symbol::sym;
87
use syntax::token;
98
use syntax::tokenstream::{self, TokenStream};
10-
use syntax::visit::Visitor;
119

1210
use rustc_data_structures::sync::Lrc;
1311
use syntax_pos::{Span, DUMMY_SP};
@@ -167,21 +165,6 @@ impl MultiItemModifier for ProcMacroDerive {
167165
}
168166
}
169167

170-
crate struct MarkAttrs<'a>(crate &'a [ast::Name]);
171-
172-
impl<'a> Visitor<'a> for MarkAttrs<'a> {
173-
fn visit_attribute(&mut self, attr: &Attribute) {
174-
if let Some(ident) = attr.ident() {
175-
if self.0.contains(&ident.name) {
176-
mark_used(attr);
177-
mark_known(attr);
178-
}
179-
}
180-
}
181-
182-
fn visit_mac(&mut self, _mac: &Mac) {}
183-
}
184-
185168
crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
186169
let mut result = Vec::new();
187170
attrs.retain(|attr| {

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@ use test_macros::empty_attr as empty_helper;
99
#[empty_helper] //~ ERROR `empty_helper` is ambiguous
1010
#[derive(Empty)]
1111
struct S {
12-
// FIXME No ambiguity, attributes in non-macro positions are not resolved properly
13-
#[empty_helper]
12+
#[empty_helper] //~ ERROR `empty_helper` is ambiguous
1413
field: [u8; {
1514
use empty_helper; //~ ERROR `empty_helper` is ambiguous
1615

17-
// FIXME No ambiguity, derive helpers are not put into scope for inner items
18-
#[empty_helper]
16+
#[empty_helper] //~ ERROR `empty_helper` is ambiguous
1917
struct U;
2018

2119
mod inner {
22-
// FIXME No ambiguity, attributes in non-macro positions are not resolved properly
20+
// OK, no ambiguity, the non-helper attribute is not in scope here, only the helper.
2321
#[empty_helper]
2422
struct V;
2523
}

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

+38-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0659]: `empty_helper` is ambiguous (name vs any other name during import resolution)
2-
--> $DIR/derive-helper-shadowing.rs:15:13
2+
--> $DIR/derive-helper-shadowing.rs:14:13
33
|
44
LL | use empty_helper;
55
| ^^^^^^^^^^^^ ambiguous name
@@ -34,6 +34,42 @@ LL | use test_macros::empty_attr as empty_helper;
3434
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3535
= help: use `crate::empty_helper` to refer to this attribute macro unambiguously
3636

37-
error: aborting due to 2 previous errors
37+
error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
38+
--> $DIR/derive-helper-shadowing.rs:12:7
39+
|
40+
LL | #[empty_helper]
41+
| ^^^^^^^^^^^^ ambiguous name
42+
|
43+
note: `empty_helper` could refer to the derive helper attribute defined here
44+
--> $DIR/derive-helper-shadowing.rs:10:10
45+
|
46+
LL | #[derive(Empty)]
47+
| ^^^^^
48+
note: `empty_helper` could also refer to the attribute macro imported here
49+
--> $DIR/derive-helper-shadowing.rs:7:5
50+
|
51+
LL | use test_macros::empty_attr as empty_helper;
52+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
= help: use `crate::empty_helper` to refer to this attribute macro unambiguously
54+
55+
error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
56+
--> $DIR/derive-helper-shadowing.rs:16:11
57+
|
58+
LL | #[empty_helper]
59+
| ^^^^^^^^^^^^ ambiguous name
60+
|
61+
note: `empty_helper` could refer to the derive helper attribute defined here
62+
--> $DIR/derive-helper-shadowing.rs:10:10
63+
|
64+
LL | #[derive(Empty)]
65+
| ^^^^^
66+
note: `empty_helper` could also refer to the attribute macro imported here
67+
--> $DIR/derive-helper-shadowing.rs:7:5
68+
|
69+
LL | use test_macros::empty_attr as empty_helper;
70+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
71+
= help: use `crate::empty_helper` to refer to this attribute macro unambiguously
72+
73+
error: aborting due to 4 previous errors
3874

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

0 commit comments

Comments
 (0)