Skip to content

Commit e1bf198

Browse files
committed
[Sema] Put effects checking behind a request for experimental lazy
type checking.
1 parent 55e9f37 commit e1bf198

File tree

7 files changed

+71
-24
lines changed

7 files changed

+71
-24
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2475,8 +2475,12 @@ class PatternBindingDecl final : public Decl,
24752475
getMutablePatternList()[i].setOriginalInit(E);
24762476
}
24772477

2478-
/// Returns a fully typechecked init expression for the pattern at the given
2478+
/// Returns a typechecked init expression for the pattern at the given
24792479
/// index.
2480+
Expr *getContextualizedInit(unsigned i) const;
2481+
2482+
/// Returns an init expression for the pattern at the given index.
2483+
/// The initializer is fully type checked, including effects checking.
24802484
Expr *getCheckedAndContextualizedInit(unsigned i) const;
24812485

24822486
/// Returns the result of `getCheckedAndContextualizedInit()` if the init is

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3929,6 +3929,25 @@ class CheckInconsistentWeakLinkedImportsRequest
39293929
bool isCached() const { return true; }
39303930
};
39313931

3932+
/// Run effects checking for an initializer expression.
3933+
class CheckInitEffectsRequest
3934+
: public SimpleRequest<CheckInitEffectsRequest,
3935+
evaluator::SideEffect(Initializer *, Expr *),
3936+
RequestFlags::Cached> {
3937+
public:
3938+
using SimpleRequest::SimpleRequest;
3939+
3940+
private:
3941+
friend SimpleRequest;
3942+
3943+
evaluator::SideEffect evaluate(Evaluator &evaluator,
3944+
Initializer *initCtx,
3945+
Expr *init) const;
3946+
3947+
public:
3948+
bool isCached() const { return true; }
3949+
};
3950+
39323951
/// Retrieves the primary source files in the main module.
39333952
// FIXME: This isn't really a type-checking request, if we ever split off a
39343953
// zone for more basic AST requests, this should be moved there.

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ SWIFT_REQUEST(TypeChecker, CheckInconsistentAccessLevelOnImportSameFileRequest,
4343
evaluator::SideEffect(SourceFile *), Cached, NoLocationInfo)
4444
SWIFT_REQUEST(TypeChecker, CheckInconsistentWeakLinkedImportsRequest,
4545
evaluator::SideEffect(ModuleDecl *), Cached, NoLocationInfo)
46+
SWIFT_REQUEST(TypeChecker, CheckInitEffectsRequest,
47+
evaluator::SideEffect(Initializer *, Expr *),
48+
Cached, NoLocationInfo)
4649
SWIFT_REQUEST(TypeChecker, CheckRedeclarationRequest,
4750
evaluator::SideEffect(ValueDecl *),
4851
Uncached, NoLocationInfo)

lib/AST/Decl.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,11 +2344,35 @@ PatternBindingDecl::getInitializerIsolation(unsigned i) const {
23442344
return var->getInitializerIsolation();
23452345
}
23462346

2347+
Expr *PatternBindingDecl::getContextualizedInit(unsigned i) const {
2348+
auto *mutableThis = const_cast<PatternBindingDecl *>(this);
2349+
return evaluateOrDefault(
2350+
getASTContext().evaluator,
2351+
PatternBindingCheckedAndContextualizedInitRequest{mutableThis, i},
2352+
nullptr);
2353+
}
2354+
23472355
Expr *PatternBindingDecl::getCheckedAndContextualizedInit(unsigned i) const {
2348-
return evaluateOrDefault(getASTContext().evaluator,
2349-
PatternBindingCheckedAndContextualizedInitRequest{
2350-
const_cast<PatternBindingDecl *>(this), i},
2351-
nullptr);
2356+
auto *expr = getContextualizedInit(i);
2357+
2358+
if (auto *initContext = getInitContext(i)) {
2359+
// Property wrapper isolation is checked separately while
2360+
// synthesizing the backing property wrapper initializer.
2361+
auto *var = getSingleVar();
2362+
if (!(var && var->hasAttachedPropertyWrapper())) {
2363+
(void)getInitializerIsolation(i);
2364+
}
2365+
2366+
// Effects checking for 'async' needs actor isolation to be
2367+
// computed. Always run effects checking after the actor
2368+
// isolation checker.
2369+
evaluateOrDefault(
2370+
getASTContext().evaluator,
2371+
CheckInitEffectsRequest{initContext, expr},
2372+
{});
2373+
}
2374+
2375+
return expr;
23522376
}
23532377

23542378
Expr *PatternBindingDecl::getCheckedAndContextualizedExecutableInit(

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6036,7 +6036,7 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
60366036
auto i = pbd->getPatternEntryIndexForVarDecl(var);
60376037

60386038
dc = cast<Initializer>(pbd->getInitContext(i));
6039-
initExpr = pbd->getCheckedAndContextualizedInit(i);
6039+
initExpr = pbd->getContextualizedInit(i);
60406040
enclosingIsolation = getActorIsolation(var);
60416041
} else if (auto *param = dyn_cast<ParamDecl>(var)) {
60426042
// If this parameter corresponds to a stored property for a

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,22 +2885,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
28852885
// Trigger a request that will complete typechecking for the
28862886
// initializer.
28872887
(void) PBD->getCheckedAndContextualizedInit(i);
2888-
2889-
if (auto *var = PBD->getSingleVar()) {
2890-
if (var->hasAttachedPropertyWrapper())
2891-
return;
2892-
}
2893-
2894-
if (!PBD->getDeclContext()->isLocalContext()) {
2895-
(void) PBD->getInitializerIsolation(i);
2896-
}
2897-
2898-
// Effects checking for 'async' needs actor isolation to be computed.
2899-
// Always run effects checking after the actor isolation checker.
2900-
if (auto *initContext = PBD->getInitContext(i)) {
2901-
auto *init = PBD->getInit(i);
2902-
TypeChecker::checkInitializerEffects(initContext, init);
2903-
}
29042888
}
29052889
}
29062890

lib/Sema/TypeCheckEffects.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3794,12 +3794,25 @@ void TypeChecker::checkFunctionEffects(AbstractFunctionDecl *fn) {
37943794
superInit->walk(checker);
37953795
}
37963796

3797-
void TypeChecker::checkInitializerEffects(Initializer *initCtx,
3798-
Expr *init) {
3797+
evaluator::SideEffect
3798+
CheckInitEffectsRequest::evaluate(Evaluator &evaluator,
3799+
Initializer *initCtx,
3800+
Expr *init) const {
37993801
auto &ctx = initCtx->getASTContext();
38003802
CheckEffectsCoverage checker(ctx, Context::forInitializer(initCtx));
38013803
init->walk(checker);
38023804
init->walk(LocalFunctionEffectsChecker());
3805+
3806+
return {};
3807+
}
3808+
3809+
3810+
void TypeChecker::checkInitializerEffects(Initializer *initCtx,
3811+
Expr *init) {
3812+
evaluateOrDefault(
3813+
initCtx->getASTContext().evaluator,
3814+
CheckInitEffectsRequest{initCtx, init},
3815+
{});
38033816
}
38043817

38053818
void TypeChecker::checkCallerSideDefaultArgumentEffects(DeclContext *initCtx,

0 commit comments

Comments
 (0)