Skip to content

Commit 810f1cd

Browse files
committed
[Sema] Perform actor isolation checking across the whole function at once.
Rather than performing actor isolation checking as part of "miscellaneous" diagnostics on an expression, do it on the whole function at once. This should not change behavior by itself.
1 parent c4abccb commit 810f1cd

File tree

7 files changed

+63
-11
lines changed

7 files changed

+63
-11
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4612,7 +4612,6 @@ void swift::performSyntacticExprDiagnostics(const Expr *E,
46124612
if (ctx.LangOpts.EnableObjCInterop)
46134613
diagDeprecatedObjCSelectors(DC, E);
46144614
diagnoseConstantArgumentRequirement(E, DC);
4615-
checkActorIsolation(E, DC);
46164615
}
46174616

46184617
void swift::performStmtDiagnostics(const Stmt *S, DeclContext *DC) {

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,10 @@ findMemberReference(Expr *expr) {
578578
return None;
579579
}
580580

581-
void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
582-
class ActorIsolationWalker : public ASTWalker {
581+
namespace {
582+
/// Check for adherence to the actor isolation rules, emitting errors
583+
/// when actor-isolated declarations are used in an unsafe manner.
584+
class ActorIsolationChecker : public ASTWalker {
583585
ASTContext &ctx;
584586
SmallVector<const DeclContext *, 4> contextStack;
585587

@@ -588,18 +590,22 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
588590
}
589591

590592
public:
591-
ActorIsolationWalker(const DeclContext *dc) : ctx(dc->getASTContext()) {
593+
ActorIsolationChecker(const DeclContext *dc) : ctx(dc->getASTContext()) {
592594
contextStack.push_back(dc);
593595
}
594596

595-
bool shouldWalkIntoSeparatelyCheckedClosure(ClosureExpr *expr) override {
596-
return false;
597-
}
598-
599597
bool shouldWalkCaptureInitializerExpressions() override { return true; }
600598

601599
bool shouldWalkIntoTapExpression() override { return false; }
602600

601+
bool walkToDeclPre(Decl *D) override {
602+
// Don't walk into functions; they'll be handled separately.
603+
if (isa<AbstractFunctionDecl>(D))
604+
return false;
605+
606+
return true;
607+
}
608+
603609
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
604610
if (auto *closure = dyn_cast<AbstractClosureExpr>(expr)) {
605611
contextStack.push_back(closure);
@@ -1011,9 +1017,38 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
10111017
llvm_unreachable("unhandled actor isolation kind!");
10121018
}
10131019
};
1020+
}
1021+
1022+
void swift::checkTopLevelActorIsolation(TopLevelCodeDecl *decl) {
1023+
ActorIsolationChecker checker(decl);
1024+
decl->getBody()->walk(checker);
1025+
}
1026+
1027+
void swift::checkFunctionActorIsolation(AbstractFunctionDecl *decl) {
1028+
ActorIsolationChecker checker(decl);
1029+
if (auto body = decl->getBody()) {
1030+
body->walk(checker);
1031+
}
1032+
if (auto ctor = dyn_cast<ConstructorDecl>(decl))
1033+
if (auto superInit = ctor->getSuperInitCall())
1034+
superInit->walk(checker);
1035+
}
1036+
1037+
void swift::checkInitializerActorIsolation(Initializer *init, Expr *expr) {
1038+
ActorIsolationChecker checker(init);
1039+
expr->walk(checker);
1040+
}
1041+
1042+
void swift::checkEnumElementActorIsolation(
1043+
EnumElementDecl *element, Expr *expr) {
1044+
ActorIsolationChecker checker(element);
1045+
expr->walk(checker);
1046+
}
10141047

1015-
ActorIsolationWalker walker(dc);
1016-
const_cast<Expr *>(expr)->walk(walker);
1048+
void swift::checkPropertyWrapperActorIsolation(
1049+
PatternBindingDecl *binding, Expr *expr) {
1050+
ActorIsolationChecker checker(binding->getDeclContext());
1051+
expr->walk(checker);
10171052
}
10181053

10191054
/// Determine actor isolation solely from attributes.

lib/Sema/TypeCheckConcurrency.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,19 @@
2222

2323
namespace swift {
2424

25+
class AbstractFunctionDecl;
2526
class ActorIsolation;
2627
class ASTContext;
2728
class ClassDecl;
2829
class ConcreteDeclRef;
2930
class Decl;
3031
class DeclContext;
32+
class EnumElementDecl;
3133
class Expr;
3234
class FuncDecl;
35+
class Initializer;
36+
class PatternBindingDecl;
37+
class TopLevelCodeDecl;
3338
class TypeBase;
3439
class ValueDecl;
3540

@@ -38,7 +43,12 @@ class ValueDecl;
3843
void addAsyncNotes(FuncDecl *func);
3944

4045
/// Check actor isolation rules.
41-
void checkActorIsolation(const Expr *expr, const DeclContext *dc);
46+
void checkTopLevelActorIsolation(TopLevelCodeDecl *decl);
47+
void checkFunctionActorIsolation(AbstractFunctionDecl *decl);
48+
void checkInitializerActorIsolation(Initializer *init, Expr *expr);
49+
void checkEnumElementActorIsolation(EnumElementDecl *element, Expr *expr);
50+
void checkPropertyWrapperActorIsolation(
51+
PatternBindingDecl *binding, Expr *expr);
4252

4353
/// The isolation restriction in effect for a given declaration that is
4454
/// referenced from source.

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ EnumRawValuesRequest::evaluate(Evaluator &eval, EnumDecl *ED,
12011201
if (TypeChecker::typeCheckExpression(
12021202
exprToCheck, ED,
12031203
/*contextualInfo=*/{rawTy, CTP_EnumCaseRawValue})) {
1204+
checkEnumElementActorIsolation(elt, exprToCheck);
12041205
TypeChecker::checkEnumElementEffects(elt, exprToCheck);
12051206
}
12061207
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,7 @@ Expr *DefaultArgumentExprRequest::evaluate(Evaluator &evaluator,
910910
return new (ctx) ErrorExpr(initExpr->getSourceRange(), ErrorType::get(ctx));
911911
}
912912

913+
checkInitializerActorIsolation(dc, initExpr);
913914
TypeChecker::checkInitializerEffects(dc, initExpr);
914915

915916
// Walk the checked initializer and contextualize any closures
@@ -1746,6 +1747,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
17461747
PBD->getInitContext(i));
17471748
if (initContext) {
17481749
// Check safety of error-handling in the declaration, too.
1750+
checkInitializerActorIsolation(initContext, init);
17491751
TypeChecker::checkInitializerEffects(initContext, init);
17501752
TypeChecker::contextualizeInitializer(initContext, init);
17511753
}

lib/Sema/TypeCheckStmt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "TypeChecker.h"
1818
#include "TypeCheckAvailability.h"
19+
#include "TypeCheckConcurrency.h"
1920
#include "TypeCheckType.h"
2021
#include "MiscDiagnostics.h"
2122
#include "swift/Subsystems.h"
@@ -2066,6 +2067,7 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
20662067
if (!hadError)
20672068
performAbstractFuncDeclDiagnostics(AFD);
20682069

2070+
checkFunctionActorIsolation(AFD);
20692071
TypeChecker::checkFunctionEffects(AFD);
20702072
TypeChecker::computeCaptures(AFD);
20712073

@@ -2108,6 +2110,7 @@ void TypeChecker::typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD) {
21082110
BraceStmt *Body = TLCD->getBody();
21092111
StmtChecker(TLCD).typeCheckStmt(Body);
21102112
TLCD->setBody(Body);
2113+
checkTopLevelActorIsolation(TLCD);
21112114
checkTopLevelEffects(TLCD);
21122115
performTopLevelDeclDiagnostics(TLCD);
21132116
}

lib/Sema/TypeCheckStorage.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "CodeSynthesis.h"
1919
#include "TypeChecker.h"
2020
#include "TypeCheckAvailability.h"
21+
#include "TypeCheckConcurrency.h"
2122
#include "TypeCheckDecl.h"
2223
#include "TypeCheckType.h"
2324
#include "swift/AST/ASTContext.h"
@@ -2508,6 +2509,7 @@ static void typeCheckSynthesizedWrapperInitializer(
25082509
dyn_cast_or_null<Initializer>(pbd->getInitContext(i))) {
25092510
TypeChecker::contextualizeInitializer(initializerContext, initializer);
25102511
}
2512+
checkPropertyWrapperActorIsolation(pbd, initializer);
25112513
TypeChecker::checkPropertyWrapperEffects(pbd, initializer);
25122514
}
25132515

0 commit comments

Comments
 (0)