From fc83fc885ddfef7c695c49e1be3af90655f4af44 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 9 Sep 2026 05:02:14 +0900 Subject: [PATCH 1/2] avoid ICEs when recovering malformed function parameters --- .../rustc_parse/src/parser/diagnostics.rs | 36 +++++++++++++------ .../recover-invalid-fn-trait-bound-pattern.rs | 5 +++ ...over-invalid-fn-trait-bound-pattern.stderr | 20 +++++++++++ ...over-invalid-function-parameter-pattern.rs | 6 ++++ ...-invalid-function-parameter-pattern.stderr | 28 +++++++++++++++ 5 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs create mode 100644 tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr create mode 100644 tests/ui/parser/recover-invalid-function-parameter-pattern.rs create mode 100644 tests/ui/parser/recover-invalid-function-parameter-pattern.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index db6af6ab17aca..928518c88fec6 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2140,16 +2140,32 @@ impl<'a> Parser<'a> { let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?; self.expect(exp!(Colon))?; let ty = self.parse_ty()?; - self.dcx().emit_err(PatternMethodParamWithoutBody { - span: pat.span, - target: match context { - FnContext::Trait => "methods without bodies", - FnContext::FunctionPtrType => "function pointer types", - FnContext::ParenthesizedArgumentList => "parenthesized argument list", - FnContext::Free => unreachable!("This method is not called in free functions, as patterns are always allowed there"), - FnContext::Impl => unreachable!("This method is not called in impls, as patterns are always allowed there"), - }, - }); + match context { + FnContext::Trait + | FnContext::FunctionPtrType + | FnContext::ParenthesizedArgumentList => { + self.dcx().emit_err(PatternMethodParamWithoutBody { + span: pat.span, + target: if context == FnContext::Trait { + "methods without bodies" + } else if context == FnContext::FunctionPtrType { + "function pointer types" + } else { + "parenthesized argument list" + }, + }); + } + FnContext::Free | FnContext::Impl => { + self.dcx().span_delayed_bug( + pat.span, + if context == FnContext::Free { + "This method is not called in free functions, as patterns are always allowed there" + } else { + "This method is not called in impls, as patterns are always allowed there" + }, + ); + } + } // Pretend the pattern is `_`, to avoid duplicate errors from AST validation. let pat = Box::new(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID }); diff --git a/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs new file mode 100644 index 0000000000000..abbff103bb2be --- /dev/null +++ b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs @@ -0,0 +1,5 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160337. + +struct Baz where U : fn(() : bool) +//~^ ERROR expected identifier, found keyword `fn` +//~| ERROR expected `{` after struct name, found `` diff --git a/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr new file mode 100644 index 0000000000000..02ec950b3a365 --- /dev/null +++ b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr @@ -0,0 +1,20 @@ +error: expected identifier, found keyword `fn` + --> $DIR/recover-invalid-fn-trait-bound-pattern.rs:3:22 + | +LL | struct Baz where U : fn(() : bool) + | ^^ + | +help: use `Fn` to refer to the trait (notice the capitalization) + | +LL - struct Baz where U : fn(() : bool) +LL + struct Baz where U : Fn(() : bool) + | + +error: expected `{` after struct name, found `` + --> $DIR/recover-invalid-fn-trait-bound-pattern.rs:3:34 + | +LL | struct Baz where U : fn(() : bool) + | ^ expected `{` after struct name + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern.rs b/tests/ui/parser/recover-invalid-function-parameter-pattern.rs new file mode 100644 index 0000000000000..a9e6a5578486f --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern.rs @@ -0,0 +1,6 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160337. + +fn main(... : ...) +//~^ ERROR unexpected `...` +//~| ERROR unexpected `...` +//~| ERROR expected one of `->`, `where`, or `{`, found `` diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr b/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr new file mode 100644 index 0000000000000..d4b78db29dba9 --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr @@ -0,0 +1,28 @@ +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern.rs:3:9 + | +LL | fn main(... : ...) + | ^^^ not a valid pattern + | +help: for a rest pattern, use `..` instead of `...` + | +LL - fn main(... : ...) +LL + fn main(.. : ...) + | + +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern.rs:3:15 + | +LL | fn main(... : ...) + | ^^^ + | + = note: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: expected one of `->`, `where`, or `{`, found `` + --> $DIR/recover-invalid-function-parameter-pattern.rs:3:18 + | +LL | fn main(... : ...) + | ^ expected one of `->`, `where`, or `{` + +error: aborting due to 3 previous errors + From e2160bd1cd7a99e0fc2d33b1c0f5229a5ec80ca1 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 24 Sep 2026 00:14:06 +0900 Subject: [PATCH 2/2] convert the malformed function parameter crash test to a UI test --- tests/crashes/160490.rs | 2 - ...r-invalid-function-parameter-pattern-1.rs} | 0 ...valid-function-parameter-pattern-1.stderr} | 6 +-- ...er-invalid-function-parameter-pattern-2.rs | 8 ++++ ...nvalid-function-parameter-pattern-2.stderr | 43 +++++++++++++++++++ 5 files changed, 54 insertions(+), 5 deletions(-) delete mode 100644 tests/crashes/160490.rs rename tests/ui/parser/{recover-invalid-function-parameter-pattern.rs => recover-invalid-function-parameter-pattern-1.rs} (100%) rename tests/ui/parser/{recover-invalid-function-parameter-pattern.stderr => recover-invalid-function-parameter-pattern-1.stderr} (75%) create mode 100644 tests/ui/parser/recover-invalid-function-parameter-pattern-2.rs create mode 100644 tests/ui/parser/recover-invalid-function-parameter-pattern-2.stderr diff --git a/tests/crashes/160490.rs b/tests/crashes/160490.rs deleted file mode 100644 index 5f713ed268042..0000000000000 --- a/tests/crashes/160490.rs +++ /dev/null @@ -1,2 +0,0 @@ -//@ known-bug: #160490 -fn f(...: u8) {} diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern.rs b/tests/ui/parser/recover-invalid-function-parameter-pattern-1.rs similarity index 100% rename from tests/ui/parser/recover-invalid-function-parameter-pattern.rs rename to tests/ui/parser/recover-invalid-function-parameter-pattern-1.rs diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr b/tests/ui/parser/recover-invalid-function-parameter-pattern-1.stderr similarity index 75% rename from tests/ui/parser/recover-invalid-function-parameter-pattern.stderr rename to tests/ui/parser/recover-invalid-function-parameter-pattern-1.stderr index d4b78db29dba9..0bf724d0db8eb 100644 --- a/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern-1.stderr @@ -1,5 +1,5 @@ error: unexpected `...` - --> $DIR/recover-invalid-function-parameter-pattern.rs:3:9 + --> $DIR/recover-invalid-function-parameter-pattern-1.rs:3:9 | LL | fn main(... : ...) | ^^^ not a valid pattern @@ -11,7 +11,7 @@ LL + fn main(.. : ...) | error: unexpected `...` - --> $DIR/recover-invalid-function-parameter-pattern.rs:3:15 + --> $DIR/recover-invalid-function-parameter-pattern-1.rs:3:15 | LL | fn main(... : ...) | ^^^ @@ -19,7 +19,7 @@ LL | fn main(... : ...) = note: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: expected one of `->`, `where`, or `{`, found `` - --> $DIR/recover-invalid-function-parameter-pattern.rs:3:18 + --> $DIR/recover-invalid-function-parameter-pattern-1.rs:3:18 | LL | fn main(... : ...) | ^ expected one of `->`, `where`, or `{` diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern-2.rs b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.rs new file mode 100644 index 0000000000000..ea0233f433099 --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.rs @@ -0,0 +1,8 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160490. + +fn f(...: u8) {} +//~^ ERROR unexpected `...` +//~| ERROR missing pattern for `...` argument +//~| WARN this was previously accepted by the compiler + +fn main() {} diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern-2.stderr b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.stderr new file mode 100644 index 0000000000000..7a9ea16a9d5d5 --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.stderr @@ -0,0 +1,43 @@ +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern-2.rs:3:6 + | +LL | fn f(...: u8) {} + | ^^^ not a valid pattern + | +help: for a rest pattern, use `..` instead of `...` + | +LL - fn f(...: u8) {} +LL + fn f(..: u8) {} + | + +error: missing pattern for `...` argument + --> $DIR/recover-invalid-function-parameter-pattern-2.rs:3:6 + | +LL | fn f(...: u8) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 + = note: `#[deny(varargs_without_pattern)]` (part of `#[deny(future_incompatible)]`) on by default +help: name the argument, or use `_` to continue ignoring it + | +LL | fn f(_: ...: u8) {} + | ++ + +error: aborting due to 2 previous errors + +Future incompatibility report: Future breakage diagnostic: +error: missing pattern for `...` argument + --> $DIR/recover-invalid-function-parameter-pattern-2.rs:3:6 + | +LL | fn f(...: u8) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 + = note: `#[deny(varargs_without_pattern)]` (part of `#[deny(future_incompatible)]`) on by default +help: name the argument, or use `_` to continue ignoring it + | +LL | fn f(_: ...: u8) {} + | ++ +