Skip to content

Commit 49f216b

Browse files
committed
fix: reuse the instances of a non-exposed definition in inferInstanceAs
This PR makes `inferInstanceAs` reuse the existing instances of a non-exposed definition. This is done by checking the reusability of an instance in the private scope, as neither the auxiliary definitions being generated nor the ones in the existing instance are exposed in this case. Closes #14470.
1 parent b80e849 commit 49f216b

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

src/Lean/Meta/WrapInstance.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ where go (inst expectedType : Expr) (isEta : Bool) : MetaM (Option Expr) := do
233233
try
234234
if let .some new ← trySynthInstance argExpectedType then
235235
-- ignore instances from non-defeq diamonds
236-
if (← withDefault <| isDefEq new arg) then
236+
if (← withoutExporting (when := !exposeAux) <| withDefault <| isDefEq new arg) then
237237
trace[Meta.wrapInstance] "using existing instance {new}"
238238
mvarId.assign new
239239
isEta := false
@@ -264,7 +264,7 @@ where go (inst expectedType : Expr) (isEta : Bool) : MetaM (Option Expr) := do
264264
if let .some existingBaseClassInst ← trySynthInstance baseClassType then
265265
let proj ← mkProjection existingBaseClassInst fieldInfo.fieldName
266266
-- ignore instances from non-defeq diamonds
267-
if (← withDefault <| isDefEq proj arg) then
267+
if (← withoutExporting (when := !exposeAux) <| withDefault <| isDefEq proj arg) then
268268
trace[Meta.wrapInstance] "using projection of existing instance `{existingBaseClassInst}`"
269269
mvarId.assign proj
270270
continue

tests/elab/inferInstanceAs.lean

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module
22

3+
public import Lean
4+
35
class C (α : Type) where
46
c : α → α
57

@@ -180,4 +182,42 @@ Nat.zero
180182
#guard_msgs in
181183
#print instInhabitedIsExposed._aux_1
182184

185+
/-! Test the reuse of instances of `NotExposed` (#14470). -/
186+
187+
class Base' (α : Type) where
188+
b : α
189+
190+
class Foo' (α : Type) extends Base' α where
191+
a : α
192+
193+
class Bar' (α : Type) extends Base' α where
194+
c : α
195+
196+
class FooBar' (α : Type) extends Foo' α, Bar' α
197+
198+
instance : FooBar' Nat where
199+
a := 0
200+
b := 1
201+
c := 2
202+
203+
namespace NotExposed
204+
205+
noncomputable instance : Foo' NotExposed := inferInstanceAs (Foo' Nat)
206+
noncomputable instance : Bar' NotExposed := inferInstanceAs (Bar' Nat)
207+
noncomputable instance : FooBar' NotExposed := inferInstanceAs (FooBar' Nat)
208+
209+
open Lean Elab Tactic in
210+
elab "with_exporting" tac:tacticSeq : tactic =>
211+
Lean.withExporting (isExporting := true) (Lean.Elab.Tactic.evalTactic tac)
212+
213+
-- The instances must be reused for these defeqs to hold publicly.
214+
215+
example : instFooBar'.toFoo' = instFoo' := by
216+
with_exporting with_reducible_and_instances rfl
217+
218+
example : instFooBar'.toBar' = instBar' := by
219+
with_exporting with_reducible_and_instances rfl
220+
221+
end NotExposed
222+
183223
end

0 commit comments

Comments
 (0)