diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-11-05 10:29:54 -0800 | 
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-11-05 10:29:54 -0800 | 
| commit | a8ccbf5f2fa75007ce0effe58caef4e342859a4f (patch) | |
| tree | de4a7862c55287076de8397f19102ff9a8860e19 | |
| parent | 3bbfc7320ba0f23541f94a84cf5281a210a546cd (diff) | |
| download | rust-a8ccbf5f2fa75007ce0effe58caef4e342859a4f.tar.gz rust-a8ccbf5f2fa75007ce0effe58caef4e342859a4f.zip | |
Account for typo in turbofish and suggest `::`
| -rw-r--r-- | src/libsyntax/parse/parser/diagnostics.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr | 2 | 
2 files changed, 11 insertions, 5 deletions
| diff --git a/src/libsyntax/parse/parser/diagnostics.rs b/src/libsyntax/parse/parser/diagnostics.rs index ad479e6278b..fc2b10f2260 100644 --- a/src/libsyntax/parse/parser/diagnostics.rs +++ b/src/libsyntax/parse/parser/diagnostics.rs @@ -358,7 +358,7 @@ impl<'a> Parser<'a> { err: &mut DiagnosticBuilder<'_>, maybe_expected_semicolon: bool, ) { - if let Some((sp, likely_path)) = self.last_type_ascription { + if let Some((sp, likely_path)) = self.last_type_ascription.take() { let sm = self.sess.source_map(); let next_pos = sm.lookup_char_pos(self.token.span.lo()); let op_pos = sm.lookup_char_pos(sp.hi()); @@ -395,7 +395,6 @@ impl<'a> Parser<'a> { err.note("for more information, see \ https://github.com/rust-lang/rust/issues/23416"); } - self.last_type_ascription = None; } } @@ -1083,8 +1082,15 @@ impl<'a> Parser<'a> { } pub(super) fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool { - self.token.is_ident() && - if let ast::ExprKind::Path(..) = node { true } else { false } && + (self.token == token::Lt && // `foo:<bar`, likely a typoed turbofish. + self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident()) + ) || + self.token.is_ident() && + match node { + // `foo::` → `foo:` or `foo.bar::` → `foo.bar:` + ast::ExprKind::Path(..) | ast::ExprKind::Field(..) => true, + _ => false, + } && !self.token.is_reserved_ident() && // v `foo:bar(baz)` self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) || self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar<baz` diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr index 191c4f631c4..db793c84cf8 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr @@ -4,7 +4,7 @@ error: expected `::`, found `(` LL | vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; | - ^ expected `::` | | - | tried to parse a type due to this type ascription + | help: maybe write a path separator here: `::` | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` = note: for more information, see https://github.com/rust-lang/rust/issues/23416 | 
