Skip to content

Commit 3041ec6

Browse files
committed
resolve/expand: Catch macro kind mismatches early in resolve
This way we are processing all of them in a single point, rather than separately for each syntax extension kind. Also, the standard expected/found wording is used.
1 parent f16993d commit 3041ec6

File tree

10 files changed

+106
-68
lines changed

10 files changed

+106
-68
lines changed

src/librustc_resolve/macros.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,18 @@ impl<'a> Resolver<'a> {
348348
_ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
349349
};
350350

351-
Ok((res, self.get_macro(res)))
351+
let ext = self.get_macro(res);
352+
Ok(if ext.macro_kind() != kind {
353+
let expected = if kind == MacroKind::Attr { "attribute" } else { kind.descr() };
354+
let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path);
355+
self.session.struct_span_err(path.span, &msg)
356+
.span_label(path.span, format!("not {} {}", kind.article(), expected))
357+
.emit();
358+
// Return dummy syntax extensions for unexpected macro kinds for better recovery.
359+
(Res::Err, self.dummy_ext(kind))
360+
} else {
361+
(res, ext)
362+
})
352363
}
353364

354365
fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) {

src/libsyntax/ext/expand.rs

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
323323
progress = true;
324324
let ExpansionData { depth, mark, .. } = invoc.expansion_data;
325325
self.cx.current_expansion = invoc.expansion_data.clone();
326-
327326
self.cx.current_expansion.mark = scope;
327+
328328
// FIXME(jseyfried): Refactor out the following logic
329329
let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
330330
let (invoc_fragment_kind, invoc_span) = (invoc.fragment_kind, invoc.span());
331-
let fragment = self.expand_invoc(invoc, &*ext).unwrap_or_else(|| {
331+
let fragment = self.expand_invoc(invoc, &ext).unwrap_or_else(|| {
332332
invoc_fragment_kind.dummy(invoc_span).unwrap()
333333
});
334334
self.collect_invocations(fragment, &[])
@@ -551,17 +551,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
551551
self.gate_proc_macro_expansion(attr.span, &res);
552552
res
553553
}
554-
SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
555-
self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path));
556-
self.cx.trace_macros_diag();
557-
invoc.fragment_kind.dummy(attr.span)
558-
}
559-
_ => {
560-
let msg = &format!("macro `{}` may not be used in attributes", attr.path);
561-
self.cx.span_err(attr.span, msg);
562-
self.cx.trace_macros_diag();
563-
invoc.fragment_kind.dummy(attr.span)
564-
}
554+
_ => unreachable!()
565555
}
566556
}
567557

@@ -671,21 +661,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
671661
let tok_result = expander.expand(self.cx, span, mac.node.stream());
672662
kind.make_from(tok_result)
673663
}
674-
675-
SyntaxExtensionKind::Attr(..) |
676-
SyntaxExtensionKind::LegacyAttr(..) |
677-
SyntaxExtensionKind::NonMacroAttr { .. } => {
678-
self.cx.span_err(path.span,
679-
&format!("`{}` can only be used in attributes", path));
680-
self.cx.trace_macros_diag();
681-
kind.dummy(span)
682-
}
683-
684-
SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
685-
self.cx.span_err(path.span, &format!("`{}` is a derive macro", path));
686-
self.cx.trace_macros_diag();
687-
kind.dummy(span)
688-
}
664+
_ => unreachable!()
689665
};
690666

691667
if opt_expanded.is_some() {
@@ -747,12 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
747723
let items = expander.expand(self.cx, span, &meta, item);
748724
Some(invoc.fragment_kind.expect_from_annotatables(items))
749725
}
750-
_ => {
751-
let msg = &format!("macro `{}` may not be used for derive attributes", path);
752-
self.cx.span_err(path.span, msg);
753-
self.cx.trace_macros_diag();
754-
invoc.fragment_kind.dummy(path.span)
755-
}
726+
_ => unreachable!()
756727
}
757728
}
758729

src/test/ui/feature-gates/feature-gate-rustc-attrs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ mod unknown { pub macro rustc() {} }
77

88
#[rustc::unknown]
99
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
10-
//~| ERROR macro `rustc::unknown` may not be used in attributes
10+
//~| ERROR expected attribute, found macro `rustc::unknown`
1111
fn f() {}
1212

1313
#[unknown::rustc]
1414
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
15-
//~| ERROR macro `unknown::rustc` may not be used in attributes
15+
//~| ERROR expected attribute, found macro `unknown::rustc`
1616
fn g() {}
1717

1818
#[rustc_dummy]

src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ LL | #[rustc::unknown]
77
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
88
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
99

10-
error: macro `rustc::unknown` may not be used in attributes
11-
--> $DIR/feature-gate-rustc-attrs.rs:8:1
10+
error: expected attribute, found macro `rustc::unknown`
11+
--> $DIR/feature-gate-rustc-attrs.rs:8:3
1212
|
1313
LL | #[rustc::unknown]
14-
| ^^^^^^^^^^^^^^^^^
14+
| ^^^^^^^^^^^^^^ not an attribute
1515

1616
error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
1717
--> $DIR/feature-gate-rustc-attrs.rs:13:12
@@ -22,11 +22,11 @@ LL | #[unknown::rustc]
2222
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
2323
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
2424

25-
error: macro `unknown::rustc` may not be used in attributes
26-
--> $DIR/feature-gate-rustc-attrs.rs:13:1
25+
error: expected attribute, found macro `unknown::rustc`
26+
--> $DIR/feature-gate-rustc-attrs.rs:13:3
2727
|
2828
LL | #[unknown::rustc]
29-
| ^^^^^^^^^^^^^^^^^
29+
| ^^^^^^^^^^^^^^ not an attribute
3030

3131
error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
3232
--> $DIR/feature-gate-rustc-attrs.rs:20:3
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[derive(inline)] //~ ERROR macro `inline` may not be used for derive attributes
1+
#[derive(inline)] //~ ERROR expected derive macro, found built-in attribute `inline`
22
struct S;
33

44
fn main() {}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: macro `inline` may not be used for derive attributes
1+
error: expected derive macro, found built-in attribute `inline`
22
--> $DIR/macro-path-prelude-fail-4.rs:1:10
33
|
44
LL | #[derive(inline)]
5-
| ^^^^^^
5+
| ^^^^^^ not a derive macro
66

77
error: aborting due to previous error
88

src/test/ui/proc-macro/macro-namespace-reserved-2.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,31 @@ fn check_bang1() {
2626
}
2727
fn check_bang2() {
2828
my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr!` in this scope
29+
crate::my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines
30+
//~| ERROR expected macro, found attribute macro `crate::my_macro_attr`
2931
}
3032
fn check_bang3() {
3133
MyTrait!(); //~ ERROR cannot find macro `MyTrait!` in this scope
34+
crate::MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it
35+
//~| ERROR expected macro, found derive macro `crate::MyTrait`
3236
}
3337

3438
#[my_macro] //~ ERROR attribute `my_macro` is currently unknown
39+
#[crate::my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it
40+
//~| ERROR expected attribute, found macro `crate::my_macro`
3541
fn check_attr1() {}
3642
#[my_macro_attr] //~ ERROR can't use a procedural macro from the same crate that defines it
3743
fn check_attr2() {}
3844
#[MyTrait] //~ ERROR can't use a procedural macro from the same crate that defines it
39-
//~| ERROR `MyTrait` is a derive macro
45+
//~| ERROR expected attribute, found derive macro `MyTrait`
4046
fn check_attr3() {}
4147

4248
#[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` in this scope
49+
#[derive(crate::my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines
50+
//~| ERROR expected derive macro, found macro `crate::my_macro`
4351
struct CheckDerive1;
4452
#[derive(my_macro_attr)] //~ ERROR can't use a procedural macro from the same crate that defines it
45-
//~| ERROR macro `my_macro_attr` may not be used for derive attributes
53+
//~| ERROR expected derive macro, found attribute macro `my_macro_attr`
4654
struct CheckDerive2;
4755
#[derive(MyTrait)] //~ ERROR can't use a procedural macro from the same crate that defines it
4856
struct CheckDerive3;

src/test/ui/proc-macro/macro-namespace-reserved-2.stderr

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,100 @@ LL | my_macro!();
55
| ^^^^^^^^
66

77
error: can't use a procedural macro from the same crate that defines it
8-
--> $DIR/macro-namespace-reserved-2.rs:36:3
8+
--> $DIR/macro-namespace-reserved-2.rs:29:5
9+
|
10+
LL | crate::my_macro_attr!();
11+
| ^^^^^^^^^^^^^^^^^^^^
12+
13+
error: expected macro, found attribute macro `crate::my_macro_attr`
14+
--> $DIR/macro-namespace-reserved-2.rs:29:5
15+
|
16+
LL | crate::my_macro_attr!();
17+
| ^^^^^^^^^^^^^^^^^^^^ not a macro
18+
19+
error: can't use a procedural macro from the same crate that defines it
20+
--> $DIR/macro-namespace-reserved-2.rs:34:5
21+
|
22+
LL | crate::MyTrait!();
23+
| ^^^^^^^^^^^^^^
24+
25+
error: expected macro, found derive macro `crate::MyTrait`
26+
--> $DIR/macro-namespace-reserved-2.rs:34:5
27+
|
28+
LL | crate::MyTrait!();
29+
| ^^^^^^^^^^^^^^ not a macro
30+
31+
error: can't use a procedural macro from the same crate that defines it
32+
--> $DIR/macro-namespace-reserved-2.rs:42:3
933
|
1034
LL | #[my_macro_attr]
1135
| ^^^^^^^^^^^^^
1236

1337
error: can't use a procedural macro from the same crate that defines it
14-
--> $DIR/macro-namespace-reserved-2.rs:38:3
38+
--> $DIR/macro-namespace-reserved-2.rs:44:3
1539
|
1640
LL | #[MyTrait]
1741
| ^^^^^^^
1842

19-
error: `MyTrait` is a derive macro
20-
--> $DIR/macro-namespace-reserved-2.rs:38:1
43+
error: expected attribute, found derive macro `MyTrait`
44+
--> $DIR/macro-namespace-reserved-2.rs:44:3
2145
|
2246
LL | #[MyTrait]
23-
| ^^^^^^^^^^
47+
| ^^^^^^^ not an attribute
2448

2549
error: can't use a procedural macro from the same crate that defines it
26-
--> $DIR/macro-namespace-reserved-2.rs:44:10
50+
--> $DIR/macro-namespace-reserved-2.rs:49:10
51+
|
52+
LL | #[derive(crate::my_macro)]
53+
| ^^^^^^^^^^^^^^^
54+
55+
error: expected derive macro, found macro `crate::my_macro`
56+
--> $DIR/macro-namespace-reserved-2.rs:49:10
57+
|
58+
LL | #[derive(crate::my_macro)]
59+
| ^^^^^^^^^^^^^^^ not a derive macro
60+
61+
error: can't use a procedural macro from the same crate that defines it
62+
--> $DIR/macro-namespace-reserved-2.rs:52:10
2763
|
2864
LL | #[derive(my_macro_attr)]
2965
| ^^^^^^^^^^^^^
3066

31-
error: macro `my_macro_attr` may not be used for derive attributes
32-
--> $DIR/macro-namespace-reserved-2.rs:44:10
67+
error: expected derive macro, found attribute macro `my_macro_attr`
68+
--> $DIR/macro-namespace-reserved-2.rs:52:10
3369
|
3470
LL | #[derive(my_macro_attr)]
35-
| ^^^^^^^^^^^^^
71+
| ^^^^^^^^^^^^^ not a derive macro
3672

3773
error: can't use a procedural macro from the same crate that defines it
38-
--> $DIR/macro-namespace-reserved-2.rs:47:10
74+
--> $DIR/macro-namespace-reserved-2.rs:55:10
3975
|
4076
LL | #[derive(MyTrait)]
4177
| ^^^^^^^
4278

4379
error[E0658]: The attribute `my_macro` is currently unknown to the compiler and may have meaning added to it in the future
44-
--> $DIR/macro-namespace-reserved-2.rs:34:3
80+
--> $DIR/macro-namespace-reserved-2.rs:38:3
4581
|
4682
LL | #[my_macro]
4783
| ^^^^^^^^
4884
|
4985
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
5086
= help: add #![feature(custom_attribute)] to the crate attributes to enable
5187

88+
error: can't use a procedural macro from the same crate that defines it
89+
--> $DIR/macro-namespace-reserved-2.rs:39:3
90+
|
91+
LL | #[crate::my_macro]
92+
| ^^^^^^^^^^^^^^^
93+
94+
error: expected attribute, found macro `crate::my_macro`
95+
--> $DIR/macro-namespace-reserved-2.rs:39:3
96+
|
97+
LL | #[crate::my_macro]
98+
| ^^^^^^^^^^^^^^^ not an attribute
99+
52100
error: cannot find derive macro `my_macro` in this scope
53-
--> $DIR/macro-namespace-reserved-2.rs:42:10
101+
--> $DIR/macro-namespace-reserved-2.rs:48:10
54102
|
55103
LL | #[derive(my_macro)]
56104
| ^^^^^^^^
@@ -62,11 +110,11 @@ LL | my_macro_attr!();
62110
| ^^^^^^^^^^^^^
63111

64112
error: cannot find macro `MyTrait!` in this scope
65-
--> $DIR/macro-namespace-reserved-2.rs:31:5
113+
--> $DIR/macro-namespace-reserved-2.rs:33:5
66114
|
67115
LL | MyTrait!();
68116
| ^^^^^^^
69117

70-
error: aborting due to 11 previous errors
118+
error: aborting due to 19 previous errors
71119

72120
For more information about this error, try `rustc --explain E0658`.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#[derive(rustfmt::skip)] //~ ERROR macro `rustfmt::skip` may not be used for derive attributes
1+
#[derive(rustfmt::skip)] //~ ERROR expected derive macro, found tool attribute `rustfmt::skip`
22
struct S;
33

44
fn main() {
5-
rustfmt::skip!(); //~ ERROR `rustfmt::skip` can only be used in attributes
5+
rustfmt::skip!(); //~ ERROR expected macro, found tool attribute `rustfmt::skip`
66
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error: macro `rustfmt::skip` may not be used for derive attributes
1+
error: expected derive macro, found tool attribute `rustfmt::skip`
22
--> $DIR/tool-attributes-misplaced-2.rs:1:10
33
|
44
LL | #[derive(rustfmt::skip)]
5-
| ^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^ not a derive macro
66

7-
error: `rustfmt::skip` can only be used in attributes
7+
error: expected macro, found tool attribute `rustfmt::skip`
88
--> $DIR/tool-attributes-misplaced-2.rs:5:5
99
|
1010
LL | rustfmt::skip!();
11-
| ^^^^^^^^^^^^^
11+
| ^^^^^^^^^^^^^ not a macro
1212

1313
error: aborting due to 2 previous errors
1414

0 commit comments

Comments
 (0)