rust-lang/rust · critical
This method is not called in free functions, as patterns are
Error message
This method is not called in free functions, as patterns are always allowed there
What it means
Internal `unreachable!` in `recover_arg_parse`, which recovers from malformed function parameters by re-parsing `pat: Ty`. This recovery is only valid for trait method signatures and function-pointer types, where identifier-only parameters (no pattern) are disallowed; for free functions and inherent impls patterns are always permitted, so the caller must never pass `FnContext::Free` or `FnContext::Impl`. The `target` field's match arms for those two variants panic.
Source
Thrown at compiler/rustc_parse/src/parser/diagnostics.rs:2400
return if self.token == token::Lt { None } else { Some(ident) };
}
None
}
#[cold]
pub(super) fn recover_arg_parse(
&mut self,
context: FnContext,
) -> PResult<'a, (Box<ast::Pat>, Box<ast::Ty>)> {
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::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"),
},
});
// 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 });
Ok((pat, ty))
}
pub(super) fn recover_bad_self_param(&mut self, mut param: Param) -> PResult<'a, Param> {
let span = param.pat.span;
let guar = self.dcx().emit_err(SelfParamNotFirst { span });
param.ty.kind = TyKind::Err(guar);
Ok(param)
}
pub(super) fn consume_block(
&mut self,View on GitHub (pinned to 22057b88b0)
Solutions
- Fix the syntax error the compiler was attempting to recover from (add the missing type annotation) so recovery is not invoked
- Report as a rustc ICE with the malformed function signature and the backtrace
- Try a different toolchain to check whether it is a recent regression
Example fix
// before: malformed parameter triggers recovery
fn f(x) {}
// after: provide the parameter type so recovery is unnecessary
fn f(x: i32) {} Defensive patterns
Strategy: type-guard
Type guard
use rustc_ast::ast::{Item, ItemKind};
pub fn item_allows_patterns_unconditionally(item: &Item) -> bool {
// Free functions always allow patterns; the guarded method is meant for
// closures/associated fns/other contexts where patterns may be restricted.
matches!(item.kind, ItemKind::Fn(..)) && !item_is_in_impl_or_trait(item)
}
fn item_is_in_impl_or_trait(_item: &Item) -> bool { /* consult parent context */ false } Prevention
- Only call this pattern-restriction method on parameters of closures or associated functions, never on free functions.
- Inspect the parent item kind before invoking; for top-level `fn`, patterns are always allowed and the method will panic.
- Carry the enclosing item context alongside the param so you can branch on free-fn vs associated-fn.
- If walking params generically, skip the method call when the owner is an ItemKind::Fn at module scope.
When it happens
Trigger: The parser's argument-recovery logic is invoked with `context = FnContext::Free` or `FnContext::Impl`, i.e. the caller misclassified the surrounding function kind while recovering from a bad parameter.
Common situations: Compiler regression in parameter parsing/recovery after refactor of `FnContext`; surfaced when a user writes a malformed parameter (e.g. missing type) and the recovery path is misrouted.
Related errors
- file modules must have an attribute to exclude
- because the current token is a '{'
- layout decided on a larger discriminant type ({min_ity:?}) t
- encountered a non-arbitrary layout during enum layout
- obj_size_bound: unknown pointer bit size {bits}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/c8ca520080bd621c.json.
Report an issue: GitHub.