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/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index b9256daa72525..9b38512591588 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -1,4 +1,4 @@ -use ast::token::Delimiter; +use ast::token::{Delimiter, TokenKind}; use rustc_ast::{ self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause, token, }; @@ -275,6 +275,11 @@ impl<'a> Parser<'a> { self.expect_gt_or_maybe_suggest_closing_generics(¶ms)?; (params, span_lo.to(self.prev_token.span)) } else { + 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 }); + } (ThinVec::new(), self.prev_token.span.shrink_to_hi()) }; Ok(ast::Generics { 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 +