Skip to content

Commit 9997802

Browse files
committed
[Concurrency] Represent an unsafe global actor using preconcurrency.
`@GlobalActor(unsafe)` and `@preconcurrency @GlobalActor` mean the same thing, but there were two different representations in the actor isolation checker. Standardize on the preconcurrency representation.
1 parent 229d926 commit 9997802

File tree

7 files changed

+32
-41
lines changed

7 files changed

+32
-41
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,8 @@ class ActorIsolation {
121121
return ActorIsolation(ActorInstance, capturedActor);
122122
}
123123

124-
static ActorIsolation forGlobalActor(Type globalActor, bool unsafe) {
125-
return ActorIsolation(
126-
unsafe ? GlobalActorUnsafe : GlobalActor, globalActor);
124+
static ActorIsolation forGlobalActor(Type globalActor) {
125+
return ActorIsolation(GlobalActor, globalActor);
127126
}
128127

129128
static std::optional<ActorIsolation> forSILString(StringRef string) {

lib/AST/Decl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10965,9 +10965,9 @@ ActorIsolation swift::getActorIsolationOfContext(
1096510965
dcToUse->getASTContext().LangOpts.StrictConcurrencyLevel >=
1096610966
StrictConcurrency::Complete) {
1096710967
if (Type mainActor = dcToUse->getASTContext().getMainActorType())
10968-
return ActorIsolation::forGlobalActor(
10969-
mainActor,
10970-
/*unsafe=*/!dcToUse->getASTContext().isSwiftVersionAtLeast(6));
10968+
return ActorIsolation::forGlobalActor(mainActor)
10969+
.withPreconcurrency(
10970+
!dcToUse->getASTContext().isSwiftVersionAtLeast(6));
1097110971
}
1097210972
}
1097310973

lib/AST/TypeCheckRequests.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,9 +1679,8 @@ ActorIsolation ActorIsolation::subst(SubstitutionMap subs) const {
16791679

16801680
case GlobalActor:
16811681
case GlobalActorUnsafe:
1682-
return forGlobalActor(
1683-
getGlobalActor().subst(subs), kind == GlobalActorUnsafe)
1684-
.withPreconcurrency(preconcurrency());
1682+
return forGlobalActor(getGlobalActor().subst(subs))
1683+
.withPreconcurrency(preconcurrency());
16851684
}
16861685
llvm_unreachable("unhandled actor isolation kind!");
16871686
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,8 +1889,7 @@ static ActorIsolation getInnermostIsolatedContext(
18891889
case ActorIsolation::GlobalActor:
18901890
case ActorIsolation::GlobalActorUnsafe:
18911891
return ActorIsolation::forGlobalActor(
1892-
dc->mapTypeIntoContext(isolation.getGlobalActor()),
1893-
isolation == ActorIsolation::GlobalActorUnsafe)
1892+
dc->mapTypeIntoContext(isolation.getGlobalActor()))
18941893
.withPreconcurrency(isolation.preconcurrency());
18951894
}
18961895
}
@@ -3238,8 +3237,7 @@ namespace {
32383237
// we are within that global actor already.
32393238
if (!(getContextIsolation().isGlobalActor() &&
32403239
getContextIsolation().getGlobalActor()->isEqual(globalActor))) {
3241-
unsatisfiedIsolation = ActorIsolation::forGlobalActor(
3242-
globalActor, /*unsafe=*/false);
3240+
unsatisfiedIsolation = ActorIsolation::forGlobalActor(globalActor);
32433241
}
32443242

32453243
mayExitToNonisolated = false;
@@ -3891,7 +3889,7 @@ namespace {
38913889

38923890
// If the closure specifies a global actor, use it.
38933891
if (Type globalActor = resolveGlobalActorType(explicitClosure))
3894-
return ActorIsolation::forGlobalActor(globalActor, /*unsafe=*/false)
3892+
return ActorIsolation::forGlobalActor(globalActor)
38953893
.withPreconcurrency(preconcurrency);
38963894
}
38973895

@@ -3927,7 +3925,7 @@ namespace {
39273925
case ActorIsolation::GlobalActorUnsafe: {
39283926
Type globalActor = closure->mapTypeIntoContext(
39293927
parentIsolation.getGlobalActor()->mapTypeOutOfContext());
3930-
return ActorIsolation::forGlobalActor(globalActor, /*unsafe=*/false)
3928+
return ActorIsolation::forGlobalActor(globalActor)
39313929
.withPreconcurrency(preconcurrency);
39323930
}
39333931

@@ -4124,7 +4122,7 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
41244122
isUnsafe = true;
41254123

41264124
return ActorIsolation::forGlobalActor(
4127-
globalActorType->mapTypeOutOfContext(), isUnsafe)
4125+
globalActorType->mapTypeOutOfContext())
41284126
.withPreconcurrency(decl->preconcurrency() || isUnsafe);
41294127
}
41304128

@@ -4216,8 +4214,8 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
42164214
return true;
42174215

42184216
// Update the global actor type, now that we've done this substitution.
4219-
std::get<1>(isolated) = ActorIsolation::forGlobalActor(
4220-
globalActor, isolation == ActorIsolation::GlobalActorUnsafe);
4217+
std::get<1>(isolated) = ActorIsolation::forGlobalActor(globalActor)
4218+
.withPreconcurrency(isolation.preconcurrency());
42214219
return false;
42224220
}
42234221
}
@@ -4461,8 +4459,7 @@ getActorIsolationForMainFuncDecl(FuncDecl *fnDecl) {
44614459

44624460
return isMainFunction && hasMainActor
44634461
? ActorIsolation::forGlobalActor(
4464-
ctx.getMainActorType()->mapTypeOutOfContext(),
4465-
/*isUnsafe*/ false)
4462+
ctx.getMainActorType()->mapTypeOutOfContext())
44664463
: llvm::Optional<ActorIsolation>();
44674464
}
44684465

@@ -4906,8 +4903,8 @@ ActorIsolation ActorIsolationRequest::evaluate(
49064903
var->getDeclContext()->isAsyncContext())) {
49074904
if (Type mainActor = var->getASTContext().getMainActorType())
49084905
return inferredIsolation(
4909-
ActorIsolation::forGlobalActor(mainActor,
4910-
/*unsafe=*/var->preconcurrency()));
4906+
ActorIsolation::forGlobalActor(mainActor))
4907+
.withPreconcurrency(var->preconcurrency());
49114908
}
49124909
if (auto isolation = getActorIsolationFromWrappedProperty(var))
49134910
return inferredIsolation(isolation);
@@ -4993,7 +4990,8 @@ ActorIsolation ActorIsolationRequest::evaluate(
49934990
ASTContext &ctx = value->getASTContext();
49944991
if (Type mainActor = ctx.getMainActorType()) {
49954992
return inferredIsolation(
4996-
ActorIsolation::forGlobalActor(mainActor, /*unsafe=*/true));
4993+
ActorIsolation::forGlobalActor(mainActor)
4994+
.withPreconcurrency(true));
49974995
}
49984996
}
49994997

@@ -5907,14 +5905,12 @@ AnyFunctionType *swift::adjustFunctionTypeForConcurrency(
59075905
return fnType;
59085906

59095907
case ActorIsolation::GlobalActorUnsafe:
5910-
// Only treat as global-actor-qualified within code that has adopted
5911-
// Swift Concurrency features.
5912-
if (!strictChecking)
5908+
case ActorIsolation::GlobalActor:
5909+
// For preconcurrency, only treat as global-actor-qualified
5910+
// within code that has adopted Swift Concurrency features.
5911+
if (!strictChecking && isolation.preconcurrency())
59135912
return fnType;
59145913

5915-
LLVM_FALLTHROUGH;
5916-
5917-
case ActorIsolation::GlobalActor:
59185914
globalActorType = openType(isolation.getGlobalActor());
59195915
break;
59205916
}
@@ -6058,22 +6054,19 @@ static ActorIsolation getActorIsolationForReference(
60586054
ValueDecl *decl, const DeclContext *fromDC) {
60596055
auto declIsolation = getActorIsolation(decl);
60606056

6061-
// If the isolation is "unsafe" global actor isolation, adjust it based on
6057+
// If the isolation is preconcurrency global actor, adjust it based on
60626058
// context itself. For contexts that require strict checking, treat it as
60636059
// global actor isolation. Otherwise, treat it as unspecified isolation.
6064-
if (declIsolation == ActorIsolation::GlobalActorUnsafe) {
6065-
if (contextRequiresStrictConcurrencyChecking(
6060+
if (declIsolation == ActorIsolation::GlobalActor &&
6061+
declIsolation.preconcurrency()) {
6062+
if (!contextRequiresStrictConcurrencyChecking(
60666063
fromDC,
60676064
[](const AbstractClosureExpr *closure) {
60686065
return closure->getType();
60696066
},
60706067
[](const ClosureExpr *closure) {
60716068
return closure->isIsolatedByPreconcurrency();
60726069
})) {
6073-
declIsolation = ActorIsolation::forGlobalActor(
6074-
declIsolation.getGlobalActor(), /*unsafe=*/false)
6075-
.withPreconcurrency(declIsolation.preconcurrency());
6076-
} else {
60776070
declIsolation = ActorIsolation::forUnspecified();
60786071
}
60796072
}

lib/Serialization/Deserialization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3863,8 +3863,8 @@ class DeclDeserializer {
38633863

38643864
case ActorIsolation::GlobalActor:
38653865
case ActorIsolation::GlobalActorUnsafe:
3866-
isolation = ActorIsolation::forGlobalActor(
3867-
globalActor, isoKind == ActorIsolation::GlobalActorUnsafe);
3866+
isolation = ActorIsolation::forGlobalActor(globalActor)
3867+
.withPreconcurrency(isoKind == ActorIsolation::GlobalActorUnsafe);
38683868
break;
38693869

38703870
case ActorIsolation::ActorInstance:

test/Concurrency/actor_isolation_unsafe.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ struct S5_P2: P2 {
6262
nonisolated func testP2(x: S5_P2, p2: P2) {
6363
p2.f() // expected-warning{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
6464
p2.g() // OKAY
65-
x.f() // expected-error{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
65+
x.f() // expected-warning{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
6666
x.g() // OKAY
6767
}
6868

@@ -72,7 +72,7 @@ func testP2_noconcurrency(x: S5_P2, p2: P2) {
7272
// expected-complete-tns-warning @-1 {{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
7373
p2.g() // okay
7474
x.f() // okay without complete. with targeted/minimal not concurrency-related code
75-
// expected-complete-tns-error @-1 {{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
75+
// expected-complete-tns-warning @-1 {{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
7676
x.g() // OKAY
7777
}
7878

test/Concurrency/toplevel/async-5-top-level.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func isolatedSync() {
2222
func nonIsolatedAsync() async {
2323
await print(a)
2424
a = a + 10
25-
// expected-error@-1:5 {{main actor-isolated var 'a' can not be mutated from a non-isolated context}}
25+
// expected-warning@-1:5 {{main actor-isolated var 'a' can not be mutated from a non-isolated context}}
2626
// expected-warning@-2:9 {{expression is 'async' but is not marked with 'await'}}{{9-9=await }}
2727
// expected-note@-3:9 {{property access is 'async'}}
2828
}

0 commit comments

Comments
 (0)