This PR fixes #12495 where equational theorem generation fails for structurally recursive definitions using a Box-like wrapper around nested inductives. ## Root Cause `withInferTypeConfig` (in `InferType.lean`) ensures various MetaM config settings (`beta`, `iota`, `zeta`, `zetaHave`, `zetaDelta`, `proj`) are enabled during type inference, but was missing `etaStruct`. When `inferType` is called from a context where `etaStruct` is disabled — such as inside `simpMatch` (which sets `etaStruct := .none` via `SimpM.run` → `withSimpContext`) — `whnf` cannot eta-expand structure values needed for recursor iota reduction. Concretely, projecting from a type like `Rec.rec_2 ... base` (where `base : Box Rec`) requires eta-expanding `base` to `Box.mk base.data` so the `Box` recursor can reduce. With `etaStruct := .none`, `toCtorWhenStructure` skips the eta-expansion, leaving `whnf` stuck and `inferProjType` unable to recognize the resulting type as a structure. ## Fix Add `etaStruct := .all` to the config settings ensured by `withInferTypeConfig`, alongside the existing `beta`, `iota`, `zeta`, `zetaHave`, `zetaDelta`, and `proj` settings. This also allows reverting the workaround (`try/catch` around `simpMatch?`) that was added in the first commit. ## Test plan - [x] Existing test `tests/lean/run/issue12495.lean` passes - [x] Full test suite (3561 tests) passes with 0 failures 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
22 lines
664 B
Text
22 lines
664 B
Text
-- Regression test for https://github.com/leanprover/lean4/issues/12495
|
||
-- Equational theorem generation fails for structurally recursive definition
|
||
-- using a Box-like wrapper.
|
||
|
||
structure Box (α : Type u) where
|
||
data : α
|
||
|
||
structure Rec where
|
||
base? : Option (Box Rec)
|
||
|
||
def test (self : Rec) : List (Box Rec) :=
|
||
match self with
|
||
| {base? := none, ..} => []
|
||
| {base? := some base, ..} => base :: test base.data
|
||
termination_by structural self
|
||
|
||
-- unfold should work, meaning equational theorems are generated.
|
||
example : test { base? := none } = [] := by
|
||
unfold test; rfl
|
||
|
||
-- Check that the unfold equation exists and can be applied
|
||
#check @test.eq_unfold
|