From 3bbfc7320ba0f23541f94a84cf5281a210a546cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 4 Nov 2019 16:19:55 -0800 Subject: [PATCH 1/2] Detect `::` -> `:` typo when involving turbofish --- src/libsyntax/parse/parser/diagnostics.rs | 3 ++- src/libsyntax/parse/parser/stmt.rs | 1 + .../type-ascription-instead-of-path-2.rs | 5 +++++ .../type-ascription-instead-of-path-2.stderr | 13 +++++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-path-2.rs create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr diff --git a/src/libsyntax/parse/parser/diagnostics.rs b/src/libsyntax/parse/parser/diagnostics.rs index ab2b4519cb72a..ad479e6278b70 100644 --- a/src/libsyntax/parse/parser/diagnostics.rs +++ b/src/libsyntax/parse/parser/diagnostics.rs @@ -354,7 +354,7 @@ impl<'a> Parser<'a> { } pub fn maybe_annotate_with_ascription( - &self, + &mut self, err: &mut DiagnosticBuilder<'_>, maybe_expected_semicolon: bool, ) { @@ -395,6 +395,7 @@ impl<'a> Parser<'a> { err.note("for more information, see \ https://github.com/rust-lang/rust/issues/23416"); } + self.last_type_ascription = None; } } diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs index 4f51fefe66fba..12c530f3cbba0 100644 --- a/src/libsyntax/parse/parser/stmt.rs +++ b/src/libsyntax/parse/parser/stmt.rs @@ -397,6 +397,7 @@ impl<'a> Parser<'a> { } let stmt = match self.parse_full_stmt(false) { Err(mut err) => { + self.maybe_annotate_with_ascription(&mut err, false); err.emit(); self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore); Some(Stmt { diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs new file mode 100644 index 0000000000000..220fd1eebda46 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs @@ -0,0 +1,5 @@ +fn main() -> Result<(), ()> { + vec![Ok(2)].into_iter().collect:,_>>()?; + //~^ ERROR expected `::`, found `(` + Ok(()) +} 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 new file mode 100644 index 0000000000000..191c4f631c458 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr @@ -0,0 +1,13 @@ +error: expected `::`, found `(` + --> $DIR/type-ascription-instead-of-path-2.rs:2:55 + | +LL | vec![Ok(2)].into_iter().collect:,_>>()?; + | - ^ expected `::` + | | + | tried to parse a type due to this type ascription + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 + +error: aborting due to previous error + From a8ccbf5f2fa75007ce0effe58caef4e342859a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 5 Nov 2019 10:29:54 -0800 Subject: [PATCH 2/2] Account for typo in turbofish and suggest `::` --- src/libsyntax/parse/parser/diagnostics.rs | 14 ++++++++++---- .../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 ad479e6278b70..fc2b10f226097 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: 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,_>>()?; | - ^ 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: `: ` = note: for more information, see https://github.com/rust-lang/rust/issues/23416