diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index a61e77b7c3bfb..12753c6785c9a 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -553,39 +553,46 @@ impl<'a> Parser<'a> { match stmt.kind { // Expression without semicolon. StmtKind::Expr(ref mut expr) - if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => - { + if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => { // Just check for errors and recover; do not eat semicolon yet. - if let Err(mut e) = - self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]) - { - if let TokenKind::DocComment(..) = self.token.kind { - if let Ok(snippet) = self.span_to_snippet(self.token.span) { - let sp = self.token.span; - let marker = &snippet[..3]; - let (comment_marker, doc_comment_marker) = marker.split_at(2); - - e.span_suggestion( - sp.with_hi(sp.lo() + BytePos(marker.len() as u32)), - &format!( - "add a space before `{}` to use a regular comment", - doc_comment_marker, - ), - format!("{} {}", comment_marker, doc_comment_marker), - Applicability::MaybeIncorrect, - ); + // `expect_one_of` returns PResult<'a, bool /* recovered */> + let replace_with_err = + match self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]) { + // Recover from parser, skip type error to avoid extra errors. + Ok(true) => true, + Err(mut e) => { + if let TokenKind::DocComment(..) = self.token.kind && + let Ok(snippet) = self.span_to_snippet(self.token.span) { + let sp = self.token.span; + let marker = &snippet[..3]; + let (comment_marker, doc_comment_marker) = marker.split_at(2); + + e.span_suggestion( + sp.with_hi(sp.lo() + BytePos(marker.len() as u32)), + &format!( + "add a space before `{}` to use a regular comment", + doc_comment_marker, + ), + format!("{} {}", comment_marker, doc_comment_marker), + Applicability::MaybeIncorrect, + ); } - } - if let Err(mut e) = - self.check_mistyped_turbofish_with_multiple_type_params(e, expr) - { - if recover.no() { - return Err(e); + + if let Err(mut e) = + self.check_mistyped_turbofish_with_multiple_type_params(e, expr) + { + if recover.no() { + return Err(e); + } + e.emit(); + self.recover_stmt(); } - e.emit(); - self.recover_stmt(); + true } - // Don't complain about type errors in body tail after parse error (#57383). + _ => false + }; + if replace_with_err { + // We already emitted an error, so don't emit another type error let sp = expr.span.to(self.prev_token.span); *expr = self.mk_expr_err(sp); } diff --git a/src/test/ui/parser/issue-103425.rs b/src/test/ui/parser/issue-103425.rs new file mode 100644 index 0000000000000..c2f8123ca4e67 --- /dev/null +++ b/src/test/ui/parser/issue-103425.rs @@ -0,0 +1,15 @@ +fn f() -> f32 { + 3 + //~^ ERROR expected `;` + 5.0 +} + +fn k() -> f32 { + 2_u32 + //~^ ERROR expected `;` + 3_i8 + //~^ ERROR expected `;` + 5.0 +} + +fn main() {} diff --git a/src/test/ui/parser/issue-103425.stderr b/src/test/ui/parser/issue-103425.stderr new file mode 100644 index 0000000000000..0efe3e3ca7117 --- /dev/null +++ b/src/test/ui/parser/issue-103425.stderr @@ -0,0 +1,29 @@ +error: expected `;`, found `5.0` + --> $DIR/issue-103425.rs:2:6 + | +LL | 3 + | ^ help: add `;` here +LL | +LL | 5.0 + | --- unexpected token + +error: expected `;`, found `3_i8` + --> $DIR/issue-103425.rs:8:10 + | +LL | 2_u32 + | ^ help: add `;` here +LL | +LL | 3_i8 + | ---- unexpected token + +error: expected `;`, found `5.0` + --> $DIR/issue-103425.rs:10:9 + | +LL | 3_i8 + | ^ help: add `;` here +LL | +LL | 5.0 + | --- unexpected token + +error: aborting due to 3 previous errors +