lean4-htt/tests/elab/inferInstanceAs.lean
Sebastian Ullrich 10338ed1b0
fix: wrapInstance: do not leak via un-reducible instances (#13441)
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.
2026-04-20 06:41:32 +00:00

103 lines
2.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}