@@ -546,7 +546,9 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
546546 // We need to follow the partial_apply value for two reasons:
547547 // 1. the closure (with the captured values) itself can escape
548548 // 2. something can escape in a destructor when the context is destroyed
549- return walkDownUses ( ofValue: pai, path: path. with ( knownType: nil ) )
549+ if followLoads ( at: path) || pai. capturesAddress ( of: operand) {
550+ return walkDownUses ( ofValue: pai, path: path. with ( knownType: nil ) )
551+ }
550552 case is LoadInst , is LoadWeakInst , is LoadUnownedInst , is LoadBorrowInst :
551553 if !followLoads( at: path) {
552554 return . continueWalk
@@ -966,3 +968,23 @@ private extension SmallProjectionPath {
966968 EscapeUtilityTypes . EscapePath ( projectionPath: self , followStores: false , addressIsStored: false , knownType: nil )
967969 }
968970}
971+
972+ private extension PartialApplyInst {
973+ func capturesAddress( of operand: Operand ) -> Bool {
974+ assert ( operand. value. type. isAddress)
975+ guard let conv = convention ( of: operand) else {
976+ fatalError ( " callee operand of partial_apply cannot have address type " )
977+ }
978+ switch conv {
979+ case . indirectIn, . indirectInGuaranteed:
980+ // A partial_apply copies the values from indirect-in arguments, but does not capture the address.
981+ return false
982+ case . indirectInout, . indirectInoutAliasable, . packInout:
983+ return true
984+ case . directOwned, . directUnowned, . directGuaranteed, . packOwned, . packGuaranteed:
985+ fatalError ( " invalid convention for address operand " )
986+ case . indirectOut, . packOut, . indirectInCXX:
987+ fatalError ( " invalid convention for partial_apply " )
988+ }
989+ }
990+ }
0 commit comments