diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-11-06 03:28:15 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-06 03:28:15 +0100 |
| commit | 409b2bf941b2724a028f65518c64f799f205a186 (patch) | |
| tree | 18d029fe26855d648607d80090acb0a28048f5fe /src | |
| parent | 7d66a09a29342d520a3a17ae3b4f6233c97948f4 (diff) | |
| parent | a8ccbf5f2fa75007ce0effe58caef4e342859a4f (diff) | |
| download | rust-409b2bf941b2724a028f65518c64f799f205a186.tar.gz rust-409b2bf941b2724a028f65518c64f799f205a186.zip | |
Rollup merge of #66098 - estebank:path-asciption-typo, r=Centril
Detect `::` -> `:` typo when involving turbofish Fix #65569.
Diffstat (limited to 'src')
4 files changed, 30 insertions, 4 deletions
diff --git a/src/libsyntax/parse/parser/diagnostics.rs b/src/libsyntax/parse/parser/diagnostics.rs index fcf3b4c0aa8..453ef5963be 100644 --- a/src/libsyntax/parse/parser/diagnostics.rs +++ b/src/libsyntax/parse/parser/diagnostics.rs @@ -360,11 +360,11 @@ impl<'a> Parser<'a> { } pub fn maybe_annotate_with_ascription( - &self, + &mut self, 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()); @@ -1088,8 +1088,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/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs index 4f51fefe66f..12c530f3cbb 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 00000000000..220fd1eebda --- /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:<Result<Vec<_>,_>>()?; + //~^ 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 00000000000..db793c84cf8 --- /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:<Result<Vec<_>,_>>()?; + | - ^ expected `::` + | | + | 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 + +error: aborting due to previous error + |
