fix: fixes #1851
This commit is contained in:
parent
5e9767a283
commit
a5ab59a413
3 changed files with 40 additions and 2 deletions
|
|
@ -527,6 +527,33 @@ mutual
|
|||
private partial def processExplictArg (argName : Name) : M Expr := do
|
||||
match (← get).args with
|
||||
| arg::args =>
|
||||
unless (← get).namedArgs.isEmpty do
|
||||
if (← anyNamedArgDependsOnCurrent) then
|
||||
/-
|
||||
We treat the explicit argument `argName` as implicit if we have named arguments that depend on it.
|
||||
The idea is that this explicit argument can be inferred using the type of the named argument one.
|
||||
Note that we also use this approach in the branch where there are no explicit arguments left.
|
||||
This is important to make sure the system behaves in a uniform way.
|
||||
Moreover, users rely on this behavior. For example, consider the example on issue #1851
|
||||
```
|
||||
class Approx {α : Type} (a : α) (X : Type) : Type where
|
||||
val : X
|
||||
|
||||
variable {α β X Y : Type} {f' : α → β} {x' : α} [f : Approx f' (X → Y)] [x : Approx x' X]
|
||||
|
||||
#check f.val
|
||||
#check f.val x.val
|
||||
```
|
||||
The type of `Approx.val` is `{α : Type} → (a : α) → {X : Type} → [self : Approx a X] → X`
|
||||
Note that the argument `a` is explicit since there is no way to infer it from the expected
|
||||
type or the type of other explicit arguments.
|
||||
Recall that `f.val` is sugar for `Approx.val (self := f)`. In both `#check` commands above
|
||||
the user assumed that `a` does not need to be provided since it can be inferred from the type
|
||||
of `self`.
|
||||
We used to that only in the branch where `(← get).args` was empty, but it created an asymmetry
|
||||
because `#check f.val` worked as expected, but one would have to write `#check f.val _ x.val`
|
||||
-/
|
||||
return (← addImplicitArg argName)
|
||||
propagateExpectedType arg
|
||||
modify fun s => { s with args }
|
||||
elabAndAddNewArg argName arg
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ def f7 (xs : Vec α n) : Nat :=
|
|||
xs.casesOn (a := 10) 0 -- Error unused named args
|
||||
|
||||
def f8 (xs : List Nat) : xs ≠ [] → xs.length > 0 :=
|
||||
@List.casesOn _ (motive := fun xs => xs ≠ [] → xs.length > 0) xs (by dsimp; intros; contradiction) (by dsimp; intros; simp_arith)
|
||||
@List.casesOn _ (fun xs => xs ≠ [] → xs.length > 0) xs (by dsimp; intros; contradiction) (by dsimp; intros; simp_arith)
|
||||
|
||||
def f5' (xs : List Nat) (h : xs ≠ []) : xs.length > 0 :=
|
||||
xs.casesOn (fun h => absurd rfl h) (fun _ _ _ => Nat.zero_lt_succ ..) h
|
||||
|
|
@ -87,4 +87,3 @@ noncomputable def f : Nat → Nat :=
|
|||
|
||||
example : ∀ x, x ≥ 0 :=
|
||||
Nat.rec (Nat.le_refl 0) (fun _ ih => Nat.le_succ_of_le ih)
|
||||
|
||||
|
|
|
|||
12
tests/lean/run/1851.lean
Normal file
12
tests/lean/run/1851.lean
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class Approx {α : Type} (a : α) (X : Type) : Type where
|
||||
val : X
|
||||
|
||||
variable {α β X Y : Type} {f' : α → β} {x' : α} [f : Approx f' (X → Y)] [x : Approx x' X]
|
||||
|
||||
-- fails
|
||||
#check f.val x.val
|
||||
|
||||
-- works
|
||||
#check let f'' := f.val
|
||||
let x'' := x.val
|
||||
f'' x''
|
||||
Loading…
Add table
Reference in a new issue