Skip to content

Commit e26c165

Browse files
committed
only warn for isolation mismatch in @preconcurrency context
Much like how we do for an isolation mismatch for a call within a closure that is `@preconcurrency`, references should also only warn about the isolation issue too. The reason why there is a mismatch is that the completion-handlers are considered `@Sendable`, which disables the isolation inheriting behavior of other, non-Sendable closures. resolves rdar://96830159
1 parent 33a987f commit e26c165

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2919,13 +2919,18 @@ namespace {
29192919
}
29202920
}
29212921

2922+
// Does the reference originate from a @preconcurrency context?
2923+
bool preconcurrencyContext =
2924+
result.options.contains(ActorReferenceResult::Flags::Preconcurrency);
2925+
29222926
ctx.Diags.diagnose(
29232927
loc, diag::actor_isolated_non_self_reference,
29242928
decl->getDescriptiveKind(),
29252929
decl->getName(),
29262930
useKind,
29272931
refKind + 1, refGlobalActor,
2928-
result.isolation);
2932+
result.isolation)
2933+
.warnUntilSwiftVersionIf(preconcurrencyContext, 6);
29292934

29302935
noteIsolatedActorMember(decl, context);
29312936

@@ -5179,6 +5184,10 @@ ActorReferenceResult ActorReferenceResult::forReference(
51795184
// to perform.
51805185
Options options = None;
51815186

5187+
// Note if the reference originates from a @preconcurrency-isolated context.
5188+
if (contextIsolation.preconcurrency())
5189+
options |= Flags::Preconcurrency;
5190+
51825191
// If the declaration isn't asynchronous, promote to async.
51835192
if (!isAsyncDecl(declRef))
51845193
options |= Flags::AsyncPromotion;

lib/Sema/TypeCheckConcurrency.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ struct ActorReferenceResult {
210210
/// The declaration is being accessed from outside the actor and
211211
/// potentially from a different node, so it must be marked 'distributed'.
212212
Distributed = 1 << 2,
213+
214+
/// The declaration is being accessed from a @preconcurrency context.
215+
Preconcurrency = 1 << 3,
213216
};
214217

215218
using Options = OptionSet<Flags>;

test/ClangImporter/objc_async.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,17 @@ public struct SomeWrapper<T: AuditedNonSendable> {
381381
}
382382

383383
extension SomeWrapper: Sendable where T: Sendable {}
384+
385+
386+
// rdar://96830159
387+
@MainActor class SendableCompletionHandler {
388+
var isolatedThing: [String] = []
389+
// expected-note@-1 {{property declared here}}
390+
391+
func makeCall(slowServer: SlowServer) {
392+
slowServer.doSomethingSlow("churn butter") { (_ : Int) in
393+
let _ = self.isolatedThing
394+
// expected-warning@-1 {{main actor-isolated property 'isolatedThing' can not be referenced from a Sendable closure; this is an error in Swift 6}}
395+
}
396+
}
397+
}

0 commit comments

Comments
 (0)