lean4-htt/tests/lean/run/mightBeDerivable.lean
Robert J. Simmons 429734c02f
feat: suggest deriving an instance when the instance might be derivable (#11346)
This PR modifies the error message for type synthesis failure for the
case where the type class in question is potentially derivable using a
`deriving` command. Also changes the error explanation for type class
instance synthesis failure with an illustration of this pattern.

## Example

```lean4
inductive MyColor where
  | chartreuse | sienna | thistle
def forceColor (oc : Option MyColor) :=
  oc.get!
```

Before this PR, this gives the potentially confusing impression that
Lean may have decided that `MyColor` is _not_ inhabited — people used to
Rust may be especially inclined towards this confusion.
```
failed to synthesize instance of type class
  Inhabited MyColor

Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command.
```

After this PR, a targeted hint suggests precisely the command that will
fix the issue:
```
error: failed to synthesize instance of type class
  Inhabited MyColor

Hint: Adding the command `deriving instance Inhabited for MyColor` may allow Lean to derive the missing instance.
```
2025-12-01 14:28:15 +00:00

96 lines
2.8 KiB
Text

import Lean
open Lean
inductive MyColor where
| chartreuse | sienna | thistle
/--
error: failed to synthesize instance of type class
Inhabited MyColor
Hint: Adding the command `deriving instance Inhabited for MyColor` may allow Lean to derive the missing instance.
-/
#guard_msgs in
def forceColor (oc : Option MyColor) :=
oc.get!
/--
error: failed to synthesize instance of type class
ToJson MyColor
Hint: Adding the command `deriving instance Lean.ToJson for MyColor` may allow Lean to derive the missing instance.
-/
#guard_msgs in
def jsonMaybeColor (oc : MyColor) :=
ToJson.toJson oc
/--
error: failed to synthesize instance of type class
ToJson MyColor
Hint: Adding the command `deriving instance Lean.ToJson for MyColor` may allow Lean to derive the missing instance.
---
error: failed to synthesize instance of type class
ToExpr MyColor
Hint: Adding the command `deriving instance Lean.ToExpr for MyColor` may allow Lean to derive the missing instance.
---
error: No deriving handlers have been implemented for class `ToString`
-/
#guard_msgs in
inductive MyList where
| nil : MyList
| cons : MyColor → MyList
deriving ToJson, ToExpr, ToString, Nonempty
-- It would be very cool if this case could give us "maybe derive ToJson MyColor", but that's more sophisticated than we can presently manage
/--
error: failed to synthesize instance of type class
ToJson (Option MyColor)
Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command.
-/
#guard_msgs in
def jsonColor (oc : Option MyColor) :=
ToJson.toJson oc
-- It would be very cool if this case could give us "maybe derive DecidableEq MyColor"
/--
error: failed to synthesize instance of type class
Decidable (oc = some MyColor.thistle)
Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command.
-/
#guard_msgs in
def checkColor (oc : Option MyColor) :=
if oc = .some .thistle then 1 else 2
inductive MyTree where
| nil : MyTree
| cons : MyColor → MyTree → MyTree
-- The suggestion here will fail, it would be super awesome if we gave the full recommendation,
-- but each hint makes progress
/--
error: failed to synthesize instance of type class
ToJson MyTree
Hint: Adding the command `deriving instance Lean.ToJson for MyTree` may allow Lean to derive the missing instance.
-/
#guard_msgs in
def jsonListColor (oc : MyTree) :=
ToJson.toJson oc
/--
error: failed to synthesize instance of type class
ToJson MyColor
Hint: Adding the command `deriving instance Lean.ToJson for MyColor` may allow Lean to derive the missing instance.
-/
#guard_msgs in
deriving instance Lean.ToJson for MyTree
deriving instance Lean.ToJson for MyColor
deriving instance Lean.ToJson for MyTree