Skip to content

Commit bd8626f

Browse files
committed
[Concurrency] Parse and add 'isolated' parameters to the type system.
1 parent 0e5f0b0 commit bd8626f

26 files changed

+248
-59
lines changed

include/swift/AST/Attr.def

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,11 @@ CONTEXTUAL_SIMPLE_DECL_ATTR(actor, Actor,
574574
APIBreakingToAdd | APIBreakingToRemove,
575575
102)
576576

577-
// Unused attribute 103
577+
CONTEXTUAL_SIMPLE_DECL_ATTR(isolated, Isolated,
578+
DeclModifier | OnParam |
579+
ABIBreakingToAdd | ABIBreakingToRemove |
580+
APIBreakingToAdd | APIBreakingToRemove,
581+
103)
578582

579583
SIMPLE_DECL_ATTR(globalActor, GlobalActor,
580584
OnClass | OnStruct | OnEnum | ConcurrencyOnly |
@@ -668,7 +672,6 @@ SIMPLE_DECL_ATTR(_distributedActorIndependent, DistributedActorIndependent,
668672
APIBreakingToAdd | APIBreakingToRemove,
669673
119)
670674

671-
672675
#undef TYPE_ATTR
673676
#undef DECL_ATTR_ALIAS
674677
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Decl.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,7 +5262,7 @@ class ParamDecl : public VarDecl {
52625262

52635263
TypeRepr *TyRepr = nullptr;
52645264

5265-
struct StoredDefaultArgument {
5265+
struct alignas(1 << DeclAlignInBits) StoredDefaultArgument {
52665266
PointerUnion<Expr *, VarDecl *> DefaultArg;
52675267

52685268
/// Stores the context for the default argument as well as a bit to
@@ -5283,10 +5283,13 @@ class ParamDecl : public VarDecl {
52835283

52845284
/// Whether or not this parameter is `@autoclosure`.
52855285
IsAutoClosure = 1 << 1,
5286+
5287+
/// Whether or not this parameter is 'isolated'.
5288+
IsIsolated = 1 << 2,
52865289
};
52875290

52885291
/// The default value, if any, along with flags.
5289-
llvm::PointerIntPair<StoredDefaultArgument *, 2, OptionSet<Flags>>
5292+
llvm::PointerIntPair<StoredDefaultArgument *, 3, OptionSet<Flags>>
52905293
DefaultValueAndFlags;
52915294

52925295
friend class ParamSpecifierRequest;
@@ -5437,6 +5440,17 @@ class ParamDecl : public VarDecl {
54375440
: flags - Flags::IsAutoClosure);
54385441
}
54395442

5443+
/// Whether or not this parameter is marked with 'isolated'.
5444+
bool isIsolated() const {
5445+
return DefaultValueAndFlags.getInt().contains(Flags::IsIsolated);
5446+
}
5447+
5448+
void setIsolated(bool value = true) {
5449+
auto flags = DefaultValueAndFlags.getInt();
5450+
DefaultValueAndFlags.setInt(value ? flags | Flags::IsIsolated
5451+
: flags - Flags::IsIsolated);
5452+
}
5453+
54405454
/// Does this parameter reject temporary pointer conversions?
54415455
bool isNonEphemeral() const;
54425456

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4477,6 +4477,9 @@ ERROR(actor_cannot_conform_to_global_actor_protocol,none,
44774477
NOTE(protocol_isolated_to_global_actor_here,none,
44784478
"%0 is isolated to global actor %1 here", (Type, Type))
44794479

4480+
ERROR(isolated_parameter_not_actor,none,
4481+
"'isolated' parameter has non-actor type %0", (Type))
4482+
44804483
WARNING(non_concurrent_param_type,none,
44814484
"cannot pass argument of non-sendable type %0 across actors",
44824485
(Type))
@@ -4523,6 +4526,9 @@ ERROR(nonisolated_local_var,none,
45234526
"'nonisolated' can not be applied to local variables",
45244527
())
45254528

4529+
ERROR(isolated_param_non_actor,none,
4530+
"'isolated' parameter cannot have not-actor type %0", (Type))
4531+
45264532
ERROR(actor_instance_property_wrapper,none,
45274533
"%0 property in property wrapper type %1 cannot be isolated to "
45284534
"the actor instance; consider 'nonisolated'",

include/swift/AST/TypeRepr.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,8 @@ class SpecifierTypeRepr : public TypeRepr {
939939
static bool classof(const TypeRepr *T) {
940940
return T->getKind() == TypeReprKind::InOut ||
941941
T->getKind() == TypeReprKind::Shared ||
942-
T->getKind() == TypeReprKind::Owned;
942+
T->getKind() == TypeReprKind::Owned ||
943+
T->getKind() == TypeReprKind::Isolated;
943944
}
944945
static bool classof(const SpecifierTypeRepr *T) { return true; }
945946

@@ -995,6 +996,21 @@ class OwnedTypeRepr : public SpecifierTypeRepr {
995996
static bool classof(const OwnedTypeRepr *T) { return true; }
996997
};
997998

999+
/// An 'isolated' type.
1000+
/// \code
1001+
/// x : isolated Actor
1002+
/// \endcode
1003+
class IsolatedTypeRepr : public SpecifierTypeRepr {
1004+
public:
1005+
IsolatedTypeRepr(TypeRepr *Base, SourceLoc InOutLoc)
1006+
: SpecifierTypeRepr(TypeReprKind::Isolated, Base, InOutLoc) {}
1007+
1008+
static bool classof(const TypeRepr *T) {
1009+
return T->getKind() == TypeReprKind::Isolated;
1010+
}
1011+
static bool classof(const IsolatedTypeRepr *T) { return true; }
1012+
};
1013+
9981014
/// A TypeRepr for a known, fixed type.
9991015
///
10001016
/// Fixed type representations should be used sparingly, in places
@@ -1226,6 +1242,7 @@ inline bool TypeRepr::isSimple() const {
12261242
case TypeReprKind::SILBox:
12271243
case TypeReprKind::Shared:
12281244
case TypeReprKind::Owned:
1245+
case TypeReprKind::Isolated:
12291246
case TypeReprKind::Placeholder:
12301247
return true;
12311248
}

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ ABSTRACT_TYPEREPR(Specifier, TypeRepr)
5959
TYPEREPR(InOut, SpecifierTypeRepr)
6060
TYPEREPR(Shared, SpecifierTypeRepr)
6161
TYPEREPR(Owned, SpecifierTypeRepr)
62+
TYPEREPR(Isolated, SpecifierTypeRepr)
6263
TYPEREPR(Fixed, TypeRepr)
6364
TYPEREPR(SILBox, TypeRepr)
6465
LAST_TYPEREPR(SILBox)

include/swift/AST/Types.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,10 +1929,11 @@ class ParameterTypeFlags {
19291929
OwnershipShift = 3,
19301930
Ownership = 7 << OwnershipShift,
19311931
NoDerivative = 1 << 6,
1932-
NumBits = 7
1932+
Isolated = 1 << 7,
1933+
NumBits = 8
19331934
};
19341935
OptionSet<ParameterFlags> value;
1935-
static_assert(NumBits < 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
1936+
static_assert(NumBits <= 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
19361937

19371938
ParameterTypeFlags(OptionSet<ParameterFlags, uint8_t> val) : value(val) {}
19381939

@@ -1943,17 +1944,18 @@ class ParameterTypeFlags {
19431944
}
19441945

19451946
ParameterTypeFlags(bool variadic, bool autoclosure, bool nonEphemeral,
1946-
ValueOwnership ownership, bool noDerivative)
1947+
ValueOwnership ownership, bool isolated, bool noDerivative)
19471948
: value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
19481949
(nonEphemeral ? NonEphemeral : 0) |
19491950
uint8_t(ownership) << OwnershipShift |
1951+
(isolated ? Isolated : 0) |
19501952
(noDerivative ? NoDerivative : 0)) {}
19511953

19521954
/// Create one from what's present in the parameter type
19531955
inline static ParameterTypeFlags
19541956
fromParameterType(Type paramTy, bool isVariadic, bool isAutoClosure,
19551957
bool isNonEphemeral, ValueOwnership ownership,
1956-
bool isNoDerivative);
1958+
bool isolated, bool isNoDerivative);
19571959

19581960
bool isNone() const { return !value; }
19591961
bool isVariadic() const { return value.contains(Variadic); }
@@ -1962,6 +1964,7 @@ class ParameterTypeFlags {
19621964
bool isInOut() const { return getValueOwnership() == ValueOwnership::InOut; }
19631965
bool isShared() const { return getValueOwnership() == ValueOwnership::Shared;}
19641966
bool isOwned() const { return getValueOwnership() == ValueOwnership::Owned; }
1967+
bool isIsolated() const { return value.contains(Isolated); }
19651968
bool isNoDerivative() const { return value.contains(NoDerivative); }
19661969

19671970
ValueOwnership getValueOwnership() const {
@@ -2005,6 +2008,12 @@ class ParameterTypeFlags {
20052008
: value - ParameterTypeFlags::NonEphemeral);
20062009
}
20072010

2011+
ParameterTypeFlags withIsolated(bool isolated) const {
2012+
return ParameterTypeFlags(isolated
2013+
? value | ParameterTypeFlags::Isolated
2014+
: value - ParameterTypeFlags::Isolated);
2015+
}
2016+
20082017
ParameterTypeFlags withNoDerivative(bool noDerivative) const {
20092018
return ParameterTypeFlags(noDerivative
20102019
? value | ParameterTypeFlags::NoDerivative
@@ -2078,7 +2087,7 @@ class YieldTypeFlags {
20782087
return ParameterTypeFlags(/*variadic*/ false,
20792088
/*autoclosure*/ false,
20802089
/*nonEphemeral*/ false, getValueOwnership(),
2081-
/*noDerivative*/ false);
2090+
/*isolated*/ false, /*noDerivative*/ false);
20822091
}
20832092

20842093
bool operator ==(const YieldTypeFlags &other) const {
@@ -6227,7 +6236,7 @@ inline TupleTypeElt TupleTypeElt::getWithType(Type T) const {
62276236
/// Create one from what's present in the parameter decl and type
62286237
inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
62296238
Type paramTy, bool isVariadic, bool isAutoClosure, bool isNonEphemeral,
6230-
ValueOwnership ownership, bool isNoDerivative) {
6239+
ValueOwnership ownership, bool isolated, bool isNoDerivative) {
62316240
// FIXME(Remove InOut): The last caller that needs this is argument
62326241
// decomposition. Start by enabling the assertion there and fixing up those
62336242
// callers, then remove this, then remove
@@ -6237,7 +6246,8 @@ inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
62376246
ownership == ValueOwnership::InOut);
62386247
ownership = ValueOwnership::InOut;
62396248
}
6240-
return {isVariadic, isAutoClosure, isNonEphemeral, ownership, isNoDerivative};
6249+
return {isVariadic, isAutoClosure, isNonEphemeral, ownership, isolated,
6250+
isNoDerivative};
62416251
}
62426252

62436253
inline const Type *BoundGenericType::getTrailingObjectsPointer() const {

include/swift/Parse/Parser.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,16 +1100,21 @@ class Parser {
11001100

11011101
ParserStatus parseTypeAttributeList(ParamDecl::Specifier &Specifier,
11021102
SourceLoc &SpecifierLoc,
1103+
SourceLoc &IsolatedLoc,
11031104
TypeAttributes &Attributes) {
11041105
if (Tok.isAny(tok::at_sign, tok::kw_inout) ||
11051106
(Tok.is(tok::identifier) &&
11061107
(Tok.getRawText().equals("__shared") ||
1107-
Tok.getRawText().equals("__owned"))))
1108-
return parseTypeAttributeListPresent(Specifier, SpecifierLoc, Attributes);
1108+
Tok.getRawText().equals("__owned") ||
1109+
Tok.isContextualKeyword("isolated"))))
1110+
return parseTypeAttributeListPresent(
1111+
Specifier, SpecifierLoc, IsolatedLoc, Attributes);
11091112
return makeParserSuccess();
11101113
}
1114+
11111115
ParserStatus parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
11121116
SourceLoc &SpecifierLoc,
1117+
SourceLoc &IsolatedLoc,
11131118
TypeAttributes &Attributes);
11141119

11151120
bool parseConventionAttributeInternal(bool justChecking,
@@ -1268,7 +1273,8 @@ class Parser {
12681273

12691274
TypeRepr *applyAttributeToType(TypeRepr *Ty, const TypeAttributes &Attr,
12701275
ParamDecl::Specifier Specifier,
1271-
SourceLoc SpecifierLoc);
1276+
SourceLoc SpecifierLoc,
1277+
SourceLoc IsolatedLoc);
12721278

12731279
//===--------------------------------------------------------------------===//
12741280
// Pattern Parsing
@@ -1327,6 +1333,9 @@ class Parser {
13271333
/// The second name, the presence of which is indicated by \c SecondNameLoc.
13281334
Identifier SecondName;
13291335

1336+
/// The location of the 'isolated' keyword, if present.
1337+
SourceLoc IsolatedLoc;
1338+
13301339
/// The type following the ':'.
13311340
TypeRepr *Type = nullptr;
13321341

lib/AST/ASTContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,8 @@ void AnyFunctionType::decomposeInput(
33133313
result.emplace_back(
33143314
type->getInOutObjectType(), Identifier(),
33153315
ParameterTypeFlags::fromParameterType(type, false, false, false,
3316-
ValueOwnership::Default, false));
3316+
ValueOwnership::Default, false,
3317+
false));
33173318
return;
33183319
}
33193320
}

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3115,6 +3115,12 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
31153115
PrintWithColorRAII(OS, ParenthesisColor) << ')';
31163116
}
31173117

3118+
void visitIsolatedTypeRepr(IsolatedTypeRepr *T) {
3119+
printCommon("isolated") << '\n';
3120+
printRec(T->getBase());
3121+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3122+
}
3123+
31183124
void visitOptionalTypeRepr(OptionalTypeRepr *T) {
31193125
printCommon("type_optional") << '\n';
31203126
printRec(T->getBase());

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3345,6 +3345,10 @@ void PrintAST::printOneParameter(const ParamDecl *param,
33453345
};
33463346

33473347
printAttributes(param);
3348+
3349+
if (param->isIsolated())
3350+
Printer << "isolated ";
3351+
33483352
printArgName();
33493353

33503354
TypeLoc TheTypeLoc;

0 commit comments

Comments
 (0)