about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-03 12:47:24 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-11 00:12:08 +0300
commit3041ec61185d6f9795ff16cc345e8f11b06edbbf (patch)
tree4b64ce98429b47fcc3001ea7aaa4006c5694596a
parentf16993d4acaf90285f6c86268a0ec2e7167c2a58 (diff)
downloadrust-3041ec61185d6f9795ff16cc345e8f11b06edbbf.tar.gz
rust-3041ec61185d6f9795ff16cc345e8f11b06edbbf.zip
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.
-rw-r--r--src/librustc_resolve/macros.rs13
-rw-r--r--src/libsyntax/ext/expand.rs39
-rw-r--r--src/test/ui/feature-gates/feature-gate-rustc-attrs.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr12
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-4.rs2
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-4.stderr4
-rw-r--r--src/test/ui/proc-macro/macro-namespace-reserved-2.rs12
-rw-r--r--src/test/ui/proc-macro/macro-namespace-reserved-2.stderr76
-rw-r--r--src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs4
-rw-r--r--src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr8
10 files changed, 106 insertions, 68 deletions
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