swift
59fdfadd - [move-only] Spill noncopyable types that are objects using store_borrow if we call a resilient function that takes it in_guaranteed.

Commit
2 years ago
[move-only] Spill noncopyable types that are objects using store_borrow if we call a resilient function that takes it in_guaranteed. This ensures that given a class that contains a noncopyable type that contains another noncopyable type: ``` @_moveOnly struct S2 {} @_moveOnly struct S { var s2: S2 } class C { var s: S } ``` if we call a resilient function that takes C.S.S2: ``` borrowVal(c.s.s2) ``` we properly spill s2 onto the stack using a store_borrow. Why Do This? ------------ Currently SILGenLValue treats ref_element_addr as a base that it needs to load from for both copyable and non-copyable types. We keep a separation of concerns and require emission of resilient functions to handle these loaded values. For copyable types this means copying the value and storing it into a temporary stack allocation. For noncopyable types, we never actually implemented this so we would hit an error in SILGenApply telling us that our resilient function expected an address argument, but we are passing an object. To work around this, I updated how we emit borrowed lvalue arguments to in this case to spill the value into a temporary allocation using a store_borrow. I also included a test that validates that we properly have a read exclusivity scope around the original loaded from memory for the entire call site so even though we are performing a load_borrow and then spilling it, we still have read exclusivity to the original memory for the entire region meaning that we still preserve the semantics. rdar://109171001
Author
Committer
Parents
Loading