diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 75e3393aa96..9f8361a4b1e 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -39,7 +39,7 @@ use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{Span, SpanSnippetError, Symbol, DUMMY_SP}; +use rustc_span::{BytePos, Span, SpanSnippetError, Symbol, DUMMY_SP}; use std::mem::take; use std::ops::{Deref, DerefMut}; use thin_vec::{thin_vec, ThinVec}; @@ -648,6 +648,26 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool { ); } + if let token::DocComment(kind, style, _) = self.token.kind { + // We have something like `expr //!val` where the user likely meant `expr // !val` + let pos = self.token.span.lo() + BytePos(2); + let span = self.token.span.with_lo(pos).with_hi(pos); + err.span_suggestion_verbose( + span, + format!( + "add a space before {} to write a regular comment", + match (kind, style) { + (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`", + (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`", + (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`", + (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`", + }, + ), + " ".to_string(), + Applicability::MachineApplicable, + ); + } + // Add suggestion for a missing closing angle bracket if '>' is included in expected_tokens // there are unclosed angle brackets if self.unmatched_angle_bracket_count > 0 diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index e2f59cb2071..8e3c4568694 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -632,23 +632,6 @@ pub fn parse_full_stmt( // 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 `{doc_comment_marker}` to use a regular comment", - ), - format!("{comment_marker} {doc_comment_marker}"), - Applicability::MaybeIncorrect, - ); - } - if self.recover_colon_as_semi() { // recover_colon_as_semi has already emitted a nicer error. e.delay_as_bug(); diff --git a/tests/ui/parser/doc-comment-in-stmt.fixed b/tests/ui/parser/doc-comment-in-stmt.fixed new file mode 100644 index 00000000000..4b3ecccf66c --- /dev/null +++ b/tests/ui/parser/doc-comment-in-stmt.fixed @@ -0,0 +1,27 @@ +// run-rustfix +#![allow(unused)] +fn foo() -> bool { + false + // !self.allow_ty_infer() + //~^ ERROR found doc comment +} + +fn bar() -> bool { + false + /* ! bar */ //~ ERROR found doc comment +} + +fn baz() -> i32 { + 1 /* * baz */ //~ ERROR found doc comment +} + +fn quux() -> i32 { + 2 // / quux + //~^ ERROR found doc comment +} + +fn main() { + let x = 0; + let y = x.max(1) // !foo //~ ERROR found doc comment + .min(2); +} diff --git a/tests/ui/parser/doc-comment-in-stmt.rs b/tests/ui/parser/doc-comment-in-stmt.rs index b02df13213f..73d08f51c66 100644 --- a/tests/ui/parser/doc-comment-in-stmt.rs +++ b/tests/ui/parser/doc-comment-in-stmt.rs @@ -1,3 +1,5 @@ +// run-rustfix +#![allow(unused)] fn foo() -> bool { false //!self.allow_ty_infer() @@ -14,7 +16,12 @@ fn baz() -> i32 { } fn quux() -> i32 { - 2 /*! quux */ //~ ERROR found doc comment + 2 /// quux + //~^ ERROR found doc comment } -fn main() {} +fn main() { + let x = 0; + let y = x.max(1) //!foo //~ ERROR found doc comment + .min(2); +} diff --git a/tests/ui/parser/doc-comment-in-stmt.stderr b/tests/ui/parser/doc-comment-in-stmt.stderr index febfb600cc7..7aefd5c9952 100644 --- a/tests/ui/parser/doc-comment-in-stmt.stderr +++ b/tests/ui/parser/doc-comment-in-stmt.stderr @@ -1,50 +1,61 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `//!self.allow_ty_infer()` - --> $DIR/doc-comment-in-stmt.rs:3:5 + --> $DIR/doc-comment-in-stmt.rs:5:5 | LL | false | - expected one of `.`, `;`, `?`, `}`, or an operator LL | //!self.allow_ty_infer() | ^^^^^^^^^^^^^^^^^^^^^^^^ unexpected token | -help: add a space before `!` to use a regular comment +help: add a space before `!` to write a regular comment | LL | // !self.allow_ty_infer() - | ~~~~ + | + error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! bar */` - --> $DIR/doc-comment-in-stmt.rs:9:5 + --> $DIR/doc-comment-in-stmt.rs:11:5 | LL | false | - expected one of `.`, `;`, `?`, `}`, or an operator LL | /*! bar */ | ^^^^^^^^^^ unexpected token | -help: add a space before `!` to use a regular comment +help: add a space before `!` to write a regular comment | LL | /* ! bar */ - | ~~~~ + | + error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/** baz */` - --> $DIR/doc-comment-in-stmt.rs:13:7 + --> $DIR/doc-comment-in-stmt.rs:15:7 | LL | 1 /** baz */ | ^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator | -help: add a space before `*` to use a regular comment +help: add a space before the last `*` to write a regular comment | LL | 1 /* * baz */ - | ~~~~ + | + -error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! quux */` - --> $DIR/doc-comment-in-stmt.rs:17:7 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/// quux` + --> $DIR/doc-comment-in-stmt.rs:19:7 | -LL | 2 /*! quux */ - | ^^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator +LL | 2 /// quux + | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator | -help: add a space before `!` to use a regular comment +help: add a space before the last `/` to write a regular comment | -LL | 2 /* ! quux */ - | ~~~~ +LL | 2 // / quux + | + -error: aborting due to 4 previous errors +error: expected one of `.`, `;`, `?`, `else`, or an operator, found doc comment `//!foo + --> $DIR/doc-comment-in-stmt.rs:25:22 + | +LL | let y = x.max(1) //!foo + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected one of `.`, `;`, `?`, `else`, or an operator + | +help: add a space before `!` to write a regular comment + | +LL | let y = x.max(1) // !foo + | + + +error: aborting due to 5 previous errors