Skip to content

Commit b18b269

Browse files
authored
Rollup merge of #68681 - bobrippling:fix-matched-angle-brackets, r=Centril
Suggest path separator for single-colon typos This commit adds guidance for when a user means to type a path, but ends up typing a single colon, such as `<<Impl as T>:Ty>`. This change seemed pertinent as the current error message is particularly misleading, emitting `error: unmatched angle bracket`, despite the angle bracket being matched later on, leaving the user to track down the typo'd colon.
2 parents bf68a05 + 07ee472 commit b18b269

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

src/librustc_parse/parser/path.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,49 @@ impl<'a> Parser<'a> {
7171
debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count);
7272
}
7373

74-
self.expect(&token::ModSep)?;
74+
if !self.recover_colon_before_qpath_proj() {
75+
self.expect(&token::ModSep)?;
76+
}
7577

7678
let qself = QSelf { ty, path_span, position: path.segments.len() };
7779
self.parse_path_segments(&mut path.segments, style)?;
7880

7981
Ok((qself, Path { segments: path.segments, span: lo.to(self.prev_span) }))
8082
}
8183

84+
/// Recover from an invalid single colon, when the user likely meant a qualified path.
85+
/// We avoid emitting this if not followed by an identifier, as our assumption that the user
86+
/// intended this to be a qualified path may not be correct.
87+
///
88+
/// ```ignore (diagnostics)
89+
/// <Bar as Baz<T>>:Qux
90+
/// ^ help: use double colon
91+
/// ```
92+
fn recover_colon_before_qpath_proj(&mut self) -> bool {
93+
if self.token.kind != token::Colon
94+
|| self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident())
95+
{
96+
return false;
97+
}
98+
99+
self.bump(); // colon
100+
101+
self.diagnostic()
102+
.struct_span_err(
103+
self.prev_span,
104+
"found single colon before projection in qualified path",
105+
)
106+
.span_suggestion(
107+
self.prev_span,
108+
"use double colon",
109+
"::".to_string(),
110+
Applicability::MachineApplicable,
111+
)
112+
.emit();
113+
114+
true
115+
}
116+
82117
/// Parses simple paths.
83118
///
84119
/// `path = [::] segment+`
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// run-rustfix
2+
trait T {
3+
type Ty;
4+
}
5+
6+
struct Impl;
7+
8+
impl T for Impl {
9+
type Ty = u32;
10+
}
11+
12+
fn template<T>() -> i64 {
13+
3
14+
}
15+
16+
fn main() {
17+
template::<<Impl as T>::Ty>();
18+
//~^ ERROR found single colon before projection in qualified path
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// run-rustfix
2+
trait T {
3+
type Ty;
4+
}
5+
6+
struct Impl;
7+
8+
impl T for Impl {
9+
type Ty = u32;
10+
}
11+
12+
fn template<T>() -> i64 {
13+
3
14+
}
15+
16+
fn main() {
17+
template::<<Impl as T>:Ty>();
18+
//~^ ERROR found single colon before projection in qualified path
19+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: found single colon before projection in qualified path
2+
--> $DIR/qualified-path-in-turbofish.rs:17:27
3+
|
4+
LL | template::<<Impl as T>:Ty>();
5+
| ^ help: use double colon: `::`
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)