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.
This commit is contained in:
parent
f16993d4ac
commit
3041ec6118
10 changed files with 106 additions and 68 deletions
|
@ -348,7 +348,18 @@ impl<'a> Resolver<'a> {
|
|||
_ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
|
||||
};
|
||||
|
||||
Ok((res, self.get_macro(res)))
|
||||
let ext = self.get_macro(res);
|
||||
Ok(if ext.macro_kind() != kind {
|
||||
let expected = if kind == MacroKind::Attr { "attribute" } else { kind.descr() };
|
||||
let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path);
|
||||
self.session.struct_span_err(path.span, &msg)
|
||||
.span_label(path.span, format!("not {} {}", kind.article(), expected))
|
||||
.emit();
|
||||
// Return dummy syntax extensions for unexpected macro kinds for better recovery.
|
||||
(Res::Err, self.dummy_ext(kind))
|
||||
} else {
|
||||
(res, ext)
|
||||
})
|
||||
}
|
||||
|
||||
fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) {
|
||||
|
|
|
@ -323,12 +323,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
progress = true;
|
||||
let ExpansionData { depth, mark, .. } = invoc.expansion_data;
|
||||
self.cx.current_expansion = invoc.expansion_data.clone();
|
||||
|
||||
self.cx.current_expansion.mark = scope;
|
||||
|
||||
// FIXME(jseyfried): Refactor out the following logic
|
||||
let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
|
||||
let (invoc_fragment_kind, invoc_span) = (invoc.fragment_kind, invoc.span());
|
||||
let fragment = self.expand_invoc(invoc, &*ext).unwrap_or_else(|| {
|
||||
let fragment = self.expand_invoc(invoc, &ext).unwrap_or_else(|| {
|
||||
invoc_fragment_kind.dummy(invoc_span).unwrap()
|
||||
});
|
||||
self.collect_invocations(fragment, &[])
|
||||
|
@ -551,17 +551,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
self.gate_proc_macro_expansion(attr.span, &res);
|
||||
res
|
||||
}
|
||||
SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
|
||||
self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path));
|
||||
self.cx.trace_macros_diag();
|
||||
invoc.fragment_kind.dummy(attr.span)
|
||||
}
|
||||
_ => {
|
||||
let msg = &format!("macro `{}` may not be used in attributes", attr.path);
|
||||
self.cx.span_err(attr.span, msg);
|
||||
self.cx.trace_macros_diag();
|
||||
invoc.fragment_kind.dummy(attr.span)
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -671,21 +661,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
let tok_result = expander.expand(self.cx, span, mac.node.stream());
|
||||
kind.make_from(tok_result)
|
||||
}
|
||||
|
||||
SyntaxExtensionKind::Attr(..) |
|
||||
SyntaxExtensionKind::LegacyAttr(..) |
|
||||
SyntaxExtensionKind::NonMacroAttr { .. } => {
|
||||
self.cx.span_err(path.span,
|
||||
&format!("`{}` can only be used in attributes", path));
|
||||
self.cx.trace_macros_diag();
|
||||
kind.dummy(span)
|
||||
}
|
||||
|
||||
SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
|
||||
self.cx.span_err(path.span, &format!("`{}` is a derive macro", path));
|
||||
self.cx.trace_macros_diag();
|
||||
kind.dummy(span)
|
||||
}
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
if opt_expanded.is_some() {
|
||||
|
@ -747,12 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
let items = expander.expand(self.cx, span, &meta, item);
|
||||
Some(invoc.fragment_kind.expect_from_annotatables(items))
|
||||
}
|
||||
_ => {
|
||||
let msg = &format!("macro `{}` may not be used for derive attributes", path);
|
||||
self.cx.span_err(path.span, msg);
|
||||
self.cx.trace_macros_diag();
|
||||
invoc.fragment_kind.dummy(path.span)
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ mod unknown { pub macro rustc() {} }
|
|||
|
||||
#[rustc::unknown]
|
||||
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
|
||||
//~| ERROR macro `rustc::unknown` may not be used in attributes
|
||||
//~| ERROR expected attribute, found macro `rustc::unknown`
|
||||
fn f() {}
|
||||
|
||||
#[unknown::rustc]
|
||||
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
|
||||
//~| ERROR macro `unknown::rustc` may not be used in attributes
|
||||
//~| ERROR expected attribute, found macro `unknown::rustc`
|
||||
fn g() {}
|
||||
|
||||
#[rustc_dummy]
|
||||
|
|
|
@ -7,11 +7,11 @@ LL | #[rustc::unknown]
|
|||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
|
||||
|
||||
error: macro `rustc::unknown` may not be used in attributes
|
||||
--> $DIR/feature-gate-rustc-attrs.rs:8:1
|
||||
error: expected attribute, found macro `rustc::unknown`
|
||||
--> $DIR/feature-gate-rustc-attrs.rs:8:3
|
||||
|
|
||||
LL | #[rustc::unknown]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^ not an attribute
|
||||
|
||||
error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
|
||||
--> $DIR/feature-gate-rustc-attrs.rs:13:12
|
||||
|
@ -22,11 +22,11 @@ LL | #[unknown::rustc]
|
|||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
|
||||
|
||||
error: macro `unknown::rustc` may not be used in attributes
|
||||
--> $DIR/feature-gate-rustc-attrs.rs:13:1
|
||||
error: expected attribute, found macro `unknown::rustc`
|
||||
--> $DIR/feature-gate-rustc-attrs.rs:13:3
|
||||
|
|
||||
LL | #[unknown::rustc]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^ not an attribute
|
||||
|
||||
error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
|
||||
--> $DIR/feature-gate-rustc-attrs.rs:20:3
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[derive(inline)] //~ ERROR macro `inline` may not be used for derive attributes
|
||||
#[derive(inline)] //~ ERROR expected derive macro, found built-in attribute `inline`
|
||||
struct S;
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error: macro `inline` may not be used for derive attributes
|
||||
error: expected derive macro, found built-in attribute `inline`
|
||||
--> $DIR/macro-path-prelude-fail-4.rs:1:10
|
||||
|
|
||||
LL | #[derive(inline)]
|
||||
| ^^^^^^
|
||||
| ^^^^^^ not a derive macro
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -26,23 +26,31 @@ fn check_bang1() {
|
|||
}
|
||||
fn check_bang2() {
|
||||
my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr!` in this scope
|
||||
crate::my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines
|
||||
//~| ERROR expected macro, found attribute macro `crate::my_macro_attr`
|
||||
}
|
||||
fn check_bang3() {
|
||||
MyTrait!(); //~ ERROR cannot find macro `MyTrait!` in this scope
|
||||
crate::MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it
|
||||
//~| ERROR expected macro, found derive macro `crate::MyTrait`
|
||||
}
|
||||
|
||||
#[my_macro] //~ ERROR attribute `my_macro` is currently unknown
|
||||
#[crate::my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it
|
||||
//~| ERROR expected attribute, found macro `crate::my_macro`
|
||||
fn check_attr1() {}
|
||||
#[my_macro_attr] //~ ERROR can't use a procedural macro from the same crate that defines it
|
||||
fn check_attr2() {}
|
||||
#[MyTrait] //~ ERROR can't use a procedural macro from the same crate that defines it
|
||||
//~| ERROR `MyTrait` is a derive macro
|
||||
//~| ERROR expected attribute, found derive macro `MyTrait`
|
||||
fn check_attr3() {}
|
||||
|
||||
#[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` in this scope
|
||||
#[derive(crate::my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines
|
||||
//~| ERROR expected derive macro, found macro `crate::my_macro`
|
||||
struct CheckDerive1;
|
||||
#[derive(my_macro_attr)] //~ ERROR can't use a procedural macro from the same crate that defines it
|
||||
//~| ERROR macro `my_macro_attr` may not be used for derive attributes
|
||||
//~| ERROR expected derive macro, found attribute macro `my_macro_attr`
|
||||
struct CheckDerive2;
|
||||
#[derive(MyTrait)] //~ ERROR can't use a procedural macro from the same crate that defines it
|
||||
struct CheckDerive3;
|
||||
|
|
|
@ -5,43 +5,79 @@ LL | my_macro!();
|
|||
| ^^^^^^^^
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:36:3
|
||||
--> $DIR/macro-namespace-reserved-2.rs:29:5
|
||||
|
|
||||
LL | crate::my_macro_attr!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected macro, found attribute macro `crate::my_macro_attr`
|
||||
--> $DIR/macro-namespace-reserved-2.rs:29:5
|
||||
|
|
||||
LL | crate::my_macro_attr!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ not a macro
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:34:5
|
||||
|
|
||||
LL | crate::MyTrait!();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: expected macro, found derive macro `crate::MyTrait`
|
||||
--> $DIR/macro-namespace-reserved-2.rs:34:5
|
||||
|
|
||||
LL | crate::MyTrait!();
|
||||
| ^^^^^^^^^^^^^^ not a macro
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:42:3
|
||||
|
|
||||
LL | #[my_macro_attr]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:38:3
|
||||
--> $DIR/macro-namespace-reserved-2.rs:44:3
|
||||
|
|
||||
LL | #[MyTrait]
|
||||
| ^^^^^^^
|
||||
|
||||
error: `MyTrait` is a derive macro
|
||||
--> $DIR/macro-namespace-reserved-2.rs:38:1
|
||||
error: expected attribute, found derive macro `MyTrait`
|
||||
--> $DIR/macro-namespace-reserved-2.rs:44:3
|
||||
|
|
||||
LL | #[MyTrait]
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^^^ not an attribute
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:44:10
|
||||
--> $DIR/macro-namespace-reserved-2.rs:49:10
|
||||
|
|
||||
LL | #[derive(crate::my_macro)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected derive macro, found macro `crate::my_macro`
|
||||
--> $DIR/macro-namespace-reserved-2.rs:49:10
|
||||
|
|
||||
LL | #[derive(crate::my_macro)]
|
||||
| ^^^^^^^^^^^^^^^ not a derive macro
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:52:10
|
||||
|
|
||||
LL | #[derive(my_macro_attr)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: macro `my_macro_attr` may not be used for derive attributes
|
||||
--> $DIR/macro-namespace-reserved-2.rs:44:10
|
||||
error: expected derive macro, found attribute macro `my_macro_attr`
|
||||
--> $DIR/macro-namespace-reserved-2.rs:52:10
|
||||
|
|
||||
LL | #[derive(my_macro_attr)]
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^ not a derive macro
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:47:10
|
||||
--> $DIR/macro-namespace-reserved-2.rs:55:10
|
||||
|
|
||||
LL | #[derive(MyTrait)]
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0658]: The attribute `my_macro` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/macro-namespace-reserved-2.rs:34:3
|
||||
--> $DIR/macro-namespace-reserved-2.rs:38:3
|
||||
|
|
||||
LL | #[my_macro]
|
||||
| ^^^^^^^^
|
||||
|
@ -49,8 +85,20 @@ LL | #[my_macro]
|
|||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/macro-namespace-reserved-2.rs:39:3
|
||||
|
|
||||
LL | #[crate::my_macro]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected attribute, found macro `crate::my_macro`
|
||||
--> $DIR/macro-namespace-reserved-2.rs:39:3
|
||||
|
|
||||
LL | #[crate::my_macro]
|
||||
| ^^^^^^^^^^^^^^^ not an attribute
|
||||
|
||||
error: cannot find derive macro `my_macro` in this scope
|
||||
--> $DIR/macro-namespace-reserved-2.rs:42:10
|
||||
--> $DIR/macro-namespace-reserved-2.rs:48:10
|
||||
|
|
||||
LL | #[derive(my_macro)]
|
||||
| ^^^^^^^^
|
||||
|
@ -62,11 +110,11 @@ LL | my_macro_attr!();
|
|||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: cannot find macro `MyTrait!` in this scope
|
||||
--> $DIR/macro-namespace-reserved-2.rs:31:5
|
||||
--> $DIR/macro-namespace-reserved-2.rs:33:5
|
||||
|
|
||||
LL | MyTrait!();
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
error: aborting due to 19 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[derive(rustfmt::skip)] //~ ERROR macro `rustfmt::skip` may not be used for derive attributes
|
||||
#[derive(rustfmt::skip)] //~ ERROR expected derive macro, found tool attribute `rustfmt::skip`
|
||||
struct S;
|
||||
|
||||
fn main() {
|
||||
rustfmt::skip!(); //~ ERROR `rustfmt::skip` can only be used in attributes
|
||||
rustfmt::skip!(); //~ ERROR expected macro, found tool attribute `rustfmt::skip`
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
error: macro `rustfmt::skip` may not be used for derive attributes
|
||||
error: expected derive macro, found tool attribute `rustfmt::skip`
|
||||
--> $DIR/tool-attributes-misplaced-2.rs:1:10
|
||||
|
|
||||
LL | #[derive(rustfmt::skip)]
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^ not a derive macro
|
||||
|
||||
error: `rustfmt::skip` can only be used in attributes
|
||||
error: expected macro, found tool attribute `rustfmt::skip`
|
||||
--> $DIR/tool-attributes-misplaced-2.rs:5:5
|
||||
|
|
||||
LL | rustfmt::skip!();
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^ not a macro
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue