mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[region-isolation] Make sure to look through begin_access and don't treat it like an assignment.
If we treat a begin_access as an assignment then in cases like below we assume
that a value was used before we reassign.
```
func testVarReassignStopActorDerived() async {
var closure = {}
await transferToMain(closure)
// This re-assignment shouldn't error.
closure = {} // (1)
}
```
rdar://117437299
This commit is contained in:
@@ -885,7 +885,6 @@ public:
|
||||
// treating some of these as lookthroughs in getUnderlyingTrackedValue
|
||||
// instead of as assignments
|
||||
case SILInstructionKind::AddressToPointerInst:
|
||||
case SILInstructionKind::BeginAccessInst:
|
||||
case SILInstructionKind::CopyValueInst:
|
||||
case SILInstructionKind::ConvertEscapeToNoEscapeInst:
|
||||
case SILInstructionKind::ConvertFunctionInst:
|
||||
@@ -1070,6 +1069,25 @@ public:
|
||||
case SILInstructionKind::YieldInst: // TODO: yield should be handled
|
||||
return;
|
||||
|
||||
// We ignore begin_access since we look through them. We look through them
|
||||
// since we want to treat the use of the begin_access as the semantic giving
|
||||
// instruction. Otherwise, if we have a store after a consume we will emit
|
||||
// an error on the begin_access rather than allowing for the store to
|
||||
// overwrite the original value. This would then cause an error.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// %0 = alloc_stack
|
||||
// store %1 to %0
|
||||
// apply %transfer(%0)
|
||||
// %2 = begin_access [modify] [static] %0
|
||||
// store %2 to %0
|
||||
//
|
||||
// If we treated a begin_access as an assign, we would require %0 to not be
|
||||
// transferred at %2 even though we are about to overwrite it.
|
||||
case SILInstructionKind::BeginAccessInst:
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user