Skip to content

Commit bd9a845

Browse files
committed
[Concurrency] Downgrade the isolated default argument error to a warning when the
isolation of the argument expression is `@preconcurrency`.
1 parent 680541d commit bd9a845

File tree

2 files changed

+42
-47
lines changed

2 files changed

+42
-47
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3758,6 +3758,14 @@ namespace {
37583758
if (!unsatisfiedIsolation)
37593759
return false;
37603760

3761+
// Record whether the callee isolation or the context isolation
3762+
// is preconcurrency, which is used later to downgrade errors to
3763+
// warnings in minimal checking.
3764+
bool preconcurrency = getContextIsolation().preconcurrency() ||
3765+
(calleeDecl && getActorIsolation(calleeDecl).preconcurrency());
3766+
unsatisfiedIsolation =
3767+
unsatisfiedIsolation->withPreconcurrency(preconcurrency);
3768+
37613769
bool onlyArgsCrossIsolation = callOptions.contains(
37623770
ActorReferenceResult::Flags::OnlyArgsCrossIsolation);
37633771
if (!onlyArgsCrossIsolation &&
@@ -3775,63 +3783,41 @@ namespace {
37753783
// If we need to mark the call as implicitly asynchronous, make sure
37763784
// we're in an asynchronous context.
37773785
if (requiresAsync && !getDeclContext()->isAsyncContext()) {
3786+
auto diagnostic = calleeDecl ?
3787+
Diagnostic(
3788+
/*id*/diag::actor_isolated_call_decl,
3789+
/*args*/*unsatisfiedIsolation, calleeDecl, getContextIsolation()
3790+
) :
3791+
Diagnostic(
3792+
/*id*/diag::actor_isolated_call,
3793+
/*args*/*unsatisfiedIsolation, getContextIsolation()
3794+
);
37783795

37793796
if (ctx.LangOpts.hasFeature(Feature::GroupActorErrors)) {
3780-
3781-
IsolationError mismatch([calleeDecl, apply, unsatisfiedIsolation, getContextIsolation]() {
3782-
if (calleeDecl) {
3783-
auto preconcurrency = getContextIsolation().preconcurrency() ||
3784-
getActorIsolation(calleeDecl).preconcurrency();
3785-
3786-
return IsolationError(
3787-
apply->getLoc(),
3788-
preconcurrency,
3789-
Diagnostic(diag::actor_isolated_call_decl,
3790-
*unsatisfiedIsolation,
3791-
calleeDecl,
3792-
getContextIsolation()));
3793-
} else {
3794-
return IsolationError(
3795-
apply->getLoc(),
3796-
getContextIsolation().preconcurrency(),
3797-
Diagnostic(diag::actor_isolated_call,
3798-
*unsatisfiedIsolation,
3799-
getContextIsolation()));
3800-
}
3801-
}());
3802-
3803-
auto iter = applyErrors.find(std::make_pair(*unsatisfiedIsolation, getContextIsolation()));
3804-
if (iter != applyErrors.end()){
3805-
iter->second.push_back((mismatch));
3806-
} else {
3807-
DiagnosticList list;
3808-
list.push_back((mismatch));
3809-
auto keyPair = std::make_pair(*unsatisfiedIsolation, getContextIsolation());
3810-
applyErrors.insert(std::make_pair(keyPair, list));
3797+
IsolationError mismatch(apply->getLoc(), preconcurrency, diagnostic);
3798+
auto key = std::make_pair(
3799+
unsatisfiedIsolation->withPreconcurrency(false),
3800+
getContextIsolation());
3801+
if (applyErrors.find(key) == applyErrors.end()) {
3802+
applyErrors.insert(std::make_pair(key, DiagnosticList()));
38113803
}
3804+
3805+
applyErrors[key].push_back(mismatch);
38123806
} else {
3807+
ctx.Diags.diagnose(
3808+
apply->getLoc(),
3809+
diagnostic.getID(),
3810+
diagnostic.getArgs())
3811+
.warnUntilSwiftVersionIf(preconcurrency, 6);
3812+
38133813
if (calleeDecl) {
38143814
auto calleeIsolation = getInferredActorIsolation(calleeDecl);
3815-
auto preconcurrency = getContextIsolation().preconcurrency() ||
3816-
calleeIsolation.preconcurrency();
3817-
3818-
ctx.Diags.diagnose(
3819-
apply->getLoc(), diag::actor_isolated_call_decl,
3820-
*unsatisfiedIsolation,
3821-
calleeDecl,
3822-
getContextIsolation())
3823-
.warnUntilSwiftVersionIf(preconcurrency, 6);
38243815
calleeDecl->diagnose(diag::actor_isolated_sync_func, calleeDecl);
38253816
if (auto source = calleeIsolation.source.isInferred()) {
38263817
calleeDecl->diagnose(diag::actor_isolation_source,
38273818
calleeIsolation.isolation,
38283819
calleeIsolation.source);
38293820
}
3830-
} else {
3831-
ctx.Diags.diagnose(
3832-
apply->getLoc(), diag::actor_isolated_call, *unsatisfiedIsolation,
3833-
getContextIsolation())
3834-
.warnUntilSwiftVersionIf(getContextIsolation().preconcurrency(), 6);
38353821
}
38363822

38373823
if (unsatisfiedIsolation->isGlobalActor()) {
@@ -5962,10 +5948,12 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
59625948
auto requiredIsolation = checker.computeRequiredIsolation(initExpr);
59635949
if (requiredIsolation.isActorIsolated()) {
59645950
if (enclosingIsolation != requiredIsolation) {
5951+
bool preconcurrency =
5952+
!isa<ParamDecl>(var) || requiredIsolation.preconcurrency();
59655953
var->diagnose(
59665954
diag::isolated_default_argument_context,
59675955
requiredIsolation, enclosingIsolation)
5968-
.warnUntilSwiftVersionIf(!isa<ParamDecl>(var), 6);
5956+
.warnUntilSwiftVersionIf(preconcurrency, 6);
59695957
return ActorIsolation::forUnspecified();
59705958
}
59715959
}

test/Concurrency/isolated_default_arguments.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22

3-
// RUN: %target-swift-frontend -I %t -disable-availability-checking -strict-concurrency=complete -parse-as-library -emit-sil -o /dev/null -verify -enable-upcoming-feature IsolatedDefaultValues -enable-upcoming-feature RegionBasedIsolation -enable-upcoming-feature InferSendableFromCaptures %s
3+
// RUN: %target-swift-frontend -I %t -disable-availability-checking -strict-concurrency=complete -parse-as-library -emit-sil -o /dev/null -verify -enable-upcoming-feature InferSendableFromCaptures %s
44

55
// REQUIRES: concurrency
66
// REQUIRES: asserts
@@ -317,3 +317,10 @@ struct Values {
317317
@MainActor var value: Int { 0 }
318318
@SomeGlobalActor var otherValue: Int { 0 }
319319
}
320+
321+
class PreconcurrencyInit {
322+
@preconcurrency @MainActor init() {}
323+
}
324+
325+
// expected-warning@+1 {{main actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
326+
func downgrade(_: PreconcurrencyInit = .init()) {}

0 commit comments

Comments
 (0)