diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index e0778f72bfe6e..6e0d44bd00e42 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -523,6 +523,9 @@ parse_missing_fn_for_function_definition = missing `fn` for function definition parse_missing_fn_for_method_definition = missing `fn` for method definition .suggestion = add `fn` here to parse `{$ident}` as a public method +parse_missing_fn_params = missing parameters for function definition + .suggestion = add a parameter list + parse_missing_for_in_trait_impl = missing `for` in a trait impl .suggestion = add `for` here diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index aeb4fd0a304aa..f22d70ec809f8 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1543,6 +1543,14 @@ pub(crate) enum AmbiguousMissingKwForItemSub { HelpMacro, } +#[derive(Diagnostic)] +#[diag(parse_missing_fn_params)] +pub(crate) struct MissingFnParams { + #[primary_span] + #[suggestion(code = "()", applicability = "machine-applicable", style = "short")] + 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 982f601c0d5a2..8340dfe2de8f0 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2492,6 +2492,19 @@ impl<'a> Parser<'a> { pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinVec> { let mut first_param = true; // Parse the arguments, starting out with `self` being allowed... + if self.token.kind != TokenKind::OpenDelim(Delimiter::Parenthesis) { + // removed syntax, handled elsewhere + if self.token.kind != TokenKind::Tilde + // might be typo'd trait impl, handled elsewhere + && !self.token.is_keyword(kw::For) + { + // recover from missing argument list, e.g. `fn main -> () {}` + self.sess.emit_err(errors::MissingFnParams { + span: self.prev_token.span.shrink_to_hi(), + }); + return Ok(ThinVec::new()); + } + } let (mut params, _) = self.parse_paren_comma_seq(|p| { p.recover_diff_marker(); let param = p.parse_param_general(req_name, first_param).or_else(|mut e| { diff --git a/tests/ui/mismatched_types/recovered-block.rs b/tests/ui/mismatched_types/recovered-block.rs index b230b47d35d37..a91bbe7083bc2 100644 --- a/tests/ui/mismatched_types/recovered-block.rs +++ b/tests/ui/mismatched_types/recovered-block.rs @@ -12,10 +12,4 @@ pub fn foo() -> Foo { } //~^^ ERROR missing `struct` for struct definition -pub fn bar() -> Foo { - fn - Foo { text: "".to_string() } -} -//~^^ ERROR expected one of `(` or `<`, found `{` - fn main() {} diff --git a/tests/ui/mismatched_types/recovered-block.stderr b/tests/ui/mismatched_types/recovered-block.stderr index f275321abe5eb..88d625456564f 100644 --- a/tests/ui/mismatched_types/recovered-block.stderr +++ b/tests/ui/mismatched_types/recovered-block.stderr @@ -9,11 +9,5 @@ help: add `struct` here to parse `Foo` as a public struct LL | pub struct Foo { text } | ++++++ -error: expected one of `(` or `<`, found `{` - --> $DIR/recovered-block.rs:17:9 - | -LL | Foo { text: "".to_string() } - | ^ expected one of `(` or `<` - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/parser/issues/issue-108109-fn-missing-params.fixed b/tests/ui/parser/issues/issue-108109-fn-missing-params.fixed new file mode 100644 index 0000000000000..b819aa810cb77 --- /dev/null +++ b/tests/ui/parser/issues/issue-108109-fn-missing-params.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +pub fn missing() -> () {} +//~^ ERROR missing parameters for function definition + +pub fn missing2() {} +//~^ ERROR missing parameters for function definition + +fn main() {} diff --git a/tests/ui/parser/issues/issue-108109-fn-missing-params.rs b/tests/ui/parser/issues/issue-108109-fn-missing-params.rs new file mode 100644 index 0000000000000..01efe728081f3 --- /dev/null +++ b/tests/ui/parser/issues/issue-108109-fn-missing-params.rs @@ -0,0 +1,9 @@ +// run-rustfix + +pub fn missing -> () {} +//~^ ERROR missing parameters for function definition + +pub fn missing2 {} +//~^ ERROR missing parameters for function definition + +fn main() {} diff --git a/tests/ui/parser/issues/issue-108109-fn-missing-params.stderr b/tests/ui/parser/issues/issue-108109-fn-missing-params.stderr new file mode 100644 index 0000000000000..86d3449cc33b6 --- /dev/null +++ b/tests/ui/parser/issues/issue-108109-fn-missing-params.stderr @@ -0,0 +1,14 @@ +error: missing parameters for function definition + --> $DIR/issue-108109-fn-missing-params.rs:3:15 + | +LL | pub fn missing -> () {} + | ^ help: add a parameter list + +error: missing parameters for function definition + --> $DIR/issue-108109-fn-missing-params.rs:6:16 + | +LL | pub fn missing2 {} + | ^ help: add a parameter list + +error: aborting due to 2 previous errors +