fix: accidental ownership with specialization
This commit is contained in:
parent
745d77b068
commit
d85d3d5f3a
5 changed files with 57 additions and 15 deletions
|
|
@ -24,12 +24,12 @@ abbrev Index := Nat
|
|||
/-- Variable identifier -/
|
||||
structure VarId where
|
||||
idx : Index
|
||||
deriving Inhabited
|
||||
deriving Inhabited, Repr
|
||||
|
||||
/-- Join point identifier -/
|
||||
structure JoinPointId where
|
||||
idx : Index
|
||||
deriving Inhabited
|
||||
deriving Inhabited, Repr
|
||||
|
||||
abbrev Index.lt (a b : Index) : Bool := a < b
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ inductive IRType where
|
|||
| irrelevant | object | tobject
|
||||
| struct (leanTypeName : Option Name) (types : Array IRType) : IRType
|
||||
| union (leanTypeName : Name) (types : Array IRType) : IRType
|
||||
deriving Inhabited
|
||||
deriving Inhabited, Repr
|
||||
|
||||
namespace IRType
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ structure Param where
|
|||
x : VarId
|
||||
borrow : Bool
|
||||
ty : IRType
|
||||
deriving Inhabited
|
||||
deriving Inhabited, Repr
|
||||
|
||||
@[export lean_ir_mk_param]
|
||||
def mkParam (x : VarId) (borrow : Bool) (ty : IRType) : Param := ⟨x, borrow, ty⟩
|
||||
|
|
|
|||
|
|
@ -258,7 +258,8 @@ def preserveTailCall (x : VarId) (v : Expr) (b : FnBody) : M Unit := do
|
|||
let ctx ← read
|
||||
match v, b with
|
||||
| (Expr.fap g ys), (FnBody.ret (Arg.var z)) =>
|
||||
if ctx.decls.any (·.name == g) && x == z then
|
||||
-- NOTE: we currently support TCO for self-calls only
|
||||
if ctx.currFn == g && x == z then
|
||||
let ps ← getParamInfo (ParamMap.Key.decl g)
|
||||
ownParamsUsingArgs ys ps
|
||||
| _, _ => pure ()
|
||||
|
|
|
|||
25
tests/lean/4240.lean
Normal file
25
tests/lean/4240.lean
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/-! Check for bug accidentally marking `m` as owned. -/
|
||||
|
||||
class MyClass (α : Type u) where
|
||||
|
||||
instance : MyClass Nat where
|
||||
|
||||
inductive MyOption (α : Type u) where
|
||||
| none
|
||||
| some (key : α)
|
||||
|
||||
namespace MyOption
|
||||
|
||||
def isSomeWithInstance [MyClass α] : MyOption α → Bool
|
||||
| none => false
|
||||
| some _ => true
|
||||
|
||||
def isSome : MyOption α → Bool
|
||||
| none => false
|
||||
| some _ => true
|
||||
|
||||
end MyOption
|
||||
|
||||
set_option trace.compiler.ir.result true in
|
||||
def isSomeWithInstanceNat (m : { m : Array (MyOption Nat) // 0 < m.size }) : Bool :=
|
||||
(m.1.uget 0 m.2).isSomeWithInstance
|
||||
26
tests/lean/4240.lean.expected.out
Normal file
26
tests/lean/4240.lean.expected.out
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
[result]
|
||||
def MyOption.isSomeWithInstance._at.isSomeWithInstanceNat._spec_1 (x_1 : @& obj) : u8 :=
|
||||
case x_1 : obj of
|
||||
MyOption.none →
|
||||
let x_2 : u8 := 0;
|
||||
ret x_2
|
||||
MyOption.some →
|
||||
let x_3 : u8 := 1;
|
||||
ret x_3
|
||||
def isSomeWithInstanceNat (x_1 : @& obj) : u8 :=
|
||||
let x_2 : usize := 0;
|
||||
let x_3 : obj := Array.uget ◾ x_1 x_2 ◾;
|
||||
let x_4 : u8 := MyOption.isSomeWithInstance._at.isSomeWithInstanceNat._spec_1 x_3;
|
||||
dec x_3;
|
||||
ret x_4
|
||||
def MyOption.isSomeWithInstance._at.isSomeWithInstanceNat._spec_1._boxed (x_1 : obj) : obj :=
|
||||
let x_2 : u8 := MyOption.isSomeWithInstance._at.isSomeWithInstanceNat._spec_1 x_1;
|
||||
dec x_1;
|
||||
let x_3 : obj := box x_2;
|
||||
ret x_3
|
||||
def isSomeWithInstanceNat._boxed (x_1 : obj) : obj :=
|
||||
let x_2 : u8 := isSomeWithInstanceNat x_1;
|
||||
dec x_1;
|
||||
let x_3 : obj := box x_2;
|
||||
ret x_3
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
set_option trace.compiler.ir.result true
|
||||
|
||||
-- should be tail calls
|
||||
mutual
|
||||
|
||||
partial def even (a : Nat) : Nat := if a == 0 then 1 else odd (a - 1)
|
||||
|
||||
partial def odd (a : Nat) : Nat := if a == 0 then 0 else even (a - 1)
|
||||
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue