More explicit diagnostic when using a vec![] in a pattern

```
error: unexpected `(` after qualified path
  --> $DIR/vec-macro-in-pattern.rs:3:14
   |
LL |         Some(vec![x]) => (),
   |              ^^^^^^^
   |              |
   |              unexpected `(` after qualified path
   |              in this macro invocation
   |              use a slice pattern here instead
   |
   = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
```
This commit is contained in:
Esteban Küber 2019-08-08 18:24:00 -07:00
parent 813a3a5d4b
commit 7c96d90c20
6 changed files with 68 additions and 7 deletions

View File

@ -686,12 +686,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
);
}
fn parse_ast_fragment(&mut self,
toks: TokenStream,
kind: AstFragmentKind,
path: &Path,
span: Span)
-> AstFragment {
fn parse_ast_fragment(
&mut self,
toks: TokenStream,
kind: AstFragmentKind,
path: &Path,
span: Span,
) -> AstFragment {
let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
match parser.parse_ast_fragment(kind, false) {
Ok(fragment) => {
@ -700,6 +701,21 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
Err(mut err) => {
err.set_span(span);
match kind {
AstFragmentKind::Ty => {
err.span_label(
span,
"this macro call doesn't expand to a type",
);
}
AstFragmentKind::Pat => {
err.span_label(
span,
"this macro call doesn't expand to a pattern",
);
}
_ => {}
};
err.emit();
self.cx.trace_macros_diag();
kind.dummy(span)

View File

@ -70,6 +70,29 @@ impl<'a> ParserAnyMacro<'a> {
} else if !parser.sess.source_map().span_to_filename(parser.token.span).is_real() {
e.span_label(site_span, "in this macro invocation");
}
match kind {
AstFragmentKind::Ty => {
e.span_label(
site_span,
"this macro call doesn't expand to a type",
);
}
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
e.span_label(
site_span,
"use a slice pattern here instead",
);
e.help("for more information, see https://doc.rust-lang.org/edition-guide/\
rust-2018/slice-patterns.html");
}
AstFragmentKind::Pat => {
e.span_label(
site_span,
"this macro call doesn't expand to a pattern",
);
}
_ => {}
};
e
}));

View File

@ -2,7 +2,7 @@ error: expected type, found `'`
--> $DIR/lifetimes.rs:9:10
|
LL | type A = single_quote_alone!();
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ this macro call doesn't expand to a type
error: aborting due to previous error

View File

@ -0,0 +1,6 @@
fn main() {
match Some(vec![3]) {
Some(vec![x]) => (), //~ ERROR unexpected `(` after qualified path
_ => (),
}
}

View File

@ -0,0 +1,15 @@
error: unexpected `(` after qualified path
--> $DIR/vec-macro-in-pattern.rs:3:14
|
LL | Some(vec![x]) => (),
| ^^^^^^^
| |
| unexpected `(` after qualified path
| in this macro invocation
| use a slice pattern here instead
|
= help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: aborting due to previous error

View File

@ -6,6 +6,7 @@ LL | let _ = Option:Some(vec![0, 1]);
| | |
| | expected type
| | in this macro invocation
| | this macro call doesn't expand to a type
| help: maybe write a path separator here: `::`
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`