Skip to content

Commit d200644

Browse files
committed
Use the strict concurrency level to make decisions.
`isConcurrencyChecked()` was being used as a proxy for `-warn-concurrency` that didn't account for Swift 6. Replace checks against it within the current module with checks against the strict concurrency level, which subsumes the Swift 6 check and can account for the difference between "limited" and "on". `isConcurrencyChecked()` is used now used exclusively to mean "treat a missing Sendable conformance as an explicitly-non-Sendable type".
1 parent 7a724c4 commit d200644

File tree

5 files changed

+21
-15
lines changed

5 files changed

+21
-15
lines changed

lib/IDE/CompletionLookup.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,7 @@ void CompletionLookup::analyzeActorIsolation(
750750
// For "unsafe" global actor isolation, automatic 'async' only happens
751751
// if the context has adopted concurrency.
752752
if (!CanCurrDeclContextHandleAsync &&
753-
!completionContextUsesConcurrencyFeatures(CurrDeclContext) &&
754-
!CurrDeclContext->getParentModule()->isConcurrencyChecked()) {
753+
!completionContextUsesConcurrencyFeatures(CurrDeclContext)) {
755754
return;
756755
}
757756
LLVM_FALLTHROUGH;
@@ -769,7 +768,7 @@ void CompletionLookup::analyzeActorIsolation(
769768
}
770769

771770
// If the reference is 'async', all types must be 'Sendable'.
772-
if (CurrDeclContext->getParentModule()->isConcurrencyChecked() &&
771+
if (Ctx.LangOpts.StrictConcurrencyLevel >= StrictConcurrency::On &&
773772
implicitlyAsync && T) {
774773
auto *M = CurrDeclContext->getParentModule();
775774
if (isa<VarDecl>(VD)) {

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -608,9 +608,6 @@ static bool hasUnavailableConformance(ProtocolConformanceRef conformance) {
608608
}
609609

610610
static bool shouldDiagnoseExistingDataRaces(const DeclContext *dc) {
611-
if (dc->getParentModule()->isConcurrencyChecked())
612-
return true;
613-
614611
return contextRequiresStrictConcurrencyChecking(dc, [](const AbstractClosureExpr *) {
615612
return Type();
616613
});
@@ -2118,9 +2115,16 @@ namespace {
21182115
///
21192116
/// \returns true if we diagnosed the entity, \c false otherwise.
21202117
bool diagnoseReferenceToUnsafeGlobal(ValueDecl *value, SourceLoc loc) {
2121-
if (!getDeclContext()->getParentModule()->isConcurrencyChecked())
2118+
switch (value->getASTContext().LangOpts.StrictConcurrencyLevel) {
2119+
case StrictConcurrency::Off:
2120+
case StrictConcurrency::Limited:
2121+
// Never diagnose.
21222122
return false;
21232123

2124+
case StrictConcurrency::On:
2125+
break;
2126+
}
2127+
21242128
// Only diagnose direct references to mutable global state.
21252129
auto var = dyn_cast<VarDecl>(value);
21262130
if (!var || var->isLet())
@@ -3893,10 +3897,16 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
38933897
bool swift::contextRequiresStrictConcurrencyChecking(
38943898
const DeclContext *dc,
38953899
llvm::function_ref<Type(const AbstractClosureExpr *)> getType) {
3896-
// If Swift >= 6, everything uses strict concurrency checking.
3897-
if (dc->getASTContext().LangOpts.isSwiftVersionAtLeast(6))
3900+
switch (dc->getASTContext().LangOpts.StrictConcurrencyLevel) {
3901+
case StrictConcurrency::On:
38983902
return true;
38993903

3904+
case StrictConcurrency::Limited:
3905+
case StrictConcurrency::Off:
3906+
// Check below to see if the context has adopted concurrency features.
3907+
break;
3908+
}
3909+
39003910
while (!dc->isModuleScopeContext()) {
39013911
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
39023912
// A closure with an explicit global actor or nonindependent

test/ClangImporter/objc_async.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules %s -verify -verify-additional-file %swift_src_root/test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h -warn-concurrency -parse-as-library
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules %s -verify -verify-additional-file %swift_src_root/test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h -strict-concurrency=limited -parse-as-library
22

33
// REQUIRES: objc_interop
44
// REQUIRES: concurrency
55
import Foundation
66
import ObjCConcurrency
7-
// expected-remark@-1{{add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'ObjCConcurrency'}}
87

98
@available(SwiftStdlib 5.5, *)
109
@MainActor func onlyOnMainActor() { }
@@ -358,8 +357,6 @@ func testSender(
358357
// expected-warning@-1 {{conformance of 'NonSendableClass' to 'Sendable' is unavailable}}
359358

360359
sender.sendGeneric(sendableGeneric)
361-
// expected-warning@-1 {{type 'GenericObject<SendableClass>' does not conform to the 'Sendable' protocol}}
362-
// FIXME(rdar://89992569): Should allow for the possibility that GenericObject will have a Sendable subclass
363360
sender.sendGeneric(nonSendableGeneric)
364361
// expected-error@-1 {{argument type 'GenericObject<SendableClass>' does not conform to expected type 'Sendable'}}
365362
// FIXME(rdar://89992095): Should be a warning because we're in -warn-concurrency

test/Concurrency/actor_isolation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ func testGlobalActorClosures() {
463463
return 17
464464
}
465465

466-
acceptConcurrentClosure { @SomeGlobalActor in 5 } // expected-warning{{converting function value of type '@SomeGlobalActor @Sendable () -> Int' to '@Sendable () -> Int' loses global actor 'SomeGlobalActor'}}
466+
acceptConcurrentClosure { @SomeGlobalActor in 5 } // expected-error{{converting function value of type '@SomeGlobalActor @Sendable () -> Int' to '@Sendable () -> Int' loses global actor 'SomeGlobalActor'}}
467467
}
468468

469469
@available(SwiftStdlib 5.1, *)

test/Concurrency/concurrent_value_checking.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func testConcurrency() {
174174
func testUnsafeSendableNothing() {
175175
var x = 5
176176
acceptUnsafeSendable {
177-
x = 17
177+
x = 17 // expected-error{{mutation of captured var 'x' in concurrently-executing code}}
178178
}
179179
print(x)
180180
}

0 commit comments

Comments
 (0)