From 6caa586f572429fd08a5df7283a97666d898d043 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 21 Feb 2025 17:39:49 +0000 Subject: [PATCH] Recover param: Ty = EXPR --- compiler/rustc_parse/src/parser/ty.rs | 27 ++++++++++++++++++-- tests/ui/parser/recover/param-default.rs | 5 ++++ tests/ui/parser/recover/param-default.stderr | 14 ++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 tests/ui/parser/recover/param-default.rs create mode 100644 tests/ui/parser/recover/param-default.stderr diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 899a43955ab77..94f381ee051b0 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -137,14 +137,37 @@ impl<'a> Parser<'a> { /// The difference from `parse_ty` is that this version allows `...` /// (`CVarArgs`) at the top level of the type. pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, Box> { - self.parse_ty_common( + let ty = self.parse_ty_common( AllowPlus::Yes, AllowCVariadic::Yes, RecoverQPath::Yes, RecoverReturnSign::Yes, None, RecoverQuestionMark::Yes, - ) + )?; + + // Recover a trailing `= EXPR` if present. + if self.may_recover() + && self.check_noexpect(&token::Eq) + && self.look_ahead(1, |tok| tok.can_begin_expr()) + { + let snapshot = self.create_snapshot_for_diagnostic(); + self.bump(); + let eq_span = self.prev_token.span; + match self.parse_expr() { + Ok(e) => { + self.dcx() + .struct_span_err(eq_span.to(e.span), "parameter defaults are not supported") + .emit(); + } + Err(diag) => { + diag.cancel(); + self.restore_snapshot(snapshot); + } + } + } + + Ok(ty) } /// Parses a type in restricted contexts where `+` is not permitted. diff --git a/tests/ui/parser/recover/param-default.rs b/tests/ui/parser/recover/param-default.rs new file mode 100644 index 0000000000000..5311d4dfae689 --- /dev/null +++ b/tests/ui/parser/recover/param-default.rs @@ -0,0 +1,5 @@ +fn foo(x: i32 = 1) {} //~ ERROR parameter defaults are not supported + +type Foo = fn(i32 = 0); //~ ERROR parameter defaults are not supported + +fn main() {} diff --git a/tests/ui/parser/recover/param-default.stderr b/tests/ui/parser/recover/param-default.stderr new file mode 100644 index 0000000000000..93dea427daf11 --- /dev/null +++ b/tests/ui/parser/recover/param-default.stderr @@ -0,0 +1,14 @@ +error: parameter defaults are not supported + --> $DIR/param-default.rs:1:15 + | +LL | fn foo(x: i32 = 1) {} + | ^^^ + +error: parameter defaults are not supported + --> $DIR/param-default.rs:3:19 + | +LL | type Foo = fn(i32 = 0); + | ^^^ + +error: aborting due to 2 previous errors +