Skip to content

Commit cd543bb

Browse files
committed
[AST/Parse] Implement nonisolated(nonsending) type modifier
1 parent d0ffce7 commit cd543bb

18 files changed

+291
-5
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,6 +2782,12 @@ BridgedSendingTypeRepr_createParsed(BridgedASTContext cContext,
27822782
BridgedTypeRepr base,
27832783
BridgedSourceLoc cSpecifierLoc);
27842784

2785+
SWIFT_NAME("BridgedCallerIsolatedTypeRepr.createParsed(_:base:specifierLoc:)")
2786+
BridgedCallerIsolatedTypeRepr
2787+
BridgedCallerIsolatedTypeRepr_createParsed(BridgedASTContext cContext,
2788+
BridgedTypeRepr base,
2789+
BridgedSourceLoc cSpecifierLoc);
2790+
27852791
SWIFT_NAME(
27862792
"BridgedTupleTypeRepr.createParsed(_:elements:leftParenLoc:rightParenLoc:)")
27872793
BridgedTupleTypeRepr BridgedTupleTypeRepr_createParsed(

include/swift/AST/DiagnosticsParse.def

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,5 +2172,18 @@ ERROR(sil_thunkinst_failed_to_parse_kind,none,
21722172
ERROR(sil_failed_to_parse_sil_optional,none,
21732173
"Expected SIL optional value of the form '[' NAME ']'", ())
21742174

2175+
//------------------------------------------------------------------------------
2176+
// MARK: nonisolated(nonsending)
2177+
//------------------------------------------------------------------------------
2178+
2179+
ERROR(nonisolated_nonsending_expected_lparen,PointsToFirstBadToken,
2180+
"expected '(' following 'nonisolated'", ())
2181+
ERROR(nonisolated_nonsending_incorrect_modifier,PointsToFirstBadToken,
2182+
"expected 'nonsending' in modifier", ())
2183+
ERROR(nonisolated_nonsending_expected_rparen,PointsToFirstBadToken,
2184+
"expected '(' after 'nonisolated' modifier", ())
2185+
ERROR(nonisolated_nonsending_repeated,none,
2186+
"parameter may have at most one 'nonisolated(nonsending)' specifier", ())
2187+
21752188
#define UNDEFINE_DIAGNOSTIC_MACROS
21762189
#include "DefineDiagnosticMacros.h"

include/swift/AST/DiagnosticsSema.def

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8537,7 +8537,7 @@ GROUPED_ERROR(isolated_conformance_wrong_domain,IsolatedConformances,none,
85378537
(ActorIsolation, Type, DeclName, ActorIsolation))
85388538
85398539
//===----------------------------------------------------------------------===//
8540-
// MARK: @execution Attribute
8540+
// MARK: @execution, @concurrent and nonisolated(nonsending) attributes
85418541
//===----------------------------------------------------------------------===//
85428542
85438543
ERROR(execution_behavior_only_on_async,none,
@@ -8557,6 +8557,18 @@ ERROR(execution_behavior_type_attr_only_on_async,none,
85578557
"cannot use '@%0' on non-async function type",
85588558
(StringRef))
85598559
8560+
ERROR(nonisolated_nonsending_only_on_function_types, none,
8561+
"%0 may only be used on function types",
8562+
(TypeRepr *))
8563+
8564+
ERROR(nonisolated_nonsending_only_on_async,none,
8565+
"cannot use %0 on non-async function type",
8566+
(TypeRepr *))
8567+
8568+
ERROR(cannot_use_nonisolated_nonsending_together_with_concurrent,none,
8569+
"cannot use %0 together with '@concurrent'",
8570+
(TypeRepr *))
8571+
85608572
ERROR(execution_behavior_incompatible_isolated_parameter,none,
85618573
"cannot use %0 on %kind1 because it has "
85628574
"an isolated parameter: %2",
@@ -8579,14 +8591,26 @@ ERROR(execution_behavior_type_attr_incompatible_with_global_isolation,none,
85798591
"cannot use '@%0' because function type is isolated to a global actor %1",
85808592
(StringRef, Type))
85818593
8594+
ERROR(nonisolated_nonsending_incompatible_with_global_isolation,none,
8595+
"cannot use %0 because function type is isolated to a global actor %1",
8596+
(TypeRepr *, Type))
8597+
85828598
ERROR(execution_behavior_type_attr_incompatible_with_isolated_param,none,
85838599
"cannot use '@%0' together with an isolated parameter",
85848600
(StringRef))
85858601
8602+
ERROR(nonisolated_nonsending_incompatible_with_isolated_param,none,
8603+
"cannot use %0 together with an isolated parameter",
8604+
(TypeRepr *))
8605+
85868606
ERROR(execution_behavior_type_attr_incompatible_with_isolated_any,none,
85878607
"cannot use '@%0' together with @isolated(any)",
85888608
(StringRef))
85898609

8610+
ERROR(nonisolated_nonsending_incompatible_with_isolated_any,none,
8611+
"cannot use %0 together with @isolated(any)",
8612+
(TypeRepr *))
8613+
85908614
ERROR(invalid_function_conversion_with_non_sendable,none,
85918615
"cannot convert %0 to %1 because crossing of an isolation boundary "
85928616
"requires parameter and result types to conform to 'Sendable' protocol",

include/swift/AST/TypeRepr.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,35 @@ class SendingTypeRepr : public SpecifierTypeRepr {
12491249
static bool classof(const SendingTypeRepr *T) { return true; }
12501250
};
12511251

1252+
/// A 'nonisolated(nonsending)' function type.
1253+
/// \code
1254+
/// x : nonisolated(nonsending) () async -> Int
1255+
/// \endcode
1256+
class CallerIsolatedTypeRepr : public TypeRepr {
1257+
TypeRepr *Base;
1258+
SourceLoc Loc;
1259+
1260+
public:
1261+
CallerIsolatedTypeRepr(TypeRepr *Base, SourceLoc Loc)
1262+
: TypeRepr(TypeReprKind::CallerIsolated), Base(Base), Loc(Loc) {
1263+
assert(Base);
1264+
}
1265+
1266+
TypeRepr *getBase() const { return Base; }
1267+
1268+
static bool classof(const TypeRepr *T) {
1269+
return T->getKind() == TypeReprKind::CallerIsolated;
1270+
}
1271+
static bool classof(const CallerIsolatedTypeRepr *T) { return true; }
1272+
1273+
private:
1274+
SourceLoc getStartLocImpl() const { return Loc; }
1275+
SourceLoc getEndLocImpl() const { return Base->getEndLoc(); }
1276+
SourceLoc getLocImpl() const { return Base->getLoc(); }
1277+
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
1278+
friend class TypeRepr;
1279+
};
1280+
12521281
/// A TypeRepr for a known, fixed type.
12531282
///
12541283
/// Fixed type representations should be used sparingly, in places
@@ -1680,6 +1709,7 @@ inline bool TypeRepr::isSimple() const {
16801709
case TypeReprKind::ConstValue:
16811710
case TypeReprKind::LifetimeDependent:
16821711
case TypeReprKind::Integer:
1712+
case TypeReprKind::CallerIsolated:
16831713
return true;
16841714
}
16851715
llvm_unreachable("bad TypeRepr kind");

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ TYPEREPR(Fixed, TypeRepr)
7777
TYPEREPR(SILBox, TypeRepr)
7878
TYPEREPR(Self, TypeRepr)
7979
TYPEREPR(LifetimeDependent, TypeRepr)
80+
TYPEREPR(CallerIsolated, TypeRepr)
8081
TYPEREPR(Integer, TypeRepr)
8182
LAST_TYPEREPR(Integer)
8283

include/swift/Parse/Parser.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,8 @@ class Parser {
11691169
Tok.isContextualKeyword("isolated") ||
11701170
Tok.isContextualKeyword("_const"))
11711171
return true;
1172+
if (isCallerIsolatedSpecifier())
1173+
return true;
11721174
if (Context.LangOpts.hasFeature(Feature::SendingArgsAndResults) &&
11731175
Tok.isContextualKeyword("sending"))
11741176
return true;
@@ -1187,6 +1189,12 @@ class Parser {
11871189
(peekToken().isContextualKeyword("lifetime"));
11881190
}
11891191

1192+
bool isCallerIsolatedSpecifier() {
1193+
if (!Tok.isContextualKeyword("nonisolated"))
1194+
return false;
1195+
return peekToken().isFollowingLParen();
1196+
}
1197+
11901198
bool canHaveParameterSpecifierContextualKeyword() {
11911199
// The parameter specifiers like `isolated`, `consuming`, `borrowing` are
11921200
// also valid identifiers and could be the name of a type. Check whether
@@ -1421,6 +1429,7 @@ class Parser {
14211429
SourceLoc IsolatedLoc;
14221430
SourceLoc ConstLoc;
14231431
SourceLoc SendingLoc;
1432+
SourceLoc CallerIsolatedLoc;
14241433
SmallVector<TypeOrCustomAttr> Attributes;
14251434
LifetimeEntry *lifetimeEntry = nullptr;
14261435

@@ -1723,6 +1732,10 @@ class Parser {
17231732
/// Returns true if a qualified declaration name base type can be parsed.
17241733
bool canParseBaseTypeForQualifiedDeclName();
17251734

1735+
/// Returns true if `nonisolated` contextual keyword could be parsed
1736+
/// as part of the type a the current location.
1737+
bool canParseNonisolatedAsTypeModifier();
1738+
17261739
/// Returns true if the current token is '->' or effects specifiers followed
17271740
/// by '->'.
17281741
///

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4646,6 +4646,12 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr, void, Label>,
46464646
printFoot();
46474647
}
46484648

4649+
void visitCallerIsolatedTypeRepr(CallerIsolatedTypeRepr *T, Label label) {
4650+
printCommon("caller_isolated", label);
4651+
printRec(T->getBase(), Label::optional("base"));
4652+
printFoot();
4653+
}
4654+
46494655
void visitCompileTimeLiteralTypeRepr(CompileTimeLiteralTypeRepr *T, Label label) {
46504656
printCommon("_const", label);
46514657
printRec(T->getBase(), Label::optional("base"));

lib/AST/ASTWalker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,6 +2324,10 @@ bool Traversal::visitSendingTypeRepr(SendingTypeRepr *T) {
23242324
return doIt(T->getBase());
23252325
}
23262326

2327+
bool Traversal::visitCallerIsolatedTypeRepr(CallerIsolatedTypeRepr *T) {
2328+
return doIt(T->getBase());
2329+
}
2330+
23272331
bool Traversal::visitCompileTimeLiteralTypeRepr(CompileTimeLiteralTypeRepr *T) {
23282332
return doIt(T->getBase());
23292333
}

lib/AST/Bridging/TypeReprBridging.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ BridgedSendingTypeRepr_createParsed(BridgedASTContext cContext,
211211
SendingTypeRepr(base.unbridged(), cSpecifierLoc.unbridged());
212212
}
213213

214+
BridgedCallerIsolatedTypeRepr
215+
BridgedCallerIsolatedTypeRepr_createParsed(BridgedASTContext cContext,
216+
BridgedTypeRepr base,
217+
BridgedSourceLoc cSpecifierLoc) {
218+
return new (cContext.unbridged())
219+
CallerIsolatedTypeRepr(base.unbridged(), cSpecifierLoc.unbridged());
220+
}
221+
214222
BridgedVarargTypeRepr
215223
BridgedVarargTypeRepr_createParsed(BridgedASTContext cContext,
216224
BridgedTypeRepr base,

lib/AST/NameLookup.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3209,6 +3209,12 @@ directReferencesForTypeRepr(Evaluator &evaluator, ASTContext &ctx,
32093209
isolated->getBase(), dc, options);
32103210
}
32113211

3212+
case TypeReprKind::CallerIsolated: {
3213+
auto callerIsolated = cast<CallerIsolatedTypeRepr>(typeRepr);
3214+
return directReferencesForTypeRepr(evaluator, ctx,
3215+
callerIsolated->getBase(), dc, options);
3216+
}
3217+
32123218
case TypeReprKind::Composition: {
32133219
auto composition = cast<CompositionTypeRepr>(typeRepr);
32143220
for (auto component : composition->getTypes()) {

0 commit comments

Comments
 (0)