Skip to content

Commit db49cb1

Browse files
committed
[Concurrency] Parse and add 'isolated' parameters to the type system.
(cherry picked from commit bd8626f)
1 parent 7a8dfa9 commit db49cb1

26 files changed

+249
-57
lines changed

include/swift/AST/Attr.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,12 @@ CONTEXTUAL_SIMPLE_DECL_ATTR(spawn, Spawn,
662662
APIBreakingToAdd | APIBreakingToRemove,
663663
117)
664664

665+
CONTEXTUAL_SIMPLE_DECL_ATTR(isolated, Isolated,
666+
DeclModifier | OnParam |
667+
ABIBreakingToAdd | ABIBreakingToRemove |
668+
APIBreakingToAdd | APIBreakingToRemove,
669+
118)
670+
665671
#undef TYPE_ATTR
666672
#undef DECL_ATTR_ALIAS
667673
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Decl.h

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

52075207
TypeRepr *TyRepr = nullptr;
52085208

5209-
struct StoredDefaultArgument {
5209+
struct alignas(1 << DeclAlignInBits) StoredDefaultArgument {
52105210
PointerUnion<Expr *, VarDecl *> DefaultArg;
52115211

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

52285228
/// Whether or not this parameter is `@autoclosure`.
52295229
IsAutoClosure = 1 << 1,
5230+
5231+
/// Whether or not this parameter is 'isolated'.
5232+
IsIsolated = 1 << 2,
52305233
};
52315234

52325235
/// The default value, if any, along with flags.
5233-
llvm::PointerIntPair<StoredDefaultArgument *, 2, OptionSet<Flags>>
5236+
llvm::PointerIntPair<StoredDefaultArgument *, 3, OptionSet<Flags>>
52345237
DefaultValueAndFlags;
52355238

52365239
friend class ParamSpecifierRequest;
@@ -5381,6 +5384,17 @@ class ParamDecl : public VarDecl {
53815384
: flags - Flags::IsAutoClosure);
53825385
}
53835386

5387+
/// Whether or not this parameter is marked with 'isolated'.
5388+
bool isIsolated() const {
5389+
return DefaultValueAndFlags.getInt().contains(Flags::IsIsolated);
5390+
}
5391+
5392+
void setIsolated(bool value = true) {
5393+
auto flags = DefaultValueAndFlags.getInt();
5394+
DefaultValueAndFlags.setInt(value ? flags | Flags::IsIsolated
5395+
: flags - Flags::IsIsolated);
5396+
}
5397+
53845398
/// Does this parameter reject temporary pointer conversions?
53855399
bool isNonEphemeral() const;
53865400

include/swift/AST/DiagnosticsSema.def

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

4471+
ERROR(isolated_parameter_not_actor,none,
4472+
"'isolated' parameter has non-actor type %0", (Type))
4473+
44714474
WARNING(non_concurrent_param_type,none,
44724475
"cannot pass argument of non-sendable type %0 across actors",
44734476
(Type))
@@ -4525,6 +4528,9 @@ ERROR(nonisolated_local_var,none,
45254528
"'nonisolated' can not be applied to local variables",
45264529
())
45274530

4531+
ERROR(isolated_param_non_actor,none,
4532+
"'isolated' parameter cannot have not-actor type %0", (Type))
4533+
45284534
ERROR(actor_instance_property_wrapper,none,
45294535
"%0 property in property wrapper type %1 cannot be isolated to "
45304536
"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
@@ -1933,10 +1933,11 @@ class ParameterTypeFlags {
19331933
OwnershipShift = 3,
19341934
Ownership = 7 << OwnershipShift,
19351935
NoDerivative = 1 << 6,
1936-
NumBits = 7
1936+
Isolated = 1 << 7,
1937+
NumBits = 8
19371938
};
19381939
OptionSet<ParameterFlags> value;
1939-
static_assert(NumBits < 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
1940+
static_assert(NumBits <= 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
19401941

19411942
ParameterTypeFlags(OptionSet<ParameterFlags, uint8_t> val) : value(val) {}
19421943

@@ -1947,17 +1948,18 @@ class ParameterTypeFlags {
19471948
}
19481949

19491950
ParameterTypeFlags(bool variadic, bool autoclosure, bool nonEphemeral,
1950-
ValueOwnership ownership, bool noDerivative)
1951+
ValueOwnership ownership, bool isolated, bool noDerivative)
19511952
: value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
19521953
(nonEphemeral ? NonEphemeral : 0) |
19531954
uint8_t(ownership) << OwnershipShift |
1955+
(isolated ? Isolated : 0) |
19541956
(noDerivative ? NoDerivative : 0)) {}
19551957

19561958
/// Create one from what's present in the parameter type
19571959
inline static ParameterTypeFlags
19581960
fromParameterType(Type paramTy, bool isVariadic, bool isAutoClosure,
19591961
bool isNonEphemeral, ValueOwnership ownership,
1960-
bool isNoDerivative);
1962+
bool isolated, bool isNoDerivative);
19611963

19621964
bool isNone() const { return !value; }
19631965
bool isVariadic() const { return value.contains(Variadic); }
@@ -1966,6 +1968,7 @@ class ParameterTypeFlags {
19661968
bool isInOut() const { return getValueOwnership() == ValueOwnership::InOut; }
19671969
bool isShared() const { return getValueOwnership() == ValueOwnership::Shared;}
19681970
bool isOwned() const { return getValueOwnership() == ValueOwnership::Owned; }
1971+
bool isIsolated() const { return value.contains(Isolated); }
19691972
bool isNoDerivative() const { return value.contains(NoDerivative); }
19701973

19711974
ValueOwnership getValueOwnership() const {
@@ -2009,6 +2012,12 @@ class ParameterTypeFlags {
20092012
: value - ParameterTypeFlags::NonEphemeral);
20102013
}
20112014

2015+
ParameterTypeFlags withIsolated(bool isolated) const {
2016+
return ParameterTypeFlags(isolated
2017+
? value | ParameterTypeFlags::Isolated
2018+
: value - ParameterTypeFlags::Isolated);
2019+
}
2020+
20122021
ParameterTypeFlags withNoDerivative(bool noDerivative) const {
20132022
return ParameterTypeFlags(noDerivative
20142023
? value | ParameterTypeFlags::NoDerivative
@@ -2082,7 +2091,7 @@ class YieldTypeFlags {
20822091
return ParameterTypeFlags(/*variadic*/ false,
20832092
/*autoclosure*/ false,
20842093
/*nonEphemeral*/ false, getValueOwnership(),
2085-
/*noDerivative*/ false);
2094+
/*isolated*/ false, /*noDerivative*/ false);
20862095
}
20872096

20882097
bool operator ==(const YieldTypeFlags &other) const {
@@ -6231,7 +6240,7 @@ inline TupleTypeElt TupleTypeElt::getWithType(Type T) const {
62316240
/// Create one from what's present in the parameter decl and type
62326241
inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
62336242
Type paramTy, bool isVariadic, bool isAutoClosure, bool isNonEphemeral,
6234-
ValueOwnership ownership, bool isNoDerivative) {
6243+
ValueOwnership ownership, bool isolated, bool isNoDerivative) {
62356244
// FIXME(Remove InOut): The last caller that needs this is argument
62366245
// decomposition. Start by enabling the assertion there and fixing up those
62376246
// callers, then remove this, then remove
@@ -6241,7 +6250,8 @@ inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
62416250
ownership == ValueOwnership::InOut);
62426251
ownership = ValueOwnership::InOut;
62436252
}
6244-
return {isVariadic, isAutoClosure, isNonEphemeral, ownership, isNoDerivative};
6253+
return {isVariadic, isAutoClosure, isNonEphemeral, ownership, isolated,
6254+
isNoDerivative};
62456255
}
62466256

62476257
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
@@ -1092,16 +1092,21 @@ class Parser {
10921092

10931093
ParserStatus parseTypeAttributeList(ParamDecl::Specifier &Specifier,
10941094
SourceLoc &SpecifierLoc,
1095+
SourceLoc &IsolatedLoc,
10951096
TypeAttributes &Attributes) {
10961097
if (Tok.isAny(tok::at_sign, tok::kw_inout) ||
10971098
(Tok.is(tok::identifier) &&
10981099
(Tok.getRawText().equals("__shared") ||
1099-
Tok.getRawText().equals("__owned"))))
1100-
return parseTypeAttributeListPresent(Specifier, SpecifierLoc, Attributes);
1100+
Tok.getRawText().equals("__owned") ||
1101+
Tok.isContextualKeyword("isolated"))))
1102+
return parseTypeAttributeListPresent(
1103+
Specifier, SpecifierLoc, IsolatedLoc, Attributes);
11011104
return makeParserSuccess();
11021105
}
1106+
11031107
ParserStatus parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
11041108
SourceLoc &SpecifierLoc,
1109+
SourceLoc &IsolatedLoc,
11051110
TypeAttributes &Attributes);
11061111

11071112
bool parseConventionAttributeInternal(bool justChecking,
@@ -1260,7 +1265,8 @@ class Parser {
12601265

12611266
TypeRepr *applyAttributeToType(TypeRepr *Ty, const TypeAttributes &Attr,
12621267
ParamDecl::Specifier Specifier,
1263-
SourceLoc SpecifierLoc);
1268+
SourceLoc SpecifierLoc,
1269+
SourceLoc IsolatedLoc);
12641270

12651271
//===--------------------------------------------------------------------===//
12661272
// Pattern Parsing
@@ -1319,6 +1325,9 @@ class Parser {
13191325
/// The second name, the presence of which is indicated by \c SecondNameLoc.
13201326
Identifier SecondName;
13211327

1328+
/// The location of the 'isolated' keyword, if present.
1329+
SourceLoc IsolatedLoc;
1330+
13221331
/// The type following the ':'.
13231332
TypeRepr *Type = nullptr;
13241333

lib/AST/ASTContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3210,7 +3210,8 @@ void AnyFunctionType::decomposeInput(
32103210
result.emplace_back(
32113211
type->getInOutObjectType(), Identifier(),
32123212
ParameterTypeFlags::fromParameterType(type, false, false, false,
3213-
ValueOwnership::Default, false));
3213+
ValueOwnership::Default, false,
3214+
false));
32143215
return;
32153216
}
32163217
}

lib/AST/ASTDumper.cpp

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

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

lib/AST/ASTPrinter.cpp

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

33533353
printAttributes(param);
3354+
3355+
if (param->isIsolated())
3356+
Printer << "isolated ";
3357+
33543358
printArgName();
33553359

33563360
TypeLoc TheTypeLoc;

0 commit comments

Comments
 (0)