Skip to content

Commit 255009d

Browse files
committed
Implement #isolation macro to produce the isolation of the current context
Introduce a new expression macro that produces an value of type `(any AnyActor)?` that describes the current actor isolation. This isolation will be `nil` in non-isolated code, and refer to either the actor instance of shared global actor in other cases. This is currently behind the experimental feature flag OptionalIsolatedParameters.
1 parent e6a0641 commit 255009d

File tree

20 files changed

+306
-14
lines changed

20 files changed

+306
-14
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,9 @@ enum ENUM_EXTENSIBILITY_ATTR(open) BridgedMacroDefinitionKind : size_t {
14921492
/// or the new spelling `#externalMacro(module: "Module", type: "Type")`.
14931493
BridgedExternalMacro,
14941494
/// The builtin definition for "externalMacro".
1495-
BridgedBuiltinExternalMacro
1495+
BridgedBuiltinExternalMacro,
1496+
/// The builtin definition for the "isolation" macro.
1497+
BridgedBuiltinIsolationMacro,
14961498
};
14971499

14981500
SWIFT_NAME("BridgedGenericParamList.createParsed(_:leftAngleLoc:parameters:"

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5564,6 +5564,8 @@ ERROR(isolated_parameter_global_actor_type,none,
55645564
ERROR(isolated_parameter_combined_nonisolated,none,
55655565
"%0 with 'isolated' parameter cannot be 'nonisolated'",
55665566
(DescriptiveDeclKind))
5567+
ERROR(isolation_macro_experimental,none,
5568+
"#isolation macro is experimental", ())
55675569

55685570
NOTE(in_derived_conformance, none,
55695571
"in derived conformance to %0",

include/swift/AST/Expr.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6089,6 +6089,39 @@ class KeyPathExpr : public Expr {
60896089
}
60906090
};
60916091

6092+
/// Provides a value of type `(any Actor)?` that represents the actor
6093+
/// isolation of the current context, or `nil` if this is non-isolated
6094+
/// code.
6095+
///
6096+
/// This expression node is implicitly created by the type checker, and
6097+
/// has no in-source spelling.
6098+
class CurrentContextIsolationExpr : public Expr {
6099+
Expr *actorExpr = nullptr;
6100+
SourceLoc implicitLoc;
6101+
6102+
public:
6103+
CurrentContextIsolationExpr(SourceLoc implicitLoc, Type type)
6104+
: Expr(ExprKind::CurrentContextIsolation, /*isImplicit=*/true, type),
6105+
implicitLoc(implicitLoc) {}
6106+
6107+
/// The expression that produces the actor isolation value.
6108+
Expr *getActor() const { return actorExpr; }
6109+
6110+
void setActor(Expr *expr) {
6111+
actorExpr = expr;
6112+
}
6113+
6114+
SourceLoc getLoc() const { return implicitLoc; }
6115+
6116+
SourceRange getSourceRange() const {
6117+
return SourceRange(implicitLoc, implicitLoc);
6118+
}
6119+
6120+
static bool classof(const Expr *E) {
6121+
return E->getKind() == ExprKind::CurrentContextIsolation;
6122+
}
6123+
};
6124+
60926125
/// Represents the unusual behavior of a . in a \ keypath expression, such as
60936126
/// \.[0] and \Foo.?.
60946127
class KeyPathDotExpr : public Expr {

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ EXPR(LazyInitializer, Expr)
207207
EXPR(EditorPlaceholder, Expr)
208208
EXPR(ObjCSelector, Expr)
209209
EXPR(KeyPath, Expr)
210+
EXPR(CurrentContextIsolation, Expr)
210211
EXPR(SingleValueStmt, Expr)
211212
UNCHECKED_EXPR(KeyPathDot, Expr)
212213
UNCHECKED_EXPR(OneWay, Expr)

include/swift/AST/MacroDefinition.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ struct ExternalMacroReference {
5858
enum class BuiltinMacroKind: uint8_t {
5959
/// #externalMacro, which references an external macro.
6060
ExternalMacro,
61+
/// #isolation, which produces the isolation of the current context
62+
IsolationMacro,
6163
};
6264

6365
/// A single replacement

lib/AST/ASTContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,7 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
11441144
M = getLoadedModule(Id_Differentiation);
11451145
break;
11461146
case KnownProtocolKind::Actor:
1147+
case KnownProtocolKind::AnyActor:
11471148
case KnownProtocolKind::GlobalActor:
11481149
case KnownProtocolKind::AsyncSequence:
11491150
case KnownProtocolKind::AsyncIteratorProtocol:

lib/AST/ASTDumper.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,6 +3147,15 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, StringRef>,
31473147
printFoot();
31483148
}
31493149

3150+
void visitCurrentContextIsolationExpr(
3151+
CurrentContextIsolationExpr *E, StringRef label) {
3152+
printCommon(E, "current_context_isolation_expr", label);
3153+
if (auto actor = E->getActor())
3154+
printRec(actor);
3155+
3156+
printFoot();
3157+
}
3158+
31503159
void visitKeyPathDotExpr(KeyPathDotExpr *E, StringRef label) {
31513160
printCommon(E, "key_path_dot_expr", label);
31523161
printFoot();

lib/AST/ASTPrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5384,6 +5384,9 @@ void PrintAST::visitMacroDecl(MacroDecl *decl) {
53845384
case BuiltinMacroKind::ExternalMacro:
53855385
Printer << "ExternalMacro";
53865386
break;
5387+
case BuiltinMacroKind::IsolationMacro:
5388+
Printer << "IsolationMacro";
5389+
break;
53875390
}
53885391
break;
53895392

@@ -5653,6 +5656,12 @@ void PrintAST::visitEnumIsCaseExpr(EnumIsCaseExpr *expr) {
56535656
void PrintAST::visitForceValueExpr(ForceValueExpr *expr) {
56545657
}
56555658

5659+
void PrintAST::visitCurrentContextIsolationExpr(
5660+
CurrentContextIsolationExpr *expr) {
5661+
if (auto actor = expr->getActor())
5662+
visit(actor);
5663+
}
5664+
56565665
void PrintAST::visitKeyPathDotExpr(KeyPathDotExpr *expr) {
56575666
}
56585667

lib/AST/ASTWalker.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,17 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
13151315
return E;
13161316
}
13171317

1318+
Expr *visitCurrentContextIsolationExpr(CurrentContextIsolationExpr *E) {
1319+
if (auto actor = E->getActor()) {
1320+
if (auto newActor = doIt(actor))
1321+
E->setActor(newActor);
1322+
else
1323+
return nullptr;
1324+
}
1325+
1326+
return E;
1327+
}
1328+
13181329
Expr *visitKeyPathDotExpr(KeyPathDotExpr *E) { return E; }
13191330

13201331
Expr *visitSingleValueStmtExpr(SingleValueStmtExpr *E) {

lib/AST/Expr.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,9 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
321321
return cast<Id##Expr>(this)->Getter()
322322
#define PASS_THROUGH_REFERENCE(Id, GetSubExpr) \
323323
case ExprKind::Id: \
324-
return cast<Id##Expr>(this) \
325-
->GetSubExpr()->getReferencedDecl(stopAtParenExpr)
324+
if (auto sub = cast<Id##Expr>(this)->GetSubExpr()) \
325+
return sub->getReferencedDecl(stopAtParenExpr); \
326+
return ConcreteDeclRef();
326327

327328
NO_REFERENCE(Error);
328329
SIMPLE_REFERENCE(NilLiteral, getInitializer);
@@ -469,6 +470,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
469470
NO_REFERENCE(ObjCSelector);
470471
NO_REFERENCE(KeyPath);
471472
NO_REFERENCE(KeyPathDot);
473+
PASS_THROUGH_REFERENCE(CurrentContextIsolation, getActor);
472474
PASS_THROUGH_REFERENCE(OneWay, getSubExpr);
473475
NO_REFERENCE(Tap);
474476
NO_REFERENCE(TypeJoin);
@@ -842,6 +844,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
842844
return true;
843845

844846
case ExprKind::MacroExpansion:
847+
case ExprKind::CurrentContextIsolation:
845848
return true;
846849
}
847850

@@ -1022,6 +1025,7 @@ bool Expr::isValidParentOfTypeExpr(Expr *typeExpr) const {
10221025
case ExprKind::SingleValueStmt:
10231026
case ExprKind::TypeJoin:
10241027
case ExprKind::MacroExpansion:
1028+
case ExprKind::CurrentContextIsolation:
10251029
return false;
10261030
}
10271031

0 commit comments

Comments
 (0)