Skip to content

Commit 2343e31

Browse files
committed
nonisolated(unsafe) to opt out of strict concurrency static checking for global variables
1 parent f436564 commit 2343e31

31 files changed

+228
-54
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ class ActorIsolation {
6060
/// meaning that it can be used from any actor but is also unable to
6161
/// refer to the isolated state of any given actor.
6262
Nonisolated,
63+
/// The declaration is explicitly specified to be not isolated and with the
64+
/// "unsafe" annotation, which means that we do not enforce isolation.
65+
NonisolatedUnsafe,
6366
/// The declaration is isolated to a global actor. It can refer to other
6467
/// entities with the same global actor.
6568
GlobalActor,
@@ -97,8 +100,8 @@ class ActorIsolation {
97100
return ActorIsolation(Unspecified, nullptr);
98101
}
99102

100-
static ActorIsolation forNonisolated() {
101-
return ActorIsolation(Nonisolated, nullptr);
103+
static ActorIsolation forNonisolated(bool unsafe) {
104+
return ActorIsolation(unsafe ? NonisolatedUnsafe : Nonisolated, nullptr);
102105
}
103106

104107
static ActorIsolation forActorInstanceSelf(NominalTypeDecl *actor) {
@@ -124,8 +127,10 @@ class ActorIsolation {
124127
operator Kind() const { return getKind(); }
125128

126129
bool isUnspecified() const { return kind == Unspecified; }
127-
128-
bool isNonisolated() const { return kind == Nonisolated; }
130+
131+
bool isNonisolated() const {
132+
return (kind == Nonisolated) || (kind == NonisolatedUnsafe);
133+
}
129134

130135
/// Retrieve the parameter to which actor-instance isolation applies.
131136
///
@@ -144,6 +149,7 @@ class ActorIsolation {
144149

145150
case Unspecified:
146151
case Nonisolated:
152+
case NonisolatedUnsafe:
147153
return false;
148154
}
149155
}
@@ -192,6 +198,7 @@ class ActorIsolation {
192198

193199
switch (lhs.getKind()) {
194200
case Nonisolated:
201+
case NonisolatedUnsafe:
195202
case Unspecified:
196203
return true;
197204

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ CONTEXTUAL_SIMPLE_DECL_ATTR(async, Async,
487487
SIMPLE_DECL_ATTR(reasync, Reasync,
488488
OnFunc | OnConstructor | RejectByParser | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
489489
109)
490-
CONTEXTUAL_SIMPLE_DECL_ATTR(nonisolated, Nonisolated,
490+
CONTEXTUAL_DECL_ATTR(nonisolated, Nonisolated,
491491
DeclModifier | OnFunc | OnConstructor | OnVar | OnSubscript | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove,
492492
112)
493493
CONTEXTUAL_SIMPLE_DECL_ATTR(distributed, DistributedActor,

include/swift/AST/Attr.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ class DeclAttribute : public AttributeBase {
179179
SWIFT_INLINE_BITFIELD(ObjCImplementationAttr, DeclAttribute, 1,
180180
isCategoryNameInvalid : 1
181181
);
182+
183+
SWIFT_INLINE_BITFIELD(NonisolatedAttr, DeclAttribute, 1,
184+
isUnsafe : 1
185+
);
182186
} Bits;
183187
// clang-format on
184188

@@ -2373,6 +2377,26 @@ class ObjCImplementationAttr final : public DeclAttribute {
23732377
}
23742378
};
23752379

2380+
/// Represents nonisolated modifier.
2381+
class NonisolatedAttr final : public DeclAttribute {
2382+
public:
2383+
NonisolatedAttr(SourceLoc atLoc, SourceRange range, bool unsafe,
2384+
bool implicit)
2385+
: DeclAttribute(DAK_Nonisolated, atLoc, range, implicit) {
2386+
Bits.NonisolatedAttr.isUnsafe = unsafe;
2387+
assert((isUnsafe() == unsafe) && "not enough bits for unsafe state");
2388+
}
2389+
2390+
NonisolatedAttr(bool unsafe, bool implicit)
2391+
: NonisolatedAttr({}, {}, unsafe, implicit) {}
2392+
2393+
bool isUnsafe() const { return Bits.NonisolatedAttr.isUnsafe; }
2394+
2395+
static bool classof(const DeclAttribute *DA) {
2396+
return DA->getKind() == DAK_Nonisolated;
2397+
}
2398+
};
2399+
23762400
/// A macro role attribute, spelled with either @attached or @freestanding,
23772401
/// which declares one of the roles that a given macro can inhabit.
23782402
class MacroRoleAttr final

include/swift/AST/Decl.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6032,7 +6032,10 @@ class VarDecl : public AbstractStorageDecl {
60326032
/// True if this is a top-level global variable from the main source file.
60336033
bool isTopLevelGlobal() const { return Bits.VarDecl.IsTopLevelGlobal; }
60346034
void setTopLevelGlobal(bool b) { Bits.VarDecl.IsTopLevelGlobal = b; }
6035-
6035+
6036+
/// True if this is any storage of static duration (global scope or static).
6037+
bool isGlobalStorage() const;
6038+
60366039
/// Retrieve the custom attributes that attach property wrappers to this
60376040
/// property. The returned list contains all of the attached property wrapper
60386041
/// attributes in source order, which means the outermost wrapper attribute

lib/AST/ASTDumper.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -944,8 +944,9 @@ namespace {
944944
D->getCaptureInfo().print(OS);
945945
}
946946

947-
if (D->getAttrs().hasAttribute<NonisolatedAttr>()) {
948-
PrintWithColorRAII(OS, ExprModifierColor) << " nonisolated";
947+
if (auto *attr = D->getAttrs().getAttribute<NonisolatedAttr>()) {
948+
PrintWithColorRAII(OS, ExprModifierColor)
949+
<< (attr->isUnsafe() ? " nonisolated(unsafe)" : " nonisolated");
949950
}
950951
if (D->isDistributed()) {
951952
PrintWithColorRAII(OS, ExprModifierColor) << " distributed";
@@ -2595,6 +2596,7 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
25952596
switch (auto isolation = E->getActorIsolation()) {
25962597
case ActorIsolation::Unspecified:
25972598
case ActorIsolation::Nonisolated:
2599+
case ActorIsolation::NonisolatedUnsafe:
25982600
break;
25992601

26002602
case ActorIsolation::ActorInstance:

lib/AST/Attr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,14 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
13691369
break;
13701370
}
13711371

1372+
case DAK_Nonisolated: {
1373+
Printer.printAttrName("nonisolated");
1374+
if (cast<NonisolatedAttr>(this)->isUnsafe()) {
1375+
Printer << "(unsafe)";
1376+
}
1377+
break;
1378+
}
1379+
13721380
case DAK_MacroRole: {
13731381
auto Attr = cast<MacroRoleAttr>(this);
13741382

@@ -1689,6 +1697,12 @@ StringRef DeclAttribute::getAttrName() const {
16891697
return "_section";
16901698
case DAK_Documentation:
16911699
return "_documentation";
1700+
case DAK_Nonisolated:
1701+
if (cast<NonisolatedAttr>(this)->isUnsafe()) {
1702+
return "nonisolated(unsafe)";
1703+
} else {
1704+
return "nonisolated";
1705+
}
16921706
case DAK_MacroRole:
16931707
switch (cast<MacroRoleAttr>(this)->getMacroSyntax()) {
16941708
case MacroSyntax::Freestanding:

lib/AST/Decl.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2358,6 +2358,7 @@ static bool deferMatchesEnclosingAccess(const FuncDecl *defer) {
23582358

23592359
switch (getActorIsolation(type)) {
23602360
case ActorIsolation::Unspecified:
2361+
case ActorIsolation::NonisolatedUnsafe:
23612362
case ActorIsolation::GlobalActorUnsafe:
23622363
break;
23632364

@@ -7712,6 +7713,15 @@ VarDecl *VarDecl::getLazyStorageProperty() const {
77127713
{});
77137714
}
77147715

7716+
bool VarDecl::isGlobalStorage() const {
7717+
if (!hasStorage()) {
7718+
return false;
7719+
}
7720+
const auto *dc = getDeclContext();
7721+
return isStatic() || dc->isModuleScopeContext() ||
7722+
(dc->isTypeContext() && !isInstanceMember());
7723+
}
7724+
77157725
bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
77167726
auto customAttrs = getAttachedPropertyWrappers();
77177727
if (customAttrs.empty())
@@ -10221,6 +10231,7 @@ bool VarDecl::isSelfParamCaptureIsolated() const {
1022110231
switch (auto isolation = closure->getActorIsolation()) {
1022210232
case ActorIsolation::Unspecified:
1022310233
case ActorIsolation::Nonisolated:
10234+
case ActorIsolation::NonisolatedUnsafe:
1022410235
case ActorIsolation::GlobalActor:
1022510236
case ActorIsolation::GlobalActorUnsafe:
1022610237
return false;
@@ -10274,7 +10285,7 @@ ActorIsolation swift::getActorIsolationOfContext(
1027410285
if (ctx.LangOpts.hasFeature(Feature::IsolatedDefaultValues) &&
1027510286
var->isInstanceMember() &&
1027610287
!var->getAttrs().hasAttribute<LazyAttr>()) {
10277-
return ActorIsolation::forNonisolated();
10288+
return ActorIsolation::forNonisolated(/*unsafe=*/false);
1027810289
}
1027910290

1028010291
return getActorIsolation(var);

lib/AST/DiagnosticEngine.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,12 @@ static void formatDiagnosticArgument(StringRef Modifier,
921921
}
922922

923923
case ActorIsolation::Nonisolated:
924+
case ActorIsolation::NonisolatedUnsafe:
924925
case ActorIsolation::Unspecified:
925926
Out << "nonisolated";
927+
if (isolation == ActorIsolation::NonisolatedUnsafe) {
928+
Out << "(unsafe)";
929+
}
926930
break;
927931
}
928932
break;

lib/AST/TypeCheckRequests.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,11 @@ void swift::simple_display(
16621662
break;
16631663

16641664
case ActorIsolation::Nonisolated:
1665+
case ActorIsolation::NonisolatedUnsafe:
16651666
out << "nonisolated";
1667+
if (state == ActorIsolation::NonisolatedUnsafe) {
1668+
out << "(unsafe)";
1669+
}
16661670
break;
16671671

16681672
case ActorIsolation::Unspecified:

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7842,7 +7842,8 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
78427842
// Hard-code @actorIndependent, until Objective-C clients start
78437843
// using nonisolated.
78447844
if (swiftAttr->getAttribute() == "@actorIndependent") {
7845-
auto attr = new (SwiftContext) NonisolatedAttr(/*isImplicit=*/true);
7845+
auto attr = new (SwiftContext)
7846+
NonisolatedAttr(/*unsafe=*/false, /*implicit=*/true);
78467847
MappedDecl->getAttrs().add(attr);
78477848
continue;
78487849
}

0 commit comments

Comments
 (0)