fix: fixes #602
This commit is contained in:
parent
789c7073dc
commit
bcfc927799
4 changed files with 71 additions and 18 deletions
|
|
@ -157,11 +157,18 @@ structure SavedState where
|
|||
deriving Inhabited
|
||||
|
||||
structure Context where
|
||||
config : Config := {}
|
||||
lctx : LocalContext := {}
|
||||
localInstances : LocalInstances := #[]
|
||||
config : Config := {}
|
||||
lctx : LocalContext := {}
|
||||
localInstances : LocalInstances := #[]
|
||||
/-- Not `none` when inside of an `isDefEq` test. See `PostponedEntry`. -/
|
||||
defEqCtx? : Option DefEqContext := none
|
||||
defEqCtx? : Option DefEqContext := none
|
||||
/--
|
||||
Track the number of nested `synthPending` invocations. Nested invocations can happen
|
||||
when the type class resolution invokes `synthPending`.
|
||||
|
||||
Remark: in the current implementation, `synthPending` fails if `synthPendingDepth > 0`.
|
||||
We will add a configuration option if necessary. -/
|
||||
synthPendingDepth : Nat := 0
|
||||
|
||||
abbrev MetaM := ReaderT Context $ StateRefT State CoreM
|
||||
|
||||
|
|
|
|||
|
|
@ -1365,7 +1365,8 @@ end
|
|||
failK
|
||||
| none => failK
|
||||
|
||||
private def isDefEqOnFailure (t s : Expr) : MetaM Bool :=
|
||||
private def isDefEqOnFailure (t s : Expr) : MetaM Bool := do
|
||||
trace[Meta.isDefEq.onFailure] "{t} =?= {s}"
|
||||
unstuckMVar t (fun t => Meta.isExprDefEqAux t s) <|
|
||||
unstuckMVar s (fun s => Meta.isExprDefEqAux t s) <|
|
||||
tryUnificationHints t s <||> tryUnificationHints s t
|
||||
|
|
|
|||
|
|
@ -647,20 +647,32 @@ def synthInstance (type : Expr) (maxResultSize? : Option Nat := none) : MetaM Ex
|
|||
private def synthPendingImp (mvarId : MVarId) : MetaM Bool := withIncRecDepth <| withMVarContext mvarId do
|
||||
let mvarDecl ← getMVarDecl mvarId
|
||||
match mvarDecl.kind with
|
||||
| MetavarKind.synthetic =>
|
||||
| MetavarKind.syntheticOpaque =>
|
||||
return false
|
||||
| _ =>
|
||||
/- Check whether the type of the given metavariable is a class or not. If yes, then try to synthesize
|
||||
it using type class resolution. We only do it for `synthetic` and `natural` metavariables. -/
|
||||
match (← isClass? mvarDecl.type) with
|
||||
| none => pure false
|
||||
| some _ => do
|
||||
let val? ← catchInternalId isDefEqStuckExceptionId (synthInstance? mvarDecl.type (maxResultSize? := none)) (fun _ => pure none)
|
||||
match val? with
|
||||
| none => pure false
|
||||
| some val =>
|
||||
if (← isExprMVarAssigned mvarId) then
|
||||
pure false
|
||||
else
|
||||
assignExprMVar mvarId val
|
||||
pure true
|
||||
| _ => pure false
|
||||
| none =>
|
||||
return false
|
||||
| some _ =>
|
||||
/- TODO: use a configuration option instead of the hard-coded limit `1`. -/
|
||||
if (← read).synthPendingDepth > 1 then
|
||||
trace[Meta.synthPending] "too many nested synthPending invocations"
|
||||
return false
|
||||
else
|
||||
withReader (fun ctx => { ctx with synthPendingDepth := ctx.synthPendingDepth + 1 }) do
|
||||
trace[Meta.synthPending] "synthPending {mkMVar mvarId}"
|
||||
let val? ← catchInternalId isDefEqStuckExceptionId (synthInstance? mvarDecl.type (maxResultSize? := none)) (fun _ => pure none)
|
||||
match val? with
|
||||
| none =>
|
||||
return false
|
||||
| some val =>
|
||||
if (← isExprMVarAssigned mvarId) then
|
||||
return false
|
||||
else
|
||||
assignExprMVar mvarId val
|
||||
return true
|
||||
|
||||
builtin_initialize
|
||||
registerTraceClass `Meta.synthInstance
|
||||
|
|
@ -669,5 +681,6 @@ builtin_initialize
|
|||
registerTraceClass `Meta.synthInstance.tryResolve
|
||||
registerTraceClass `Meta.synthInstance.resume
|
||||
registerTraceClass `Meta.synthInstance.generate
|
||||
registerTraceClass `Meta.synthPending
|
||||
|
||||
end Lean.Meta
|
||||
|
|
|
|||
32
tests/lean/run/602.lean
Normal file
32
tests/lean/run/602.lean
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
class Semiring (α : Type) where add : α → α → α
|
||||
class Ring (α : Type) where add : α → α → α
|
||||
|
||||
class AddCommMonoid (α : Type) where
|
||||
class AddCommGroup (α : Type) where
|
||||
|
||||
class Module (α β : Type) [Semiring α] [AddCommMonoid β] where
|
||||
|
||||
class NormedField (α : Type) where
|
||||
add : α → α → α
|
||||
add_comm : ∀ (x y : α), @Add.add _ ⟨add⟩ x y = @Add.add _ ⟨add⟩ y x
|
||||
|
||||
class SemiNormedGroup (α : Type) where
|
||||
class SemiNormedSpace (α β : Type) [NormedField α] [SemiNormedGroup β] where
|
||||
|
||||
instance SemiNormedGroup.toAddCommMonoid [SemiNormedGroup α] : AddCommMonoid α := {}
|
||||
instance Ring.toSemiring [instR : Ring α] : Semiring α := { add := instR.add }
|
||||
instance NormedField.toRing [instNF : NormedField α] : Ring α := { add := instNF.add }
|
||||
|
||||
|
||||
-- @[inferTCGoalsRL]
|
||||
instance SemiNormedSpace.toModule [NormedField α] [SemiNormedGroup β] [SemiNormedSpace α β] : Module α β := {}
|
||||
|
||||
constant R : Type := Unit
|
||||
constant foo (a b : R) : R := a
|
||||
|
||||
instance R.NormedField : NormedField R := { add := foo, add_comm := sorry }
|
||||
instance R.Ring : Ring R := { add := foo }
|
||||
|
||||
variable {E : Type} [instSNG : SemiNormedGroup E] [instSNS : SemiNormedSpace R E]
|
||||
|
||||
#synth Module R E
|
||||
Loading…
Add table
Reference in a new issue