diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2020-02-02 08:30:11 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-02 08:30:11 +0900 |
| commit | b18b26924c640211a358535f14e39695c48b0ec3 (patch) | |
| tree | 2c7c8a6eb9c5078b81e04b0177348b9fb29072f5 | |
| parent | bf68a057b39837ee8b9ccf00d902d1964e8ed326 (diff) | |
| parent | 07ee472cd18925be45d424d9cfd59c441ea9c9a7 (diff) | |
| download | rust-b18b26924c640211a358535f14e39695c48b0ec3.tar.gz rust-b18b26924c640211a358535f14e39695c48b0ec3.zip | |
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.
| -rw-r--r-- | src/librustc_parse/parser/path.rs | 37 | ||||
| -rw-r--r-- | src/test/ui/parser/qualified-path-in-turbofish.fixed | 19 | ||||
| -rw-r--r-- | src/test/ui/parser/qualified-path-in-turbofish.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/parser/qualified-path-in-turbofish.stderr | 8 |
4 files changed, 82 insertions, 1 deletions
diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 0358458c099..a09eb42dcfe 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -71,7 +71,9 @@ impl<'a> Parser<'a> { debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count); } - self.expect(&token::ModSep)?; + if !self.recover_colon_before_qpath_proj() { + self.expect(&token::ModSep)?; + } let qself = QSelf { ty, path_span, position: path.segments.len() }; self.parse_path_segments(&mut path.segments, style)?; @@ -79,6 +81,39 @@ impl<'a> Parser<'a> { Ok((qself, Path { segments: path.segments, span: lo.to(self.prev_span) })) } + /// Recover from an invalid single colon, when the user likely meant a qualified path. + /// We avoid emitting this if not followed by an identifier, as our assumption that the user + /// intended this to be a qualified path may not be correct. + /// + /// ```ignore (diagnostics) + /// <Bar as Baz<T>>:Qux + /// ^ help: use double colon + /// ``` + fn recover_colon_before_qpath_proj(&mut self) -> bool { + if self.token.kind != token::Colon + || self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident()) + { + return false; + } + + self.bump(); // colon + + self.diagnostic() + .struct_span_err( + self.prev_span, + "found single colon before projection in qualified path", + ) + .span_suggestion( + self.prev_span, + "use double colon", + "::".to_string(), + Applicability::MachineApplicable, + ) + .emit(); + + true + } + /// Parses simple paths. /// /// `path = [::] segment+` diff --git a/src/test/ui/parser/qualified-path-in-turbofish.fixed b/src/test/ui/parser/qualified-path-in-turbofish.fixed new file mode 100644 index 00000000000..404d2f7762d --- /dev/null +++ b/src/test/ui/parser/qualified-path-in-turbofish.fixed @@ -0,0 +1,19 @@ +// run-rustfix +trait T { + type Ty; +} + +struct Impl; + +impl T for Impl { + type Ty = u32; +} + +fn template<T>() -> i64 { + 3 +} + +fn main() { + template::<<Impl as T>::Ty>(); + //~^ ERROR found single colon before projection in qualified path +} diff --git a/src/test/ui/parser/qualified-path-in-turbofish.rs b/src/test/ui/parser/qualified-path-in-turbofish.rs new file mode 100644 index 00000000000..2f4b2ed348b --- /dev/null +++ b/src/test/ui/parser/qualified-path-in-turbofish.rs @@ -0,0 +1,19 @@ +// run-rustfix +trait T { + type Ty; +} + +struct Impl; + +impl T for Impl { + type Ty = u32; +} + +fn template<T>() -> i64 { + 3 +} + +fn main() { + template::<<Impl as T>:Ty>(); + //~^ ERROR found single colon before projection in qualified path +} diff --git a/src/test/ui/parser/qualified-path-in-turbofish.stderr b/src/test/ui/parser/qualified-path-in-turbofish.stderr new file mode 100644 index 00000000000..8857d2ef30c --- /dev/null +++ b/src/test/ui/parser/qualified-path-in-turbofish.stderr @@ -0,0 +1,8 @@ +error: found single colon before projection in qualified path + --> $DIR/qualified-path-in-turbofish.rs:17:27 + | +LL | template::<<Impl as T>:Ty>(); + | ^ help: use double colon: `::` + +error: aborting due to previous error + |
