lean4-htt/tests/elab/setOptionTermTactic.lean.out.expected
Kim Morrison e01cbf2b8f
feat: add structured TraceResult to TraceData (#12698)
This PR adds a `result? : Option TraceResult` field to `TraceData` and
populates it in `withTraceNode` and `withTraceNodeBefore`, so that
metaprograms walking trace trees can determine success/failure
structurally instead of string-matching on emoji.

`TraceResult` has three cases: `.success` (checkEmoji), `.failure`
(crossEmoji), and `.error` (bombEmoji, exception thrown). An
`ExceptToTraceResult` typeclass converts `Except` results to
`TraceResult` directly, with instances for `Bool` and `Option`.
`TraceResult.toEmoji` converts back to emoji for display. This replaces
the previous `ExceptToEmoji` typeclass — `TraceResult` is now the
primary representation rather than being derived from emoji strings.

`withTraceNodeBefore` (used by `isDefEq`) uses
`ExceptToTraceResult.toTraceResult` directly, correctly handling `Bool`
(`.ok false` = failure) and `Option` (`.ok none` = failure), with
`Except.error` mapping to `.error`.

For `withTraceNode`, `result?` defaults to `none`. Callers can pass
`mkResult?` to provide structured results; when set, the corresponding
emoji is auto-prepended to the message.

Motivated by mathlib's `#defeq_abuse` diagnostic tactic
(https://github.com/leanprover-community/mathlib4/pull/35750) which
currently string-matches on emoji to determine trace node outcomes. See
https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/backward.2EisDefEq.2ErespectTransparency

🤖 Prepared with Claude Code

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 02:42:57 +00:00

38 lines
1.6 KiB
Text

[Meta.synthInstance] 💥️ OfNat ?m 1
[Meta.synthInstance] ✅️ new goal OfNat ?m 1
[Meta.synthInstance.instances] #[@Lean.Grind.Semiring.ofNat, @One.toOfNat1, @Int16.instOfNat, @UInt64.instOfNat, @Rat.instOfNat, @Int8.instOfNat, @instOfNatFloat, @BitVec.instOfNat, Dyadic.instOfNat, @Int64.instOfNat, @instOfNat, @Id.instOfNat, @UInt16.instOfNat, instOfNatNat, @UInt32.instOfNat, @UInt8.instOfNat, @Fin.instOfNat, @ISize.instOfNat, @instOfNatFloat32, @Int32.instOfNat, @USize.instOfNat, @Lean.Grind.CommRing.OfCommSemiring.instOfNatQ]
[Meta.synthInstance.apply] 💥️ apply @Lean.Grind.CommRing.OfCommSemiring.instOfNatQ to OfNat ?m 1
[Meta.synthInstance.tryResolve] 💥️ OfNat ?m 1 ≟ OfNat (Lean.Grind.Ring.OfSemiring.Q ?m) ?m
[Meta.Tactic.simp.rewrite] Nat.add_succ:1000:
x + 1
==>
(x + 0).succ
[Meta.Tactic.simp.unify] Nat.add_succ:1000, failed to unify
?n + Nat.succ ?m
with
x + 0
[Meta.Tactic.simp.unify] Nat.add_succ:1000, failed to unify
?n + Nat.succ ?m
with
x + 0
[Meta.Tactic.simp.rewrite] unfold g, g ==> fun x => 0 + x.succ
[Meta.Tactic.simp.rewrite] Nat.add_succ:1000:
0 + x.succ
==>
(0 + x).succ
[Meta.Tactic.simp.unify] Nat.add_succ:1000, failed to unify
?n + Nat.succ ?m
with
0 + x
[Meta.Tactic.simp.unify] Nat.add_succ:1000, failed to unify
?n + Nat.succ ?m
with
0 + x
[Meta.Tactic.simp.unify] eq_self:1000, failed to unify
?a = ?a
with
(fun x => (x + 0).succ) = fun x => (0 + x).succ
[Meta.Tactic.simp.unify] eq_self:1000, failed to unify
?a = ?a
with
(fun x => (x + 0).succ) = fun x => (0 + x).succ