This PR ensures that if wrapInstance encounters an instance that cannot be reduced to a constructor, the wrapping definition is left at semireducible transparency to avoid leakage.
103 lines
2.3 KiB
Text
103 lines
2.3 KiB
Text
module
|
||
|
||
class C (α : Type) where
|
||
c : α → α
|
||
|
||
/-! Trivial data wrapper -/
|
||
|
||
axiom I : Type
|
||
instance : C I where
|
||
c x := x
|
||
|
||
def D := I
|
||
|
||
instance : C D := inferInstanceAs (C I)
|
||
|
||
-- We can still use it as an `inferInstance` synonym in the old mode
|
||
set_option backward.inferInstanceAs.wrap false in
|
||
/-- info: «inferInstanceAs» (C D) : C D -/
|
||
#guard_msgs in
|
||
#check inferInstanceAs (C D)
|
||
|
||
/--
|
||
info: @[implicit_reducible] private def instCD : C D :=
|
||
{ c := instCD._aux_1 }
|
||
-/
|
||
#guard_msgs in
|
||
#print instCD
|
||
/--
|
||
info: private def instCD._aux_1 : D → D :=
|
||
fun x => x
|
||
-/
|
||
#guard_msgs in
|
||
#print instCD._aux_1
|
||
|
||
/-! Irreducible instances are wrapped as is. -/
|
||
|
||
axiom I2 : Type
|
||
@[instance] opaque instCI2 : C I2 := { c := fun x => x }
|
||
def D2 := I2
|
||
|
||
instance : C D2 := inferInstanceAs (C I2)
|
||
/--
|
||
info: @[implicit_reducible] private def instCD2 : C D2 :=
|
||
instCD2._aux_1
|
||
-/
|
||
#guard_msgs in
|
||
#print instCD2
|
||
/--
|
||
info: private def instCD2._aux_1 : C D2 :=
|
||
instCI2
|
||
-/
|
||
#guard_msgs in
|
||
#print instCD2._aux_1
|
||
|
||
/-! Flattened inheritance test. -/
|
||
|
||
class Base (α : Type) where
|
||
b : α
|
||
|
||
class Foo (α : Type) extends Base α where
|
||
a : α
|
||
|
||
class Bar (α : Type) extends Base α where
|
||
c : α
|
||
|
||
class FooBar (α : Type) extends Foo α, Bar α
|
||
|
||
instance : FooBar Nat where
|
||
a := 0
|
||
b := 1
|
||
c := 2
|
||
|
||
def MyNat := Nat
|
||
deriving Foo, Bar, FooBar
|
||
|
||
theorem zou : instFooBarMyNat.toBar = instBarMyNat := by
|
||
with_reducible_and_instances rfl
|
||
|
||
/-! Non-constructor instances should be used as is. -/
|
||
|
||
@[macro_inline, implicit_reducible]
|
||
def dite' {α : Sort u} (c : Prop) [h : Decidable c] (t : c → α) (e : Not c → α) : α :=
|
||
h.casesOn e t
|
||
|
||
instance Nat.decLe' (n m : @& Nat) : Decidable (LE.le n m) :=
|
||
dite' (Eq (Nat.ble n m) true) (fun h => isTrue (Nat.le_of_ble_eq_true h)) (fun h => isFalse (Nat.not_le_of_not_ble_eq_true h))
|
||
|
||
#guard_msgs in
|
||
instance (x y : BitVec w) : Decidable (LE.le x y) :=
|
||
(inferInstance : Decidable (LE.le x.toNat y.toNat))
|
||
|
||
instance (x y : BitVec w) : Decidable (LE.le x y) :=
|
||
inferInstanceAs (Decidable (LE.le x.toNat y.toNat))
|
||
|
||
/-! Universes can be introduced by synth and need to be unified with the expected type properly. -/
|
||
|
||
structure MyStruct where
|
||
x : PUnit.{u + 1} := ⟨⟩
|
||
y : PUnit.{v + 1} := ⟨⟩
|
||
|
||
instance : Zero MyStruct.{u, max u v} := ⟨{}⟩
|
||
|
||
instance : Zero MyStruct.{u, max u v} := inferInstanceAs <| Zero MyStruct.{u, max u v}
|