Skip to content

Commit 1d23ada

Browse files
committed
Improve diagnostics for parenthesized type arguments
1 parent 1c580bc commit 1d23ada

7 files changed

+123
-1
lines changed

compiler/rustc_parse/src/parser/path.rs

+47-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
22
use super::{Parser, Restrictions, TokenType};
33
use crate::errors::PathSingleColon;
4+
use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
45
use crate::{errors, maybe_whole};
56
use ast::token::IdentIsRaw;
67
use rustc_ast::ptr::P;
@@ -373,7 +374,52 @@ impl<'a> Parser<'a> {
373374
.into()
374375
} else {
375376
// `(T, U) -> R`
376-
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
377+
let prev_token_before_parsing = self.prev_token.clone();
378+
379+
let mut snapshot = None;
380+
if self.may_recover()
381+
&& (self.token.can_begin_expr() || self.token.can_begin_pattern())
382+
{
383+
snapshot = Some(self.create_snapshot_for_diagnostic());
384+
}
385+
386+
let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) {
387+
Ok(output) => output,
388+
Err(mut error) if prev_token_before_parsing.kind == token::ModSep => {
389+
error.span_label(prev_token_before_parsing.span.with_hi(prev_token_before_parsing.span.hi() + BytePos(1)), "while parsing this list of parenthesized type arguments starting here");
390+
391+
if let Some(mut snapshot) = snapshot {
392+
if ((style == PathStyle::Expr
393+
&& snapshot.parse_paren_comma_seq(|p| p.parse_expr()).is_ok())
394+
|| (style == PathStyle::Pat
395+
&& snapshot
396+
.parse_paren_comma_seq(|p| {
397+
p.parse_pat_allow_top_alt(
398+
None,
399+
RecoverComma::No,
400+
RecoverColon::No,
401+
CommaRecoveryMode::LikelyTuple,
402+
)
403+
})
404+
.is_ok()))
405+
&& snapshot.token.kind != token::ModSep
406+
&& snapshot.token.kind != token::RArrow
407+
{
408+
{
409+
error.span_suggestion_verbose(
410+
prev_token_before_parsing.span,
411+
"consider removing `::`",
412+
"",
413+
Applicability::Unspecified,
414+
);
415+
}
416+
}
417+
}
418+
419+
return Err(error);
420+
}
421+
Err(error) => return Err(error),
422+
};
377423
let inputs_span = lo.to(self.prev_token.span);
378424
let output =
379425
self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fn main() {
2+
foo::( //~ HELP: consider removing `::`
3+
//~^ NOTE: while parsing this list of parenthesized type arguments starting here
4+
bar(x, y, z),
5+
bar(x, y, z),
6+
bar(x, y, z),
7+
bar(x, y, z),
8+
bar(x, y, z),
9+
bar(x, y, z),
10+
bar(x, y, z),
11+
baz("test"), //~ ERROR: expected type, found `"test"`
12+
//~^ NOTE: expected type
13+
)
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: expected type, found `"test"`
2+
--> $DIR/issue-120892-1.rs:11:9
3+
|
4+
LL | foo::(
5+
| --- while parsing this list of parenthesized type arguments starting here
6+
...
7+
LL | baz("test"),
8+
| ^^^^^^ expected type
9+
|
10+
help: consider removing `::`
11+
|
12+
LL - foo::(
13+
LL + foo(
14+
|
15+
16+
error: aborting due to 1 previous error
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
foo::(123, "foo") -> (u32); //~ ERROR: expected type, found `123`
3+
//~^ NOTE: while parsing this list of parenthesized type arguments starting here
4+
//~^^ NOTE: expected type
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: expected type, found `123`
2+
--> $DIR/issue-120892-2.rs:2:9
3+
|
4+
LL | foo::(123, "foo") -> (u32);
5+
| ---^^^ expected type
6+
| |
7+
| while parsing this list of parenthesized type arguments starting here
8+
9+
error: aborting due to 1 previous error
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
struct Foo(u32, u32);
2+
impl Foo {
3+
fn foo(&self) {
4+
match *self {
5+
Foo::(1, 2) => {}, //~ HELP: consider removing `::`
6+
//~^ NOTE: while parsing this list of parenthesized type arguments starting here
7+
//~^^ ERROR: expected type, found `1`
8+
//~^^^ NOTE: expected type
9+
_ => {},
10+
}
11+
}
12+
}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: expected type, found `1`
2+
--> $DIR/issue-120892-3.rs:5:19
3+
|
4+
LL | Foo::(1, 2) => {},
5+
| ---^ expected type
6+
| |
7+
| while parsing this list of parenthesized type arguments starting here
8+
|
9+
help: consider removing `::`
10+
|
11+
LL - Foo::(1, 2) => {},
12+
LL + Foo(1, 2) => {},
13+
|
14+
15+
error: aborting due to 1 previous error
16+

0 commit comments

Comments
 (0)