Skip to content

Commit 2eca5ca

Browse files
kim-emclaude
andauthored
fix: getEqnsFor? should not panic on matchers (#11463)
This PR fixes a panic in `getEqnsFor?` when called on matchers generated from match expressions in theorem types. When a theorem's type contains a match expression (e.g., `theorem bar : (match ... with ...) = 0`), the compiler generates a matcher like `bar.match_1`. Calling `getEqnsFor?` on this matcher would panic with: ``` PANIC: duplicate normalized declaration name bar.match_1.eq_1 vs. _private...bar.match_1.eq_1 ``` This also affected the `try?` tactic, which internally uses `getEqnsFor?`. We make `shouldGenerateEqnThms` return `false` for matchers, since their equations are already generated separately by `Lean.Meta.Match.MatchEqs`. This prevents the equation generation machinery from attempting to create duplicate equation theorems. Closes #11461 Closes #10390 🤖 Prepared with Claude Code Co-authored-by: Claude <[email protected]>
1 parent 1fc4768 commit 2eca5ca

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/Lean/Meta/Eqns.lean

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,13 @@ def registerGetEqnsFn (f : GetEqnsFn) : IO Unit := do
150150
throw (IO.userError "failed to register equation getter, this kind of extension can only be registered during initialization")
151151
getEqnsFnsRef.modify (f :: ·)
152152

153-
/-- Returns `true` iff `declName` is a definition and its type is not a proposition. -/
153+
/-- Returns `true` iff `declName` is a definition and its type is not a proposition.
154+
Returns `false` for matchers since their equations are handled by `Lean.Meta.Match.MatchEqs`. -/
154155
private def shouldGenerateEqnThms (declName : Name) : MetaM Bool := do
155156
if let some { kind := .defn, sig, .. } := (← getEnv).findAsync? declName then
157+
-- Matcher equations are handled separately in Lean.Meta.Match.MatchEqs
158+
if isMatcherCore (← getEnv) declName then
159+
return false
156160
return !(← isProp sig.get.type)
157161
else
158162
return false

tests/lean/run/try_panic.lean

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Lean
2+
3+
/-!
4+
# Regression test: getEqnsFor? should not panic on matchers
5+
6+
Previously, when a theorem had a match expression in its type (e.g. `bar.match_1`),
7+
calling `getEqnsFor?` on the matcher would panic with "duplicate normalized declaration name".
8+
9+
This was fixed by making `shouldGenerateEqnThms` return `false` for matchers, since
10+
matcher equations are handled separately by `Lean.Meta.Match.MatchEqs`.
11+
-/
12+
13+
-- A theorem with a match expression in its type creates a matcher `bar.match_1`
14+
theorem bar : (match (0 : Nat) with | 0 => 0 | _ => 1) = 0 := by native_decide
15+
16+
-- getEqnsFor? on a matcher should return none (not panic)
17+
/-- info: eqns: none -/
18+
#guard_msgs in
19+
#eval do
20+
let eqns ← Lean.Meta.getEqnsFor? `bar.match_1
21+
IO.println s!"eqns: {eqns}"
22+
23+
-- try? should not panic when encountering matchers in the goal
24+
-- (it may fail to find suggestions, but should not panic)
25+
/--
26+
info: Try these:
27+
[apply] rfl
28+
[apply] simp
29+
[apply] simp only
30+
[apply] grind
31+
[apply] grind only
32+
[apply] simp_all
33+
-/
34+
#guard_msgs in
35+
theorem bar' : (match (0 : Nat) with | 0 => 0 | _ => 1) = 0 := by try?

0 commit comments

Comments
 (0)