Skip to content

Commit 4389353

Browse files
kavonDougGregor
authored andcommitted
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 (cherry picked from commit e26c165)
1 parent 3a67c1a commit 4389353

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
@@ -2859,13 +2859,18 @@ namespace {
28592859
}
28602860
}
28612861

2862+
// Does the reference originate from a @preconcurrency context?
2863+
bool preconcurrencyContext =
2864+
result.options.contains(ActorReferenceResult::Flags::Preconcurrency);
2865+
28622866
ctx.Diags.diagnose(
28632867
loc, diag::actor_isolated_non_self_reference,
28642868
decl->getDescriptiveKind(),
28652869
decl->getName(),
28662870
useKind,
28672871
refKind + 1, refGlobalActor,
2868-
result.isolation);
2872+
result.isolation)
2873+
.warnUntilSwiftVersionIf(preconcurrencyContext, 6);
28692874

28702875
noteIsolatedActorMember(decl, context);
28712876

@@ -5119,6 +5124,10 @@ ActorReferenceResult ActorReferenceResult::forReference(
51195124
// to perform.
51205125
Options options = None;
51215126

5127+
// Note if the reference originates from a @preconcurrency-isolated context.
5128+
if (contextIsolation.preconcurrency())
5129+
options |= Flags::Preconcurrency;
5130+
51225131
// If the declaration isn't asynchronous, promote to async.
51235132
if (!isAsyncDecl(declRef))
51245133
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)