@@ -615,10 +615,14 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
615
615
}
616
616
617
617
// Indirect arguments cannot escape the function, but loaded values from such can.
618
- if !followLoads( at: path) &&
619
- // Except for begin_apply: it can yield an address value.
620
- !apply. isBeginApplyWithIndirectResults {
621
- return . continueWalk
618
+ if !followLoads( at: path) {
619
+ guard let beginApply = apply as? BeginApplyInst else {
620
+ return . continueWalk
621
+ }
622
+ // Except for begin_apply: it can yield an address value.
623
+ if !indirectResultEscapes( of: beginApply, path: path) {
624
+ return . continueWalk
625
+ }
622
626
}
623
627
624
628
if argOp. value. type. isNoEscapeFunction {
@@ -658,7 +662,16 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
658
662
}
659
663
return . continueWalk
660
664
}
661
-
665
+
666
+ private mutating func indirectResultEscapes( of beginApply: BeginApplyInst , path: Path ) -> Bool {
667
+ for result in beginApply. yieldedValues where result. type. isAddress {
668
+ if walkDownUses ( ofAddress: result, path: path) == . abortWalk {
669
+ return true
670
+ }
671
+ }
672
+ return false
673
+ }
674
+
662
675
/// Handle `.escaping` effects for an apply argument during the walk-down.
663
676
private mutating
664
677
func walkDownArgument( calleeArgIdx: Int , argPath: Path ,
@@ -928,13 +941,3 @@ private extension SmallProjectionPath {
928
941
EscapeUtilityTypes . EscapePath ( projectionPath: self , followStores: false , addressIsStored: false , knownType: nil )
929
942
}
930
943
}
931
-
932
- private extension ApplySite {
933
- var isBeginApplyWithIndirectResults : Bool {
934
- guard let ba = self as? BeginApplyInst else {
935
- return false
936
- }
937
- // Note that the token result is always a non-address type.
938
- return ba. results. contains { $0. type. isAddress }
939
- }
940
- }
0 commit comments