Fixes a long-standing bug in the the `sorryAx` app unexpander that prevented it from applying. Now `sorry` pretty prints as `sorry`.
95 lines
2.7 KiB
Text
95 lines
2.7 KiB
Text
/-!
|
||
# Dot notation and CoeFun
|
||
|
||
https://github.com/leanprover/lean4/issues/1910
|
||
-/
|
||
|
||
set_option pp.mvars false
|
||
|
||
/-!
|
||
Test that dot notation resolution can see through CoeFun instances.
|
||
-/
|
||
|
||
structure Equiv (α β : Sort _) where
|
||
toFun : α → β
|
||
invFun : β → α
|
||
|
||
infixl:25 " ≃ " => Equiv
|
||
|
||
instance : CoeFun (α ≃ β) fun _ => α → β where
|
||
coe := Equiv.toFun
|
||
|
||
structure Foo where
|
||
n : Nat
|
||
|
||
def Foo.n' : Foo ≃ Nat := ⟨Foo.n, Foo.mk⟩
|
||
|
||
variable (f : Foo)
|
||
/-- info: Foo.n'.toFun f : Nat -/
|
||
#guard_msgs in #check f.n'
|
||
|
||
example (f : Foo) : f.n' = f.n := rfl
|
||
|
||
/-!
|
||
Fail dot notation if it requires using a named argument from the CoeFun instance.
|
||
-/
|
||
structure F where
|
||
f : Bool → Nat → Nat
|
||
|
||
instance : CoeFun F (fun _ => (x : Bool) → (y : Nat) → Nat) where
|
||
coe x := fun (a : Bool) (b : Nat) => x.f a b
|
||
|
||
-- Recall CoeFun oddity: it uses the unfolded *value* to figure out parameter names.
|
||
-- That's why this is `a` and `b` rather than `x` and `y`.
|
||
/-- info: fun x => (fun a b => x.f a b) true 2 : F → Nat -/
|
||
#guard_msgs in #check fun (x : F) => x (a := true) (b := 2)
|
||
|
||
def Nat.foo : F := { f := fun _ b => b }
|
||
|
||
-- Ok:
|
||
/-- info: fun n x => (fun a b => Nat.foo.f a b) x n : Nat → Bool → Nat -/
|
||
#guard_msgs in #check fun (n : Nat) => (Nat.foo · n)
|
||
|
||
-- Intentionally fails:
|
||
/--
|
||
error: invalid field notation, function 'Nat.foo' has argument with the expected type
|
||
Nat
|
||
but it cannot be used
|
||
---
|
||
info: fun n => sorry : (n : Nat) → ?_ n
|
||
-/
|
||
#guard_msgs in #check fun (n : Nat) => n.foo
|
||
|
||
/-!
|
||
Make sure that dot notation does not use the wrong CoeFun instance.
|
||
The following instances rely on the second one having higher priority,
|
||
so we need to fail completely when the instances would depend on argument values.
|
||
-/
|
||
|
||
structure Bar (b : Bool) where
|
||
|
||
instance : CoeFun (Bar b) (fun _ => Bar b → Bool) where
|
||
coe := fun _ _ => b
|
||
|
||
instance : CoeFun (Bar true) (fun _ => (b : Bool) → Bar b) where
|
||
coe := fun _ _ => {}
|
||
|
||
def Bar.bar : Bar true := {}
|
||
|
||
/-- info: fun f => (fun x => false) f : Bar false → Bool -/
|
||
#guard_msgs in #check fun (f : Bar false) => Bar.bar false f
|
||
/--
|
||
error: invalid field notation, function 'Bar.bar' does not have argument with type (Bar ...) that can be used, it must be explicit or implicit with a unique name
|
||
---
|
||
info: fun f => sorry : (f : Bar false) → ?_ f
|
||
-/
|
||
#guard_msgs in #check fun (f : Bar false) => f.bar false
|
||
|
||
/-- info: fun f => (fun x => false) f : Bar false → Bool -/
|
||
#guard_msgs in #check fun (f : Bar false) => Bar.bar true false f
|
||
/--
|
||
error: invalid field notation, function 'Bar.bar' does not have argument with type (Bar ...) that can be used, it must be explicit or implicit with a unique name
|
||
---
|
||
info: fun f => sorry : (f : Bar false) → ?_ f
|
||
-/
|
||
#guard_msgs in #check fun (f : Bar false) => f.bar true false
|