Does partial_apply not take ownership of @inout_aliasable arguments?

I have a question about partial_apply's semantics and whether docs should be updated.

It appears that partial_apply is not taking ownership of @inout_aliasable arguments, for example, destroy_value %3 isn't destroying self in the following code.

struct Foo {
  mutating func f() {
    _ = { () -> () in _ = self }
  }
}
// Foo.f()
sil hidden [ossa] @$s13partial_apply3FooV1fyyF : $@convention(method) (@inout Foo) -> () {
// %0                                             // users: %3, %1
bb0(%0 : $*Foo):
  debug_value_addr %0 : $*Foo, var, name "self", argno 1 // id: %1
  // function_ref closure #1 in Foo.f()
  %2 = function_ref @$s13partial_apply3FooV1fyyFyycfU_ : $@convention(thin) (@inout_aliasable Foo) -> () // user: %3
  %3 = partial_apply [callee_guaranteed] %2(%0) : $@convention(thin) (@inout_aliasable Foo) -> () // user: %4
  destroy_value %3 : $@callee_guaranteed () -> () // id: %4
  %5 = tuple ()                                   // user: %6
  return %5 : $()                                 // id: %6
} // end sil function '$s13partial_apply3FooV1fyyF'

So if partial_apply is not taking ownership of @inout_aliasable arguments, should the SIL doc section on partial_apply be updated?

1 Like

@Joe_Groff

That is correct, @inout_aliasable arguments are only captured by address, because it is not allowed to refer to an inout argument in an escaping closure. (With the exclusivity model, maybe we can even capture them @inout now?)

I created PR #26523 to clarify this in SIL.rst.

1 Like