@@ -285,7 +285,9 @@ public struct EscapeEffects : CustomStringConvertible, NoReflectionChildren {
285285 /// Note that theoretically this rule also applies to the `escapingToReturn` effect, but it's impossible
286286 /// to construct such a situation for an argument which is only escaping to the function return.
287287 ///
288- case escapingToArgument( toArgumentIndex: Int , toPath: SmallProjectionPath , isExclusive: Bool )
288+ /// The `escapingToArgument` doesn't have an `isExclusive` flag, because an argument-to-argument escape
289+ /// always involves a store, which makes an exclusive escape impossible.
290+ case escapingToArgument( toArgumentIndex: Int , toPath: SmallProjectionPath )
289291 }
290292
291293 /// To which argument does this effect apply to?
@@ -330,19 +332,19 @@ public struct EscapeEffects : CustomStringConvertible, NoReflectionChildren {
330332 if resultArgDelta != 1 {
331333 return nil
332334 }
333- self . kind = . escapingToArgument( toArgumentIndex: 0 , toPath: toPath, isExclusive : exclusive )
335+ self . kind = . escapingToArgument( toArgumentIndex: 0 , toPath: toPath)
334336 } else {
335337 self . kind = . escapingToReturn( toPath: toPath, isExclusive: exclusive)
336338 }
337- case . escapingToArgument( let toArgIdx, let toPath, let exclusive ) :
339+ case . escapingToArgument( let toArgIdx, let toPath) :
338340 let resultingToArgIdx = toArgIdx + resultArgDelta
339341 if resultingToArgIdx < 0 {
340342 if resultingToArgIdx != - 1 {
341343 return nil
342344 }
343- self . kind = . escapingToReturn( toPath: toPath, isExclusive: exclusive )
345+ self . kind = . escapingToReturn( toPath: toPath, isExclusive: false )
344346 } else {
345- self . kind = . escapingToArgument( toArgumentIndex: resultingToArgIdx, toPath: toPath, isExclusive : exclusive )
347+ self . kind = . escapingToArgument( toArgumentIndex: resultingToArgIdx, toPath: toPath)
346348 }
347349 }
348350 }
@@ -362,9 +364,9 @@ public struct EscapeEffects : CustomStringConvertible, NoReflectionChildren {
362364 case . escapingToReturn( let toPath, let exclusive) :
363365 let toPathStr = ( toPath. isEmpty ? " " : " . \( toPath) " )
364366 return " escape \( patternStr) \( exclusive ? " => " : " -> " ) %r \( toPathStr) "
365- case . escapingToArgument( let toArgIdx, let toPath, let exclusive ) :
367+ case . escapingToArgument( let toArgIdx, let toPath) :
366368 let toPathStr = ( toPath. isEmpty ? " " : " . \( toPath) " )
367- return " escape \( patternStr) \( exclusive ? " => " : " -> " ) % \( toArgIdx) \( toPathStr) "
369+ return " escape \( patternStr) -> % \( toArgIdx) \( toPathStr) "
368370 }
369371 }
370372
@@ -663,16 +665,21 @@ extension StringParser {
663665 try throwError ( " multi-value returns not supported yet " )
664666 }
665667 let toPath = try parsePathPatternFromSource ( for: function, type: function. argumentTypes [ 0 ] )
666- return EscapeEffects . ArgumentEffect ( . escapingToArgument( toArgumentIndex: 0 , toPath: toPath, isExclusive: exclusive) ,
668+
669+ // Exclusive escapes are ignored for indirect return values.
670+ return EscapeEffects . ArgumentEffect ( . escapingToArgument( toArgumentIndex: 0 , toPath: toPath) ,
667671 argumentIndex: fromArgIdx, pathPattern: fromPath, isDerived: false )
668672 }
669673 let toPath = try parsePathPatternFromSource ( for: function, type: function. resultType)
670674 return EscapeEffects . ArgumentEffect ( . escapingToReturn( toPath: toPath, isExclusive: exclusive) ,
671675 argumentIndex: fromArgIdx, pathPattern: fromPath, isDerived: false )
672676 }
677+ if exclusive {
678+ try throwError ( " exclusive escapes to arguments are not supported " )
679+ }
673680 let toArgIdx = try parseArgumentIndexFromSource ( for: function, params: params)
674681 let toPath = try parsePathPatternFromSource ( for: function, type: function. argumentTypes [ toArgIdx] )
675- return EscapeEffects . ArgumentEffect ( . escapingToArgument( toArgumentIndex: toArgIdx, toPath: toPath, isExclusive : exclusive ) ,
682+ return EscapeEffects . ArgumentEffect ( . escapingToArgument( toArgumentIndex: toArgIdx, toPath: toPath) ,
676683 argumentIndex: fromArgIdx, pathPattern: fromPath, isDerived: false )
677684 }
678685 try throwError ( " unknown effect " )
@@ -739,9 +746,12 @@ extension StringParser {
739746 effect = EscapeEffects . ArgumentEffect ( . escapingToReturn( toPath: toPath, isExclusive: exclusive) ,
740747 argumentIndex: argumentIndex, pathPattern: fromPath, isDerived: isDerived)
741748 } else {
749+ if exclusive {
750+ try throwError ( " exclusive escapes to arguments are not supported " )
751+ }
742752 let toArgIdx = try parseArgumentIndexFromSIL ( )
743753 let toPath = consume ( " . " ) ? try parseProjectionPathFromSIL ( ) : SmallProjectionPath ( )
744- effect = EscapeEffects . ArgumentEffect ( . escapingToArgument( toArgumentIndex: toArgIdx, toPath: toPath, isExclusive : exclusive ) ,
754+ effect = EscapeEffects . ArgumentEffect ( . escapingToArgument( toArgumentIndex: toArgIdx, toPath: toPath) ,
745755 argumentIndex: argumentIndex, pathPattern: fromPath, isDerived: isDerived)
746756 }
747757 effects. escapeEffects. arguments. append ( effect)
0 commit comments