lean4-htt/tests/elab/trace_synth.lean
Kim Morrison 235b0eb987
feat: add Meta.synthInstance.apply trace class (#12699)
This PR gives the `generate` function's "apply @Foo to Goal" trace nodes
their own trace sub-class `Meta.synthInstance.apply` instead of sharing
the parent `Meta.synthInstance` class.

This allows metaprograms that walk synthesis traces to distinguish
instance application attempts from other synthesis nodes by checking
`td.cls` rather than string-matching on the header text.

The new class is registered with `inherited := true`, so `set_option
trace.Meta.synthInstance true` continues to show these nodes.

Motivated by mathlib's `#defeq_abuse` diagnostic tactic
(https://github.com/leanprover-community/mathlib4/pull/35750) which
currently checks `headerStr.contains "apply"` to identify these nodes.
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-01 07:06:56 +00:00

52 lines
1.5 KiB
Text

class Foo (s : String) : Type where
instance : Foo "one" where
instance [Foo "three"] : Foo "two" where
def f (s : String) [Foo s] := ()
/-- info: () -/
#guard_msgs in
#eval f "one"
/--
error: failed to synthesize instance of type class
Foo "two"
Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command.
-/
#guard_msgs in
#eval f "two"
/--
error: failed to synthesize instance of type class
Foo "two"
---
trace: [Meta.synthInstance] ❌️ Foo "two"
[Meta.synthInstance] new goal Foo "two"
[Meta.synthInstance.instances] #[@instFoo_1]
[Meta.synthInstance.apply] ✅️ apply @instFoo_1 to Foo "two"
[Meta.synthInstance.tryResolve] ✅️ Foo "two" ≟ Foo "two"
[Meta.synthInstance] no instances for Foo "three"
[Meta.synthInstance.instances] #[]
[Meta.synthInstance] result <not-available>
[Meta.synthInstance] ❌️ Foo "two"
[Meta.synthInstance] result <not-available> (cached)
-/
#guard_msgs in
set_option trace.Meta.synthInstance true in
#eval f "two"
/--
error: failed to synthesize instance of type class
Foo "three"
---
trace: [Meta.synthInstance] ❌️ Foo "three"
[Meta.synthInstance] no instances for Foo "three"
[Meta.synthInstance.instances] #[]
[Meta.synthInstance] result <not-available>
[Meta.synthInstance] ❌️ Foo "three"
[Meta.synthInstance] result <not-available> (cached)
-/
#guard_msgs in
set_option trace.Meta.synthInstance true in
#eval f "three"