feat: improve infer binder type failure message and range (#8263)
This PR improves the message and range of infer binder type failures. --------- Co-authored-by: Joseph Rotella <7482866+jrr6@users.noreply.github.com>
This commit is contained in:
parent
c0079fd9dd
commit
caf815b009
16 changed files with 120 additions and 60 deletions
|
|
@ -178,9 +178,13 @@ private def toBinderViews (stx : Syntax) : TermElabM (Array BinderView) := do
|
|||
else
|
||||
throwUnsupportedSyntax
|
||||
|
||||
private def registerFailedToInferBinderTypeInfo (type : Expr) (ref : Syntax) : TermElabM Unit := do
|
||||
registerCustomErrorIfMVar type ref "failed to infer binder type"
|
||||
registerLevelMVarErrorExprInfo type ref m!"failed to infer universe levels in binder type"
|
||||
private def registerFailedToInferBinderTypeInfo (type : Expr) (view : BinderView) : TermElabM Unit := do
|
||||
let msg := if view.id.getId.hasMacroScopes then
|
||||
m!"binder type"
|
||||
else
|
||||
m!"type of binder `{view.id.getId}`"
|
||||
registerCustomErrorIfMVar type view.ref m!"Failed to infer {msg}"
|
||||
registerLevelMVarErrorExprInfo type view.ref m!"Failed to infer universe levels in {msg}"
|
||||
|
||||
def addLocalVarInfo (stx : Syntax) (fvar : Expr) : TermElabM Unit :=
|
||||
addTermInfo' (isBinder := true) stx fvar
|
||||
|
|
@ -212,7 +216,7 @@ private partial def elabBinderViews (binderViews : Array BinderView) (fvars : Ar
|
|||
let binderView := binderViews[i]
|
||||
ensureAtomicBinderName binderView
|
||||
let type ← elabType binderView.type
|
||||
registerFailedToInferBinderTypeInfo type binderView.type
|
||||
registerFailedToInferBinderTypeInfo type binderView
|
||||
if binderView.bi.isInstImplicit && checkBinderAnnotations.get (← getOptions) then
|
||||
unless (← isClass? type).isSome do
|
||||
throwErrorAt binderView.type (m!"invalid binder annotation, type is not a class instance{indentExpr type}" ++ .note "Use the command `set_option checkBinderAnnotations false` to disable the check")
|
||||
|
|
@ -423,7 +427,7 @@ private partial def elabFunBinderViews (binderViews : Array BinderView) (i : Nat
|
|||
ensureAtomicBinderName binderView
|
||||
withRef binderView.type <| withLCtx s.lctx s.localInsts do
|
||||
let type ← elabType binderView.type
|
||||
registerFailedToInferBinderTypeInfo type binderView.type
|
||||
registerFailedToInferBinderTypeInfo type binderView
|
||||
let fvarId ← mkFreshFVarId
|
||||
let fvar := mkFVar fvarId
|
||||
let s := { s with fvars := s.fvars.push fvar }
|
||||
|
|
|
|||
|
|
@ -124,15 +124,21 @@ private def check (prevHeaders : Array DefViewElabHeader) (newHeader : DefViewEl
|
|||
else
|
||||
pure ()
|
||||
|
||||
private def registerFailedToInferDefTypeInfo (type : Expr) (ref : Syntax) (view : DefView) : TermElabM Unit :=
|
||||
let msg := if view.kind.isExample then
|
||||
m!"failed to infer type of example"
|
||||
else if view.kind matches .instance then
|
||||
-- TODO: instances are sometime named. We should probably include the name if available.
|
||||
m!"failed to infer type of instance"
|
||||
else
|
||||
m!"failed to infer type of `{view.declId}`"
|
||||
registerCustomErrorIfMVar type ref msg
|
||||
private def registerFailedToInferDefTypeInfo (type : Expr) (view : DefView) :
|
||||
TermElabM Unit :=
|
||||
let ref := view.type?.getD <| match view.kind with
|
||||
-- Use def name (or keyword if anonymous) as fallback location
|
||||
| .example => view.ref[0]
|
||||
| .instance => view.ref[1]
|
||||
| _ => view.declId
|
||||
let msg := match view.kind with
|
||||
| .example => m!"example"
|
||||
| .instance => if view.declId.getHeadInfo matches .original .. then
|
||||
m!"instance `{view.declId}`"
|
||||
else m!"instance"
|
||||
| .theorem => m!"theorem `{view.declId}`"
|
||||
| _ => m!"definition `{view.declId}`"
|
||||
registerCustomErrorIfMVar type ref m!"Failed to infer type of {msg}"
|
||||
|
||||
/--
|
||||
Return `some [b, c]` if the given `views` are representing a declaration of the form
|
||||
|
|
@ -233,13 +239,13 @@ private def elabHeaders (views : Array DefView) (expandedDeclIds : Array ExpandD
|
|||
let mut type ← match view.type? with
|
||||
| some typeStx =>
|
||||
let type ← elabType typeStx
|
||||
registerFailedToInferDefTypeInfo type typeStx view
|
||||
registerFailedToInferDefTypeInfo type view
|
||||
pure type
|
||||
| none =>
|
||||
let hole := mkHole refForElabFunType
|
||||
let type ← elabType hole
|
||||
trace[Elab.definition] ">> type: {type}\n{type.mvarId!}"
|
||||
registerFailedToInferDefTypeInfo type refForElabFunType view
|
||||
registerFailedToInferDefTypeInfo type view
|
||||
pure type
|
||||
Term.synthesizeSyntheticMVarsNoPostponing
|
||||
if view.isInstance then
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
331.lean:6:13-6:14: error: failed to infer binder type
|
||||
331.lean:6:9-6:10: error: Failed to infer type of binder `x`
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
331.lean:7:13-7:14: error: failed to infer binder type
|
||||
331.lean:7:9-7:10: error: Failed to infer type of binder `x`
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
autoImplicitCtorParamIssue.lean:1:9-1:10: error: failed to infer binder type
|
||||
autoImplicitCtorParamIssue.lean:4:9-4:10: error: failed to infer binder type
|
||||
autoImplicitCtorParamIssue.lean:7:7-7:8: error: failed to infer binder type
|
||||
autoImplicitCtorParamIssue.lean:1:9-1:10: error: Failed to infer type of binder `x`
|
||||
autoImplicitCtorParamIssue.lean:4:9-4:10: error: Failed to infer type of binder `x`
|
||||
autoImplicitCtorParamIssue.lean:7:7-7:8: error: Failed to infer type of binder `x`
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ holeErrors.lean:3:14-3:20: error: don't know how to synthesize implicit argument
|
|||
@id ?m
|
||||
context:
|
||||
⊢ Sort u
|
||||
holeErrors.lean:3:11-3:20: error: failed to infer type of `f1.{u}`
|
||||
holeErrors.lean:5:9-5:10: error: failed to infer type of `f2`
|
||||
holeErrors.lean:3:4-3:10: error: Failed to infer type of definition `f1.{u}`
|
||||
holeErrors.lean:5:9-5:10: error: Failed to infer type of definition `f2`
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
holeErrors.lean:8:9-8:15: error: don't know how to synthesize implicit argument 'α'
|
||||
|
|
@ -11,13 +11,13 @@ holeErrors.lean:8:9-8:15: error: don't know how to synthesize implicit argument
|
|||
context:
|
||||
⊢ Sort u
|
||||
holeErrors.lean:8:4-8:5: error: failed to infer 'let' declaration type
|
||||
holeErrors.lean:7:11-9:1: error: failed to infer type of `f3.{u}`
|
||||
holeErrors.lean:11:11-11:15: error: failed to infer type of `f4`
|
||||
holeErrors.lean:11:8-11:9: error: failed to infer binder type
|
||||
holeErrors.lean:13:15-13:19: error: failed to infer type of `f5`
|
||||
holeErrors.lean:13:12-13:13: error: failed to infer binder type
|
||||
holeErrors.lean:16:4-16:5: error: failed to infer binder type
|
||||
holeErrors.lean:15:7-16:10: error: failed to infer type of `f6`
|
||||
holeErrors.lean:7:4-7:10: error: Failed to infer type of definition `f3.{u}`
|
||||
holeErrors.lean:11:4-11:6: error: Failed to infer type of definition `f4`
|
||||
holeErrors.lean:11:8-11:9: error: Failed to infer type of binder `x`
|
||||
holeErrors.lean:13:4-13:6: error: Failed to infer type of definition `f5`
|
||||
holeErrors.lean:13:8-13:9: error: Failed to infer type of binder `x`
|
||||
holeErrors.lean:16:4-16:5: error: Failed to infer type of binder `x`
|
||||
holeErrors.lean:15:4-15:6: error: Failed to infer type of definition `f6`
|
||||
holeErrors.lean:19:13-19:19: error: don't know how to synthesize implicit argument 'α'
|
||||
@id ?m
|
||||
context:
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ holes.lean:10:9-10:12: error: don't know how to synthesize implicit argument 'β
|
|||
context:
|
||||
x : Nat
|
||||
⊢ Type
|
||||
holes.lean:13:10-13:11: error: failed to infer binder type
|
||||
holes.lean:15:16-15:17: error: failed to infer binder type
|
||||
holes.lean:13:10-13:11: error: Failed to infer type of binder `β`
|
||||
holes.lean:15:12-15:13: error: Failed to infer type of binder `β`
|
||||
holes.lean:19:0-19:3: error: don't know how to synthesize implicit argument 'β'
|
||||
@f Nat (?m a) a
|
||||
context:
|
||||
a : Nat
|
||||
f : {α : Type} → {β : ?m a} → α → α := ⋯
|
||||
⊢ ?m a
|
||||
holes.lean:18:9-18:10: error: failed to infer binder type
|
||||
holes.lean:21:25-22:4: error: failed to infer type of `f7`
|
||||
holes.lean:18:9-18:10: error: Failed to infer type of binder `β`
|
||||
holes.lean:21:12-21:14: error: Failed to infer type of definition `f7`
|
||||
holes.lean:25:8-25:11: error: failed to infer 'let rec' declaration type
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
implicitTypePos.lean:1:8-1:9: error: failed to infer binder type
|
||||
implicitTypePos.lean:1:6-1:7: error: failed to infer binder type
|
||||
implicitTypePos.lean:3:9-3:10: error: failed to infer binder type
|
||||
implicitTypePos.lean:5:9-5:10: error: failed to infer binder type
|
||||
implicitTypePos.lean:7:10-7:11: error: failed to infer binder type
|
||||
implicitTypePos.lean:1:8-1:9: error: Failed to infer type of binder `y`
|
||||
implicitTypePos.lean:1:6-1:7: error: Failed to infer type of binder `x`
|
||||
implicitTypePos.lean:3:9-3:10: error: Failed to infer type of binder `y`
|
||||
implicitTypePos.lean:5:9-5:10: error: Failed to infer type of binder `β`
|
||||
implicitTypePos.lean:7:10-7:11: error: Failed to infer type of binder `β`
|
||||
|
|
|
|||
|
|
@ -14,12 +14,13 @@
|
|||
{"source": "Lean 4",
|
||||
"severity": 1,
|
||||
"range":
|
||||
{"start": {"line": 21, "character": 26},
|
||||
"end": {"line": 21, "character": 31}},
|
||||
"message": "failed to infer universe levels in binder type\n PUnit.{_}",
|
||||
{"start": {"line": 21, "character": 22},
|
||||
"end": {"line": 21, "character": 23}},
|
||||
"message":
|
||||
"Failed to infer universe levels in type of binder `x`\n PUnit.{_}",
|
||||
"fullRange":
|
||||
{"start": {"line": 21, "character": 26},
|
||||
"end": {"line": 21, "character": 31}}},
|
||||
{"start": {"line": 21, "character": 22},
|
||||
"end": {"line": 21, "character": 23}}},
|
||||
{"source": "Lean 4",
|
||||
"severity": 1,
|
||||
"range":
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
multiConstantError.lean:1:11-1:12: error: failed to infer binder type
|
||||
multiConstantError.lean:1:11-1:12: error: Failed to infer type of binder `c`
|
||||
|
||||
Note: Recall that you cannot declare multiple constants in a single declaration. The identifier(s) `b`, `c` are being interpreted as parameters `(b : _)`, `(c : _)`.
|
||||
multiConstantError.lean:1:9-1:10: error: failed to infer binder type
|
||||
multiConstantError.lean:1:9-1:10: error: Failed to infer type of binder `b`
|
||||
|
||||
Note: Recall that you cannot declare multiple constants in a single declaration. The identifier(s) `b`, `c` are being interpreted as parameters `(b : _)`, `(c : _)`.
|
||||
multiConstantError.lean:3:9-3:10: error: failed to infer binder type
|
||||
multiConstantError.lean:3:9-3:10: error: Failed to infer type of binder `α`
|
||||
|
||||
Note: Recall that you cannot declare multiple constants in a single declaration. The identifier(s) `α`, `β` are being interpreted as parameters `(α : _)`, `(β : _)`.
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ Test: Works for `fun` binders.
|
|||
-/
|
||||
|
||||
/--
|
||||
error: failed to infer universe levels in binder type
|
||||
error: Failed to infer universe levels in type of binder `x`
|
||||
PUnit.{_}
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ A : Nat
|
|||
#guard_msgs in
|
||||
variable (A : Nat) (B : by skip)
|
||||
|
||||
/-- error: failed to infer type of `foo` -/
|
||||
/-- error: Failed to infer type of definition `foo` -/
|
||||
#guard_msgs in
|
||||
def foo :=
|
||||
A = B
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ error: don't know how to synthesize implicit argument 'α'
|
|||
context:
|
||||
⊢ Type
|
||||
---
|
||||
error: failed to infer type of example
|
||||
error: Failed to infer type of example
|
||||
-/
|
||||
#guard_msgs in
|
||||
example :=
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ error: don't know how to synthesize implicit argument 'ρ'
|
|||
context:
|
||||
⊢ Type _
|
||||
---
|
||||
error: failed to infer binder type
|
||||
error: Failed to infer type of binder `x`
|
||||
---
|
||||
error: don't know how to synthesize implicit argument 'α'
|
||||
@List.nil ?_
|
||||
|
|
@ -63,9 +63,9 @@ error: don't know how to synthesize implicit argument 'ρ'
|
|||
context:
|
||||
⊢ Type _
|
||||
---
|
||||
error: failed to infer binder type
|
||||
error: Failed to infer type of binder `h`
|
||||
---
|
||||
error: failed to infer binder type
|
||||
error: Failed to infer type of binder `x`
|
||||
---
|
||||
error: don't know how to synthesize implicit argument 'α'
|
||||
@List.nil ?_
|
||||
|
|
|
|||
38
tests/lean/run/inferTypeFailure.lean
Normal file
38
tests/lean/run/inferTypeFailure.lean
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/-! Check messages of binder type inference failures. -/
|
||||
|
||||
/--
|
||||
error: Failed to infer type of binder `y`
|
||||
---
|
||||
error: Failed to infer type of binder `x`
|
||||
---
|
||||
error: Failed to infer type of definition `l1`
|
||||
-/
|
||||
#guard_msgs in
|
||||
def l1 := fun x y => x
|
||||
|
||||
/--
|
||||
error: Failed to infer binder type
|
||||
---
|
||||
error: Failed to infer type of definition `l2`
|
||||
-/
|
||||
#guard_msgs in
|
||||
def l2 := fun _ => 0
|
||||
|
||||
/--
|
||||
error: Failed to infer type of theorem `t`
|
||||
|
||||
Note: All holes (e.g., `_`) in the header of a theorem are resolved before the proof is processed; information from the proof cannot be used to infer what these values should be
|
||||
---
|
||||
error: type of theorem 't' is not a proposition
|
||||
?m.65
|
||||
-/
|
||||
#guard_msgs in
|
||||
theorem t : _ := _
|
||||
|
||||
/--
|
||||
error: Failed to infer type of example
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
-/
|
||||
#guard_msgs in
|
||||
example : _ := _
|
||||
|
|
@ -118,7 +118,7 @@ end Ex4
|
|||
Here, `(α β)` is not an override since `β` is not an existing parameter, so `α` is treated as a binder.
|
||||
-/
|
||||
namespace Ex5
|
||||
/-- error: failed to infer binder type -/
|
||||
/-- error: Failed to infer type of binder `α` -/
|
||||
#guard_msgs in
|
||||
class C (α : Type) where
|
||||
f (α β) : β
|
||||
|
|
@ -128,7 +128,7 @@ end Ex5
|
|||
Here, `(α β)` is not an override since `β` is a field.
|
||||
-/
|
||||
namespace Ex6
|
||||
/-- error: failed to infer binder type -/
|
||||
/-- error: Failed to infer type of binder `α` -/
|
||||
#guard_msgs in
|
||||
class C (α : Type) where
|
||||
β : Type
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
set_option pp.mvars false
|
||||
|
||||
/--
|
||||
error: failed to infer type of `foo`
|
||||
error: Failed to infer type of theorem `foo`
|
||||
|
||||
Note: All holes (e.g., `_`) in the header of a theorem are resolved before the proof is processed; information from the proof cannot be used to infer what these values should be
|
||||
---
|
||||
error: type of theorem 'foo' is not a proposition
|
||||
?m.2
|
||||
?_
|
||||
-/
|
||||
#guard_msgs (error) in
|
||||
theorem foo : _ :=
|
||||
sorry
|
||||
|
||||
/--
|
||||
error: failed to infer type of example
|
||||
error: Failed to infer type of example
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
-/
|
||||
|
|
@ -20,7 +22,7 @@ example : _ :=
|
|||
sorry
|
||||
|
||||
/--
|
||||
error: failed to infer type of `boo`
|
||||
error: Failed to infer type of definition `boo`
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
-/
|
||||
|
|
@ -29,10 +31,19 @@ def boo : _ :=
|
|||
sorry
|
||||
|
||||
/--
|
||||
error: failed to infer type of instance
|
||||
error: Failed to infer type of instance `boo`
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
-/
|
||||
#guard_msgs (error) in
|
||||
instance boo : _ :=
|
||||
sorry
|
||||
|
||||
/--
|
||||
error: Failed to infer type of instance
|
||||
|
||||
Note: When the resulting type of a declaration is explicitly provided, all holes (e.g., `_`) in the header are resolved before the declaration body is processed
|
||||
-/
|
||||
#guard_msgs (error) in
|
||||
instance : _ :=
|
||||
sorry
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue