hylo
hylo copied to clipboard
sink in subscripts don't move arguments
trafficstars
public type Foo : Deinitializable {
public memberwise init
public var data : Int
public subscript(_ arg: sink Int): Int {
inout {
yield &data
}
}
}
public fun f(_ arg: sink Int) { }
public fun main() {
var obj = Foo(data:1)
let x = 1;
let y = 2;
// This should relocate x.
inout d = obj[x]
&d = 50;
// Can still print x. Why no error?
print(x);
// This should relocate y.
f(y);
// Error!
print(y);
}
I can use x after passing it to a subscript taking a sink parameter. I cannot use y after passing it to a normal function taking a sink parameter.
Minimal reproducer:
subscript p(_ arg: sink Int): Int {
let { yield arg }
}
public fun use(_ x: Int) { }
public fun main() {
var x = 42
let d = p[x]
use(d)
use(x)
}
Problem seems to be that the abstract interpreter doesn't properly update the sate of x after the end d's projection. See corresponding the IR:
external fun FunctionDecl(2424834)() -> {} {
b0(%b0#0 : &{}):
// var x = 42
%i0.0: &Int = alloc_stack Int
%i0.1: &word = subfield_view %i0.0, 0
%i0.2: &word = access [set] %i0.1
store i64(0x2a), %i0.2
end_access %i0.2
// let d = p[x]
%i0.4: &Int = access [sink] %i0.0
%i0.5: &Int = project SubscriptImpl(458754), %i0.4
%i0.6: &Int = access [let] %i0.5
// use(d)
%i0.7: &{} = alloc_stack {}
%i0.9: &{} = access [set] %i0.7
call @FunctionDecl(851970)(%i0.6) to %i0.9
end_access %i0.6
end_project %i0.5 // <- %i0.0 should be considered moved here
end_access %i0.4
end_access %i0.9
mark_state deinitialized %i0.7
// use(x)
%i0.13: &{} = alloc_stack {}
%i0.14: &Int = access [let] %i0.0
%i0.15: &{} = access [set] %i0.13
call @FunctionDecl(851970)(%i0.14) to %i0.15
end_access %i0.14
end_access %i0.15
mark_state deinitialized %i0.13
dealloc_stack %i0.13
dealloc_stack %i0.7
mark_state deinitialized %i0.0
dealloc_stack %i0.0
mark_state initialized %b0#0
return
}