diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 905b3347a54..30969948c4c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -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) { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2f7fb79a7f5..2349382eb5e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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!() } } diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs index d3a2e486416..9ce2fb58ab0 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -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] diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr index f098635c702..7c5aa5381e8 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -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 diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.rs b/src/test/ui/macros/macro-path-prelude-fail-4.rs index 44f0f2d7ec0..0f93fcdaa5f 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.rs +++ b/src/test/ui/macros/macro-path-prelude-fail-4.rs @@ -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() {} diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.stderr b/src/test/ui/macros/macro-path-prelude-fail-4.stderr index fdd7bf3235c..dfd6818b678 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-4.stderr @@ -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 diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs index c7b092830a2..7a9e472c6c3 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs @@ -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; diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index 83c77513ec3..a724d388f48 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -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`. diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs index b95791f4e99..b5666e4ea70 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs @@ -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` } diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr index 8ef27a07b7f..6d0f826e621 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr @@ -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