lean4-htt/tests/lean/run/grind_nested_mdata.lean
Kim Morrison 6a900dc9d6
fix: strip nested mdata in grind preprocessing (#11412)
This PR fixes an issue where `grind` would fail after multiple
`norm_cast`
calls with the error "unexpected metadata found during internalization".

The `norm_cast` tactic adds mdata nodes to expressions, and when called
multiple times it creates nested mdata. The `eraseIrrelevantMData`
preprocessing function was using `.continue e` when stripping mdata,
which causes `Core.transform` to reconstruct the mdata node around the
visited children. By changing to `.visit e`, the inner expression is
passed back to `pre` for another round of processing, allowing all
nested mdata layers to be stripped.

Closes #11411

🤖 Prepared with Claude Code

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-28 04:36:26 +00:00

59 lines
1.8 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-!
# Test that `grind` handles nested mdata from multiple `norm_cast` calls
This is a regression test for https://github.com/leanprover/lean4/issues/11411
The issue was that `norm_cast` adds mdata nodes to expressions, and when called
multiple times it creates nested mdata. The `grind` preprocessing step
`eraseIrrelevantMData` was only stripping one layer of mdata instead of all layers.
-/
-- Minimal WithTop definition
def WithTop (α : Type u) := Option α
namespace WithTop
variable {α : Type u}
@[coe] def some : α → WithTop α := Option.some
instance : Coe α (WithTop α) := ⟨some⟩
instance : NatCast (WithTop Nat) where
natCast n := some n
end WithTop
-- AtLeastTwo infrastructure (from Mathlib.Data.Nat.Init)
class Nat.AtLeastTwo (n : Nat) : Prop where
prop : n ≥ 2
instance Nat.instAtLeastTwo : Nat.AtLeastTwo (n + 2) where
prop := Nat.le_add_left 2 n
-- OfNat instance for numeric literals ≥ 2 (from Mathlib.Data.Nat.Cast.Defs)
instance instOfNatAtLeastTwo {R : Type u} [NatCast R] (n : Nat) [Nat.AtLeastTwo n] : OfNat R n where
ofNat := n
-- The key norm_cast lemma (from Mathlib.Data.Nat.Cast.Defs)
@[simp, norm_cast]
theorem Nat.cast_ofNat {R : Type u} {n : Nat} [NatCast R] [Nat.AtLeastTwo n] :
(Nat.cast (no_index (OfNat.ofNat n)) : R) = no_index (OfNat.ofNat n) := rfl
variable {Foo : WithTop Nat → Prop} {Bar : Prop}
-- Works: grind without norm_cast
example (foo_imp_bar : ∀ x, Foo x → Bar) (h : Foo 2) : Bar := by
grind
-- Works: grind after one norm_cast
example (foo_imp_bar : ∀ x, Foo x → Bar) (h : Foo 2) : Bar := by
norm_cast at h
grind
-- Previously failed: grind after two norm_casts
-- This used to fail with "unexpected metadata found during internalization"
example (foo_imp_bar : ∀ x, Foo x → Bar) (h : Foo 2) : Bar := by
norm_cast at h
norm_cast at h
grind