Skip to content

Commit de98267

Browse files
committed
Recover from missing param list in function definitions
1 parent 10143e7 commit de98267

File tree

6 files changed

+61
-2
lines changed

6 files changed

+61
-2
lines changed

compiler/rustc_parse/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,9 @@ parse_missing_fn_for_function_definition = missing `fn` for function definition
523523
parse_missing_fn_for_method_definition = missing `fn` for method definition
524524
.suggestion = add `fn` here to parse `{$ident}` as a public method
525525
526+
parse_missing_fn_params = missing parameters for function definition
527+
.suggestion = add a parameter list
528+
526529
parse_missing_for_in_trait_impl = missing `for` in a trait impl
527530
.suggestion = add `for` here
528531

compiler/rustc_parse/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,6 +1543,14 @@ pub(crate) enum AmbiguousMissingKwForItemSub {
15431543
HelpMacro,
15441544
}
15451545

1546+
#[derive(Diagnostic)]
1547+
#[diag(parse_missing_fn_params)]
1548+
pub(crate) struct MissingFnParams {
1549+
#[primary_span]
1550+
#[suggestion(code = "()", applicability = "machine-applicable", style = "short")]
1551+
pub span: Span,
1552+
}
1553+
15461554
#[derive(Diagnostic)]
15471555
#[diag(parse_missing_trait_in_trait_impl)]
15481556
pub(crate) struct MissingTraitInTraitImpl {

compiler/rustc_parse/src/parser/item.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,7 +2492,7 @@ impl<'a> Parser<'a> {
24922492
pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinVec<Param>> {
24932493
let mut first_param = true;
24942494
// Parse the arguments, starting out with `self` being allowed...
2495-
let (mut params, _) = self.parse_paren_comma_seq(|p| {
2495+
let parsed = self.parse_paren_comma_seq(|p| {
24962496
p.recover_diff_marker();
24972497
let param = p.parse_param_general(req_name, first_param).or_else(|mut e| {
24982498
e.emit();
@@ -2505,7 +2505,23 @@ impl<'a> Parser<'a> {
25052505
// ...now that we've parsed the first argument, `self` is no longer allowed.
25062506
first_param = false;
25072507
param
2508-
})?;
2508+
});
2509+
let mut params = match parsed {
2510+
Ok((p, _)) => p,
2511+
Err(e) => {
2512+
if self.token.kind != TokenKind::OpenDelim(Delimiter::Parenthesis) {
2513+
// recover from missing argument list, e.g. `fn main -> () {}`
2514+
e.cancel();
2515+
self.sess.emit_err(errors::MissingFnParams {
2516+
span: self.prev_token.span.shrink_to_hi(),
2517+
});
2518+
return Ok(ThinVec::new());
2519+
} else {
2520+
return Err(e);
2521+
}
2522+
}
2523+
};
2524+
25092525
// Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
25102526
self.deduplicate_recovered_params_names(&mut params);
25112527
Ok(params)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// run-rustfix
2+
3+
pub fn missing() -> () {}
4+
//~^ ERROR missing parameters for function definition
5+
6+
pub fn missing2() {}
7+
//~^ ERROR missing parameters for function definition
8+
9+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// run-rustfix
2+
3+
pub fn missing -> () {}
4+
//~^ ERROR missing parameters for function definition
5+
6+
pub fn missing2 {}
7+
//~^ ERROR missing parameters for function definition
8+
9+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: missing parameters for function definition
2+
--> $DIR/issue-108109-fn-missing-params.rs:3:15
3+
|
4+
LL | pub fn missing -> () {}
5+
| ^ help: add a parameter list
6+
7+
error: missing parameters for function definition
8+
--> $DIR/issue-108109-fn-missing-params.rs:6:16
9+
|
10+
LL | pub fn missing2 {}
11+
| ^ help: add a parameter list
12+
13+
error: aborting due to 2 previous errors
14+

0 commit comments

Comments
 (0)