Skip to content

Commit f0fff2e

Browse files
committed
[region-isolation] Treat sendable return values as Sendable when the returning function has a known actor isolation.
rdar://130544081
1 parent 3c6b0bd commit f0fff2e

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3475,6 +3475,14 @@ RegionAnalysisValueMap::initializeTrackableValue(
34753475

34763476
// If we did not insert, just return the already stored value.
34773477
self->stateIndexToEquivalenceClass[iter.first->second.getID()] = value;
3478+
3479+
// Before we do anything, see if we have a Sendable value.
3480+
if (!SILIsolationInfo::isNonSendableType(value->getType(), fn)) {
3481+
iter.first->getSecond().addFlag(TrackableValueFlag::isSendable);
3482+
return {{iter.first->first, iter.first->second}, true};
3483+
}
3484+
3485+
// Otherwise, we have a non-Sendable type... so wire up the isolation.
34783486
iter.first->getSecond().setIsolationRegionInfo(newInfo);
34793487

34803488
return {{iter.first->first, iter.first->second}, true};

test/Concurrency/async_let_isolation.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ actor MyActor {
2323
async let z = synchronous()
2424

2525
var localText = text
26-
// TODO: We should allow this since text is Sendable and localText is a
27-
// separate box. localText should be disconnected.
26+
2827
async let w = localText.removeLast() // expected-without-transferring-warning {{mutation of captured var 'localText' in concurrently-executing code}}
29-
// expected-tns-warning @-1 {{task or actor isolated value cannot be sent}}
3028

3129
_ = await x
3230
_ = await y

test/Concurrency/transfernonsendable.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1793,4 +1793,19 @@ public func doNotCrashOrEmitUnhandledPatternErrors<T: Sendable>(
17931793
}
17941794
throw CancellationError()
17951795
}
1796-
}
1796+
}
1797+
1798+
/// The following makes sure that when we have a function like test2 with an
1799+
/// assigned isolation that returns a Sendable value... we treat the value as
1800+
/// actually Sendable. This occurs in this example via the result of the default
1801+
/// parameter function for string.
1802+
///
1803+
/// We shouldn't emit any diagnostic here.
1804+
actor FunctionWithSendableResultAndIsolationActor {
1805+
func foo() -> String {
1806+
return string()
1807+
}
1808+
func string(someCondition: Bool = false) -> String {
1809+
return ""
1810+
}
1811+
}

0 commit comments

Comments
 (0)