Skip to content

Commit 9ece794

Browse files
authored
Rollup merge of rust-lang#63399 - estebank:vec-in-pat, r=Centril
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) ``` Fix rust-lang#61933.
2 parents 45d089a + 75c5ad2 commit 9ece794

File tree

7 files changed

+81
-8
lines changed

7 files changed

+81
-8
lines changed

src/libsyntax/ext/expand.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::config::StripUnconfigured;
66
use crate::ext::base::*;
77
use crate::ext::proc_macro::collect_derives;
88
use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind};
9+
use crate::ext::tt::macro_rules::annotate_err_with_kind;
910
use crate::ext::placeholders::{placeholder, PlaceholderExpander};
1011
use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
1112
use crate::mut_visit::*;
@@ -686,12 +687,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
686687
);
687688
}
688689

689-
fn parse_ast_fragment(&mut self,
690-
toks: TokenStream,
691-
kind: AstFragmentKind,
692-
path: &Path,
693-
span: Span)
694-
-> AstFragment {
690+
fn parse_ast_fragment(
691+
&mut self,
692+
toks: TokenStream,
693+
kind: AstFragmentKind,
694+
path: &Path,
695+
span: Span,
696+
) -> AstFragment {
695697
let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
696698
match parser.parse_ast_fragment(kind, false) {
697699
Ok(fragment) => {
@@ -700,6 +702,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
700702
}
701703
Err(mut err) => {
702704
err.set_span(span);
705+
annotate_err_with_kind(&mut err, kind, span);
703706
err.emit();
704707
self.cx.trace_macros_diag();
705708
kind.dummy(span)

src/libsyntax/ext/tt/macro_rules.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::symbol::{kw, sym, Symbol};
1717
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
1818
use crate::{ast, attr, attr::TransparencyError};
1919

20-
use errors::FatalError;
20+
use errors::{DiagnosticBuilder, FatalError};
2121
use log::debug;
2222
use syntax_pos::Span;
2323

@@ -43,6 +43,18 @@ pub struct ParserAnyMacro<'a> {
4343
arm_span: Span,
4444
}
4545

46+
pub fn annotate_err_with_kind(err: &mut DiagnosticBuilder<'_>, kind: AstFragmentKind, span: Span) {
47+
match kind {
48+
AstFragmentKind::Ty => {
49+
err.span_label(span, "this macro call doesn't expand to a type");
50+
}
51+
AstFragmentKind::Pat => {
52+
err.span_label(span, "this macro call doesn't expand to a pattern");
53+
}
54+
_ => {}
55+
};
56+
}
57+
4658
impl<'a> ParserAnyMacro<'a> {
4759
pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
4860
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
@@ -70,6 +82,32 @@ impl<'a> ParserAnyMacro<'a> {
7082
} else if !parser.sess.source_map().span_to_filename(parser.token.span).is_real() {
7183
e.span_label(site_span, "in this macro invocation");
7284
}
85+
match kind {
86+
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
87+
let mut suggestion = None;
88+
if let Ok(code) = parser.sess.source_map().span_to_snippet(site_span) {
89+
if let Some(bang) = code.find('!') {
90+
suggestion = Some(code[bang + 1..].to_string());
91+
}
92+
}
93+
if let Some(suggestion) = suggestion {
94+
e.span_suggestion(
95+
site_span,
96+
"use a slice pattern here instead",
97+
suggestion,
98+
Applicability::MachineApplicable,
99+
);
100+
} else {
101+
e.span_label(
102+
site_span,
103+
"use a slice pattern here instead",
104+
);
105+
}
106+
e.help("for more information, see https://doc.rust-lang.org/edition-guide/\
107+
rust-2018/slice-patterns.html");
108+
}
109+
_ => annotate_err_with_kind(&mut e, kind, site_span),
110+
};
73111
e
74112
}));
75113

src/test/ui/proc-macro/lifetimes.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: expected type, found `'`
22
--> $DIR/lifetimes.rs:9:10
33
|
44
LL | type A = single_quote_alone!();
5-
| ^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^ this macro call doesn't expand to a type
66

77
error: aborting due to previous error
88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
fn main() {
3+
// everything after `.as_ref` should be suggested
4+
match Some(vec![3]).as_ref().map(|v| v.as_slice()) {
5+
Some([_x]) => (), //~ ERROR unexpected `(` after qualified path
6+
_ => (),
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
fn main() {
3+
// everything after `.as_ref` should be suggested
4+
match Some(vec![3]).as_ref().map(|v| v.as_slice()) {
5+
Some(vec![_x]) => (), //~ ERROR unexpected `(` after qualified path
6+
_ => (),
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: unexpected `(` after qualified path
2+
--> $DIR/vec-macro-in-pattern.rs:5:14
3+
|
4+
LL | Some(vec![_x]) => (),
5+
| ^^^^^^^^
6+
| |
7+
| unexpected `(` after qualified path
8+
| in this macro invocation
9+
| help: use a slice pattern here instead: `[_x]`
10+
|
11+
= help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
12+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
13+
14+
error: aborting due to previous error
15+

src/test/ui/type/ascription/issue-47666.stderr

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

0 commit comments

Comments
 (0)