Skip to content

Commit d090e5e

Browse files
committed
Account for trailing closing angle brackets
1 parent 20f4e5d commit d090e5e

File tree

3 files changed

+75
-23
lines changed

3 files changed

+75
-23
lines changed

src/librustc_parse/parser/diagnostics.rs

+35-22
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use super::ty::AllowPlus;
22
use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType};
33

4-
use rustc_ast::ast::{self, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Item, Param};
54
use rustc_ast::ast::{
6-
AngleBracketedArgs, AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
5+
self, AngleBracketedArgs, AttrVec, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind,
6+
Item, ItemKind, Mutability, Param, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
77
};
88
use rustc_ast::ptr::P;
99
use rustc_ast::token::{self, Lit, LitKind, TokenKind};
@@ -498,29 +498,42 @@ impl<'a> Parser<'a> {
498498
self.bump();
499499
let lo = self.token.span;
500500
match self.parse_angle_args() {
501-
Ok(args) if self.token.kind == token::OpenDelim(token::Paren) => {
502-
// Recover from bad turbofish: `foo.collect::Vec<_>()`.
501+
Ok(args) => {
503502
let span = lo.to(self.prev_token.span);
504-
let args = AngleBracketedArgs { args, span }.into();
505-
segment.args = args;
506-
self.struct_span_err(
507-
span,
508-
"generic parameters without surrounding angle brackets",
509-
)
510-
.multipart_suggestion(
511-
"surround the type parameters with angle brackets",
512-
vec![
513-
(span.shrink_to_lo(), "<".to_string()),
514-
(span.shrink_to_hi(), ">".to_string()),
515-
],
516-
Applicability::MachineApplicable,
517-
)
518-
.emit();
519-
}
520-
Ok(_) => {
521-
*self = snapshot;
503+
// Detect trailing `>` like in `x.collect::Vec<_>>()`.
504+
let mut trailing_span = self.prev_token.span.shrink_to_hi();
505+
while self.token.kind == token::BinOp(token::Shr)
506+
|| self.token.kind == token::Gt
507+
{
508+
trailing_span = trailing_span.to(self.token.span);
509+
self.bump();
510+
}
511+
if self.token.kind == token::OpenDelim(token::Paren) {
512+
// Recover from bad turbofish: `foo.collect::Vec<_>()`.
513+
let args = AngleBracketedArgs { args, span }.into();
514+
segment.args = args;
515+
516+
self.struct_span_err(
517+
span,
518+
"generic parameters without surrounding angle brackets",
519+
)
520+
.multipart_suggestion(
521+
"surround the type parameters with angle brackets",
522+
vec![
523+
(span.shrink_to_lo(), "<".to_string()),
524+
(trailing_span, ">".to_string()),
525+
],
526+
Applicability::MachineApplicable,
527+
)
528+
.emit();
529+
} else {
530+
// This doesn't look like an invalid turbofish, can't recover parse state.
531+
*self = snapshot;
532+
}
522533
}
523534
Err(mut err) => {
535+
// We could't parse generic parameters, unlikely to be a turbofish. Rely on
536+
// generic parse error instead.
524537
err.cancel();
525538
*self = snapshot;
526539
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
fn main() {
22
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>();
33
//~^ ERROR generic parameters without surrounding angle brackets
4+
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>>();
5+
//~^ ERROR generic parameters without surrounding angle brackets
6+
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>();
7+
//~^ ERROR generic parameters without surrounding angle brackets
8+
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>();
9+
//~^ ERROR generic parameters without surrounding angle brackets
410
}

src/test/ui/suggestions/recover-missing-turbofish-surrounding-angle-braket.stderr

+34-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,38 @@ help: surround the type parameters with angle brackets
99
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
1010
| ^ ^
1111

12-
error: aborting due to previous error
12+
error: generic parameters without surrounding angle brackets
13+
--> $DIR/recover-missing-turbofish-surrounding-angle-braket.rs:4:48
14+
|
15+
LL | let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>>();
16+
| ^^^^^^
17+
|
18+
help: surround the type parameters with angle brackets
19+
|
20+
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
21+
| ^ ^
22+
23+
error: generic parameters without surrounding angle brackets
24+
--> $DIR/recover-missing-turbofish-surrounding-angle-braket.rs:6:48
25+
|
26+
LL | let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>();
27+
| ^^^^^^
28+
|
29+
help: surround the type parameters with angle brackets
30+
|
31+
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
32+
| ^ ^
33+
34+
error: generic parameters without surrounding angle brackets
35+
--> $DIR/recover-missing-turbofish-surrounding-angle-braket.rs:8:48
36+
|
37+
LL | let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>();
38+
| ^^^^^^
39+
|
40+
help: surround the type parameters with angle brackets
41+
|
42+
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
43+
| ^ ^
44+
45+
error: aborting due to 4 previous errors
1346

0 commit comments

Comments
 (0)