diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 6cb851eb8df6b..e8bff931f835e 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -415,6 +415,9 @@ parse_invalid_meta_item = expected unsuffixed literal, found `{$token}` parse_invalid_offset_of = offset_of expects dot-separated field and variant names +parse_invalid_path_sep_in_fn_definition = invalid path separator in function definition + .suggestion = remove invalid path separator + parse_invalid_unicode_escape = invalid unicode character escape .label = invalid escape .help = unicode escape must {$surrogate -> diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 20bcefd4fe1e7..86ed38a96c53b 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1755,6 +1755,14 @@ pub(crate) struct MissingFnParams { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parse_invalid_path_sep_in_fn_definition)] +pub(crate) struct InvalidPathSepInFnDefinition { + #[primary_span] + #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_missing_trait_in_trait_impl)] pub(crate) struct MissingTraitInTraitImpl { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 9fc82d84225cc..7807b3c12ecef 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2767,9 +2767,16 @@ impl<'a> Parser<'a> { // might be typo'd trait impl, handled elsewhere && !self.token.is_keyword(kw::For) { - // recover from missing argument list, e.g. `fn main -> () {}` - self.dcx() - .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() }); + if self.token == token::PathSep && self.look_ahead(1, |t| *t == TokenKind::Lt) { + // invalid path separator `::` in function definition + // for example `fn invalid_path_separator::() {}` + self.dcx().emit_err(errors::InvalidPathSepInFnDefinition { span: self.token.span }); + } else { + // recover from missing argument list, e.g. `fn main -> () {}` + self.dcx().emit_err(errors::MissingFnParams { + span: self.prev_token.span.shrink_to_hi(), + }); + } return Ok(ThinVec::new()); } diff --git a/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.fixed b/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.fixed new file mode 100644 index 0000000000000..a0f9e1d719864 --- /dev/null +++ b/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.fixed @@ -0,0 +1,8 @@ +//@ run-rustfix + +#[allow(dead_code)] +fn invalid_path_separator() {} +//~^ ERROR invalid path separator in function definition +//~| ERROR expected + +fn main() {} diff --git a/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.rs b/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.rs new file mode 100644 index 0000000000000..5314fbbf75c4f --- /dev/null +++ b/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.rs @@ -0,0 +1,8 @@ +//@ run-rustfix + +#[allow(dead_code)] +fn invalid_path_separator::() {} +//~^ ERROR invalid path separator in function definition +//~| ERROR expected + +fn main() {} diff --git a/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.stderr b/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.stderr new file mode 100644 index 0000000000000..d93c07f8cab40 --- /dev/null +++ b/tests/ui/parser/issues/invalid-path-sep-in-fn-definition-issue-130791.stderr @@ -0,0 +1,20 @@ +error: invalid path separator in function definition + --> $DIR/invalid-path-sep-in-fn-definition-issue-130791.rs:4:26 + | +LL | fn invalid_path_separator::() {} + | ^^ + | +help: remove invalid path separator + | +LL - fn invalid_path_separator::() {} +LL + fn invalid_path_separator() {} + | + +error: expected one of `->`, `<`, `where`, or `{`, found `::` + --> $DIR/invalid-path-sep-in-fn-definition-issue-130791.rs:4:26 + | +LL | fn invalid_path_separator::() {} + | ^^ expected one of `->`, `<`, `where`, or `{` + +error: aborting due to 2 previous errors +