@@ -3145,10 +3145,7 @@ namespace {
3145
3145
isolatedActor, llvm::None, llvm::None, getClosureActorIsolation);
3146
3146
switch (result) {
3147
3147
case ActorReferenceResult::SameConcurrencyDomain:
3148
- if (diagnoseReferenceToUnsafeGlobal (decl, loc))
3149
- return true ;
3150
-
3151
- return false ;
3148
+ return diagnoseReferenceToUnsafeGlobal (decl, loc);
3152
3149
3153
3150
case ActorReferenceResult::ExitsActorToNonisolated:
3154
3151
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -4073,6 +4070,33 @@ ActorIsolation ActorIsolationRequest::evaluate(
4073
4070
return ActorIsolation::forActorInstanceParameter (actor, *paramIdx);
4074
4071
}
4075
4072
4073
+ // Diagnose global state that is not either immutable plus Sendable or
4074
+ // isolated to a global actor.
4075
+ auto checkGlobalIsolation = [var = dyn_cast<VarDecl>(value)](
4076
+ ActorIsolation isolation) {
4077
+ if (var && var->getLoc () &&
4078
+ var->getASTContext ().LangOpts .hasFeature (Feature::GlobalConcurrency) &&
4079
+ !isolation.isGlobalActor ()) {
4080
+ const bool isGlobalState =
4081
+ var->isStatic () || var->getDeclContext ()->isModuleScopeContext () ||
4082
+ (var->getDeclContext ()->isTypeContext () && !var->isInstanceMember ());
4083
+ auto *classDecl = var->getDeclContext ()->getSelfClassDecl ();
4084
+ const bool isActorType = classDecl && classDecl->isAnyActor ();
4085
+ if (isGlobalState && !isActorType) {
4086
+ if (var->isLet ()) {
4087
+ if (!isSendableType (var->getModuleContext (),
4088
+ var->getInterfaceType ())) {
4089
+ var->diagnose (diag::shared_immutable_state_decl, var);
4090
+ }
4091
+ } else {
4092
+ var->diagnose (diag::shared_mutable_state_decl, var);
4093
+ var->diagnose (diag::shared_mutable_state_decl_note, var);
4094
+ }
4095
+ }
4096
+ }
4097
+ return isolation;
4098
+ };
4099
+
4076
4100
auto isolationFromAttr = getIsolationFromAttributes (value);
4077
4101
if (FuncDecl *fd = dyn_cast<FuncDecl>(value)) {
4078
4102
// Main.main() and Main.$main are implicitly MainActor-protected.
@@ -4099,7 +4123,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
4099
4123
checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
4100
4124
}
4101
4125
4102
- return *isolationFromAttr;
4126
+ return checkGlobalIsolation ( *isolationFromAttr) ;
4103
4127
}
4104
4128
4105
4129
// Determine the default isolation for this declaration, which may still be
@@ -4130,78 +4154,82 @@ ActorIsolation ActorIsolationRequest::evaluate(
4130
4154
}
4131
4155
4132
4156
// Function used when returning an inferred isolation.
4133
- auto inferredIsolation = [&](
4134
- ActorIsolation inferred, bool onlyGlobal = false ) {
4135
- // check if the inferred isolation is valid in the context of
4136
- // its overridden isolation.
4137
- if (overriddenValue) {
4138
- // if the inferred isolation is not valid, then carry-over the overridden
4139
- // declaration's isolation as this decl's inferred isolation.
4140
- switch (validOverrideIsolation (
4141
- value, inferred, overriddenValue, *overriddenIso)) {
4142
- case OverrideIsolationResult::Allowed:
4143
- case OverrideIsolationResult::Sendable:
4144
- break ;
4145
-
4146
- case OverrideIsolationResult::Disallowed:
4147
- inferred = *overriddenIso;
4148
- break ;
4149
- }
4150
- }
4157
+ auto inferredIsolation = [&](ActorIsolation inferred,
4158
+ bool onlyGlobal = false ) {
4159
+ // Invoke the body within checkGlobalIsolation to check the result.
4160
+ return checkGlobalIsolation ([&] {
4161
+ // check if the inferred isolation is valid in the context of
4162
+ // its overridden isolation.
4163
+ if (overriddenValue) {
4164
+ // if the inferred isolation is not valid, then carry-over the
4165
+ // overridden declaration's isolation as this decl's inferred isolation.
4166
+ switch (validOverrideIsolation (value, inferred, overriddenValue,
4167
+ *overriddenIso)) {
4168
+ case OverrideIsolationResult::Allowed:
4169
+ case OverrideIsolationResult::Sendable:
4170
+ break ;
4151
4171
4152
- // Add an implicit attribute to capture the actor isolation that was
4153
- // inferred, so that (e.g.) it will be printed and serialized.
4154
- ASTContext &ctx = value->getASTContext ();
4155
- switch (inferred) {
4156
- case ActorIsolation::Independent:
4157
- // Stored properties cannot be non-isolated, so don't infer it.
4158
- if (auto var = dyn_cast<VarDecl>(value)) {
4159
- if (!var->isStatic () && var->hasStorage ())
4160
- return ActorIsolation::forUnspecified ()
4161
- .withPreconcurrency (inferred.preconcurrency ());
4172
+ case OverrideIsolationResult::Disallowed:
4173
+ inferred = *overriddenIso;
4174
+ break ;
4175
+ }
4162
4176
}
4163
4177
4178
+ // Add an implicit attribute to capture the actor isolation that was
4179
+ // inferred, so that (e.g.) it will be printed and serialized.
4180
+ ASTContext &ctx = value->getASTContext ();
4181
+ switch (inferred) {
4182
+ case ActorIsolation::Independent:
4183
+ // Stored properties cannot be non-isolated, so don't infer it.
4184
+ if (auto var = dyn_cast<VarDecl>(value)) {
4185
+ if (!var->isStatic () && var->hasStorage ())
4186
+ return ActorIsolation::forUnspecified ().withPreconcurrency (
4187
+ inferred.preconcurrency ());
4188
+ }
4164
4189
4165
- if (onlyGlobal)
4166
- return ActorIsolation::forUnspecified ()
4167
- .withPreconcurrency (inferred.preconcurrency ());
4190
+ if (onlyGlobal) {
4191
+ return ActorIsolation::forUnspecified ().withPreconcurrency (
4192
+ inferred.preconcurrency ());
4193
+ }
4168
4194
4169
- value->getAttrs ().add (new (ctx) NonisolatedAttr (/* IsImplicit=*/ true ));
4170
- break ;
4195
+ value->getAttrs ().add (new (ctx) NonisolatedAttr (/* IsImplicit=*/ true ));
4196
+ break ;
4171
4197
4172
- case ActorIsolation::GlobalActorUnsafe:
4173
- case ActorIsolation::GlobalActor: {
4174
- // Stored properties of a struct don't need global-actor isolation.
4175
- if (ctx.isSwiftVersionAtLeast (6 ))
4176
- if (auto *var = dyn_cast<VarDecl>(value))
4177
- if (!var->isStatic () && var->isOrdinaryStoredProperty ())
4178
- if (auto *varDC = var->getDeclContext ())
4179
- if (auto *nominal = varDC->getSelfNominalTypeDecl ())
4180
- if (isa<StructDecl>(nominal) &&
4181
- !isWrappedValueOfPropWrapper (var))
4182
- return ActorIsolation::forUnspecified ()
4183
- .withPreconcurrency (inferred.preconcurrency ());
4184
-
4185
- auto typeExpr = TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
4186
- auto attr = CustomAttr::create (
4187
- ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
4188
- if (inferred == ActorIsolation::GlobalActorUnsafe)
4189
- attr->setArgIsUnsafe (true );
4190
- value->getAttrs ().add (attr);
4191
- break ;
4192
- }
4198
+ case ActorIsolation::GlobalActorUnsafe:
4199
+ case ActorIsolation::GlobalActor: {
4200
+ // Stored properties of a struct don't need global-actor isolation.
4201
+ if (ctx.isSwiftVersionAtLeast (6 ))
4202
+ if (auto *var = dyn_cast<VarDecl>(value))
4203
+ if (!var->isStatic () && var->isOrdinaryStoredProperty ())
4204
+ if (auto *varDC = var->getDeclContext ())
4205
+ if (auto *nominal = varDC->getSelfNominalTypeDecl ())
4206
+ if (isa<StructDecl>(nominal) &&
4207
+ !isWrappedValueOfPropWrapper (var))
4208
+ return ActorIsolation::forUnspecified ().withPreconcurrency (
4209
+ inferred.preconcurrency ());
4210
+
4211
+ auto typeExpr =
4212
+ TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
4213
+ auto attr =
4214
+ CustomAttr::create (ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
4215
+ if (inferred == ActorIsolation::GlobalActorUnsafe)
4216
+ attr->setArgIsUnsafe (true );
4217
+ value->getAttrs ().add (attr);
4218
+ break ;
4219
+ }
4193
4220
4194
- case ActorIsolation::ActorInstance:
4195
- case ActorIsolation::Unspecified:
4196
- if (onlyGlobal)
4197
- return ActorIsolation::forUnspecified ()
4198
- . withPreconcurrency ( inferred.preconcurrency ());
4221
+ case ActorIsolation::ActorInstance:
4222
+ case ActorIsolation::Unspecified:
4223
+ if (onlyGlobal)
4224
+ return ActorIsolation::forUnspecified (). withPreconcurrency (
4225
+ inferred.preconcurrency ());
4199
4226
4200
- // Nothing to do.
4201
- break ;
4202
- }
4227
+ // Nothing to do.
4228
+ break ;
4229
+ }
4203
4230
4204
- return inferred;
4231
+ return inferred;
4232
+ }());
4205
4233
};
4206
4234
4207
4235
// If this is a local function, inherit the actor isolation from its
@@ -4332,7 +4360,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
4332
4360
}
4333
4361
4334
4362
// Default isolation for this member.
4335
- return defaultIsolation;
4363
+ return checkGlobalIsolation ( defaultIsolation) ;
4336
4364
}
4337
4365
4338
4366
bool HasIsolatedSelfRequest::evaluate (
0 commit comments