@@ -3184,10 +3184,7 @@ namespace {
3184
3184
isolatedActor, llvm::None, llvm::None, getClosureActorIsolation);
3185
3185
switch (result) {
3186
3186
case ActorReferenceResult::SameConcurrencyDomain:
3187
- if (diagnoseReferenceToUnsafeGlobal (decl, loc))
3188
- return true ;
3189
-
3190
- return false ;
3187
+ return diagnoseReferenceToUnsafeGlobal (decl, loc);
3191
3188
3192
3189
case ActorReferenceResult::ExitsActorToNonisolated:
3193
3190
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -4112,6 +4109,33 @@ ActorIsolation ActorIsolationRequest::evaluate(
4112
4109
return ActorIsolation::forActorInstanceParameter (actor, *paramIdx);
4113
4110
}
4114
4111
4112
+ // Diagnose global state that is not either immutable plus Sendable or
4113
+ // isolated to a global actor.
4114
+ auto checkGlobalIsolation = [var = dyn_cast<VarDecl>(value)](
4115
+ ActorIsolation isolation) {
4116
+ if (var && var->getLoc () &&
4117
+ var->getASTContext ().LangOpts .hasFeature (Feature::GlobalConcurrency) &&
4118
+ !isolation.isGlobalActor ()) {
4119
+ const bool isGlobalState =
4120
+ var->isStatic () || var->getDeclContext ()->isModuleScopeContext () ||
4121
+ (var->getDeclContext ()->isTypeContext () && !var->isInstanceMember ());
4122
+ auto *classDecl = var->getDeclContext ()->getSelfClassDecl ();
4123
+ const bool isActorType = classDecl && classDecl->isAnyActor ();
4124
+ if (isGlobalState && !isActorType) {
4125
+ if (var->isLet ()) {
4126
+ if (!isSendableType (var->getModuleContext (),
4127
+ var->getInterfaceType ())) {
4128
+ var->diagnose (diag::shared_immutable_state_decl, var);
4129
+ }
4130
+ } else {
4131
+ var->diagnose (diag::shared_mutable_state_decl, var);
4132
+ var->diagnose (diag::shared_mutable_state_decl_note, var);
4133
+ }
4134
+ }
4135
+ }
4136
+ return isolation;
4137
+ };
4138
+
4115
4139
auto isolationFromAttr = getIsolationFromAttributes (value);
4116
4140
if (FuncDecl *fd = dyn_cast<FuncDecl>(value)) {
4117
4141
// Main.main() and Main.$main are implicitly MainActor-protected.
@@ -4138,7 +4162,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
4138
4162
checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
4139
4163
}
4140
4164
4141
- return *isolationFromAttr;
4165
+ return checkGlobalIsolation ( *isolationFromAttr) ;
4142
4166
}
4143
4167
4144
4168
// Determine the default isolation for this declaration, which may still be
@@ -4169,78 +4193,82 @@ ActorIsolation ActorIsolationRequest::evaluate(
4169
4193
}
4170
4194
4171
4195
// Function used when returning an inferred isolation.
4172
- auto inferredIsolation = [&](
4173
- ActorIsolation inferred, bool onlyGlobal = false ) {
4174
- // check if the inferred isolation is valid in the context of
4175
- // its overridden isolation.
4176
- if (overriddenValue) {
4177
- // if the inferred isolation is not valid, then carry-over the overridden
4178
- // declaration's isolation as this decl's inferred isolation.
4179
- switch (validOverrideIsolation (
4180
- value, inferred, overriddenValue, *overriddenIso)) {
4181
- case OverrideIsolationResult::Allowed:
4182
- case OverrideIsolationResult::Sendable:
4183
- break ;
4184
-
4185
- case OverrideIsolationResult::Disallowed:
4186
- inferred = *overriddenIso;
4187
- break ;
4188
- }
4189
- }
4196
+ auto inferredIsolation = [&](ActorIsolation inferred,
4197
+ bool onlyGlobal = false ) {
4198
+ // Invoke the body within checkGlobalIsolation to check the result.
4199
+ return checkGlobalIsolation ([&] {
4200
+ // check if the inferred isolation is valid in the context of
4201
+ // its overridden isolation.
4202
+ if (overriddenValue) {
4203
+ // if the inferred isolation is not valid, then carry-over the
4204
+ // overridden declaration's isolation as this decl's inferred isolation.
4205
+ switch (validOverrideIsolation (value, inferred, overriddenValue,
4206
+ *overriddenIso)) {
4207
+ case OverrideIsolationResult::Allowed:
4208
+ case OverrideIsolationResult::Sendable:
4209
+ break ;
4190
4210
4191
- // Add an implicit attribute to capture the actor isolation that was
4192
- // inferred, so that (e.g.) it will be printed and serialized.
4193
- ASTContext &ctx = value->getASTContext ();
4194
- switch (inferred) {
4195
- case ActorIsolation::Independent:
4196
- // Stored properties cannot be non-isolated, so don't infer it.
4197
- if (auto var = dyn_cast<VarDecl>(value)) {
4198
- if (!var->isStatic () && var->hasStorage ())
4199
- return ActorIsolation::forUnspecified ()
4200
- .withPreconcurrency (inferred.preconcurrency ());
4211
+ case OverrideIsolationResult::Disallowed:
4212
+ inferred = *overriddenIso;
4213
+ break ;
4214
+ }
4201
4215
}
4202
4216
4217
+ // Add an implicit attribute to capture the actor isolation that was
4218
+ // inferred, so that (e.g.) it will be printed and serialized.
4219
+ ASTContext &ctx = value->getASTContext ();
4220
+ switch (inferred) {
4221
+ case ActorIsolation::Independent:
4222
+ // Stored properties cannot be non-isolated, so don't infer it.
4223
+ if (auto var = dyn_cast<VarDecl>(value)) {
4224
+ if (!var->isStatic () && var->hasStorage ())
4225
+ return ActorIsolation::forUnspecified ().withPreconcurrency (
4226
+ inferred.preconcurrency ());
4227
+ }
4203
4228
4204
- if (onlyGlobal)
4205
- return ActorIsolation::forUnspecified ()
4206
- .withPreconcurrency (inferred.preconcurrency ());
4229
+ if (onlyGlobal) {
4230
+ return ActorIsolation::forUnspecified ().withPreconcurrency (
4231
+ inferred.preconcurrency ());
4232
+ }
4207
4233
4208
- value->getAttrs ().add (new (ctx) NonisolatedAttr (/* IsImplicit=*/ true ));
4209
- break ;
4234
+ value->getAttrs ().add (new (ctx) NonisolatedAttr (/* IsImplicit=*/ true ));
4235
+ break ;
4210
4236
4211
- case ActorIsolation::GlobalActorUnsafe:
4212
- case ActorIsolation::GlobalActor: {
4213
- // Stored properties of a struct don't need global-actor isolation.
4214
- if (ctx.isSwiftVersionAtLeast (6 ))
4215
- if (auto *var = dyn_cast<VarDecl>(value))
4216
- if (!var->isStatic () && var->isOrdinaryStoredProperty ())
4217
- if (auto *varDC = var->getDeclContext ())
4218
- if (auto *nominal = varDC->getSelfNominalTypeDecl ())
4219
- if (isa<StructDecl>(nominal) &&
4220
- !isWrappedValueOfPropWrapper (var))
4221
- return ActorIsolation::forUnspecified ()
4222
- .withPreconcurrency (inferred.preconcurrency ());
4223
-
4224
- auto typeExpr = TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
4225
- auto attr = CustomAttr::create (
4226
- ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
4227
- if (inferred == ActorIsolation::GlobalActorUnsafe)
4228
- attr->setArgIsUnsafe (true );
4229
- value->getAttrs ().add (attr);
4230
- break ;
4231
- }
4237
+ case ActorIsolation::GlobalActorUnsafe:
4238
+ case ActorIsolation::GlobalActor: {
4239
+ // Stored properties of a struct don't need global-actor isolation.
4240
+ if (ctx.isSwiftVersionAtLeast (6 ))
4241
+ if (auto *var = dyn_cast<VarDecl>(value))
4242
+ if (!var->isStatic () && var->isOrdinaryStoredProperty ())
4243
+ if (auto *varDC = var->getDeclContext ())
4244
+ if (auto *nominal = varDC->getSelfNominalTypeDecl ())
4245
+ if (isa<StructDecl>(nominal) &&
4246
+ !isWrappedValueOfPropWrapper (var))
4247
+ return ActorIsolation::forUnspecified ().withPreconcurrency (
4248
+ inferred.preconcurrency ());
4249
+
4250
+ auto typeExpr =
4251
+ TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
4252
+ auto attr =
4253
+ CustomAttr::create (ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
4254
+ if (inferred == ActorIsolation::GlobalActorUnsafe)
4255
+ attr->setArgIsUnsafe (true );
4256
+ value->getAttrs ().add (attr);
4257
+ break ;
4258
+ }
4232
4259
4233
- case ActorIsolation::ActorInstance:
4234
- case ActorIsolation::Unspecified:
4235
- if (onlyGlobal)
4236
- return ActorIsolation::forUnspecified ()
4237
- . withPreconcurrency ( inferred.preconcurrency ());
4260
+ case ActorIsolation::ActorInstance:
4261
+ case ActorIsolation::Unspecified:
4262
+ if (onlyGlobal)
4263
+ return ActorIsolation::forUnspecified (). withPreconcurrency (
4264
+ inferred.preconcurrency ());
4238
4265
4239
- // Nothing to do.
4240
- break ;
4241
- }
4266
+ // Nothing to do.
4267
+ break ;
4268
+ }
4242
4269
4243
- return inferred;
4270
+ return inferred;
4271
+ }());
4244
4272
};
4245
4273
4246
4274
// If this is a local function, inherit the actor isolation from its
@@ -4371,7 +4399,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
4371
4399
}
4372
4400
4373
4401
// Default isolation for this member.
4374
- return defaultIsolation;
4402
+ return checkGlobalIsolation ( defaultIsolation) ;
4375
4403
}
4376
4404
4377
4405
bool HasIsolatedSelfRequest::evaluate (
0 commit comments