Skip to content

Commit 690d6c4

Browse files
committed
[AST] Record whether a closure was type-checked in its enclosing expression
Rather than using various "applied function builder" and "is single expression body" checks to determine whether a closure was type-checked in its enclosing expression, record in the closure expression whether it actually *was* type-checked as part of its enclosing expression.
1 parent 8c20bcd commit 690d6c4

File tree

5 files changed

+28
-11
lines changed

5 files changed

+28
-11
lines changed

include/swift/AST/Expr.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3774,7 +3774,7 @@ class ClosureExpr : public AbstractClosureExpr {
37743774
/// The bit indicates whether this closure has had a function builder
37753775
/// applied to it.
37763776
llvm::PointerIntPair<VarDecl *, 1, bool> CapturedSelfDeclAndAppliedBuilder;
3777-
3777+
37783778
/// The location of the "throws", if present.
37793779
SourceLoc ThrowsLoc;
37803780

@@ -3786,7 +3786,8 @@ class ClosureExpr : public AbstractClosureExpr {
37863786
SourceLoc InLoc;
37873787

37883788
/// The explicitly-specified result type.
3789-
TypeExpr *ExplicitResultType;
3789+
llvm::PointerIntPair<TypeExpr *, 1, bool>
3790+
ExplicitResultTypeAndEnclosingChecked;
37903791

37913792
/// The body of the closure, along with a bit indicating whether it
37923793
/// was originally just a single expression.
@@ -3801,7 +3802,8 @@ class ClosureExpr : public AbstractClosureExpr {
38013802
BracketRange(bracketRange),
38023803
CapturedSelfDeclAndAppliedBuilder(capturedSelfDecl, false),
38033804
ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc),
3804-
ExplicitResultType(explicitResultType), Body(nullptr) {
3805+
ExplicitResultTypeAndEnclosingChecked(explicitResultType, false),
3806+
Body(nullptr) {
38053807
setParameterList(params);
38063808
Bits.ClosureExpr.HasAnonymousClosureVars = false;
38073809
}
@@ -3855,13 +3857,15 @@ class ClosureExpr : public AbstractClosureExpr {
38553857

38563858
Type getExplicitResultType() const {
38573859
assert(hasExplicitResultType() && "No explicit result type");
3858-
return ExplicitResultType->getInstanceType();
3860+
return ExplicitResultTypeAndEnclosingChecked.getPointer()
3861+
->getInstanceType();
38593862
}
38603863
void setExplicitResultType(Type ty);
38613864

38623865
TypeRepr *getExplicitResultTypeRepr() const {
38633866
assert(hasExplicitResultType() && "No explicit result type");
3864-
return ExplicitResultType->getTypeRepr();
3867+
return ExplicitResultTypeAndEnclosingChecked.getPointer()
3868+
->getTypeRepr();
38653869
}
38663870

38673871
/// Determine whether the closure has a single expression for its
@@ -3918,6 +3922,16 @@ class ClosureExpr : public AbstractClosureExpr {
39183922
CapturedSelfDeclAndAppliedBuilder.setInt(flag);
39193923
}
39203924

3925+
/// Whether this closure's body was type checked within the enclosing
3926+
/// context.
3927+
bool wasTypeCheckedInEnclosingContext() const {
3928+
return ExplicitResultTypeAndEnclosingChecked.getInt();
3929+
}
3930+
3931+
void setTypeCheckedInEnclosingContext(bool flag = true) {
3932+
ExplicitResultTypeAndEnclosingChecked.setInt(flag);
3933+
}
3934+
39213935
static bool classof(const Expr *E) {
39223936
return E->getKind() == ExprKind::Closure;
39233937
}

lib/AST/Expr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1923,7 +1923,8 @@ bool ClosureExpr::capturesSelfEnablingImplictSelf() const {
19231923

19241924
void ClosureExpr::setExplicitResultType(Type ty) {
19251925
assert(ty && !ty->hasTypeVariable());
1926-
ExplicitResultType->setType(MetatypeType::get(ty));
1926+
ExplicitResultTypeAndEnclosingChecked.getPointer()
1927+
->setType(MetatypeType::get(ty));
19271928
}
19281929

19291930
FORWARD_SOURCE_LOCS_TO(AutoClosureExpr, Body)

lib/Sema/CSClosure.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ SolutionApplicationToFunctionResult ConstraintSystem::applySolution(
331331
fn.setBody(newBody, /*isSingleExpression=*/false);
332332
if (closure) {
333333
closure->setAppliedFunctionBuilder();
334+
closure->setTypeCheckedInEnclosingContext();
334335
solution.setExprTypes(closure);
335336
}
336337

@@ -343,6 +344,7 @@ SolutionApplicationToFunctionResult ConstraintSystem::applySolution(
343344
solution, closure, closureFnType->getResult(), rewriteTarget);
344345
application.visit(fn.getBody());
345346

347+
closure->setTypeCheckedInEnclosingContext();
346348
return SolutionApplicationToFunctionResult::Success;
347349
}
348350

lib/Sema/MiscDiagnostics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
8686

8787
bool walkToDeclPre(Decl *D) override {
8888
if (auto *closure = dyn_cast<ClosureExpr>(D->getDeclContext()))
89-
return closure->hasAppliedFunctionBuilder();
89+
return closure->wasTypeCheckedInEnclosingContext();
9090
return false;
9191
}
9292

@@ -1459,7 +1459,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
14591459
// Don't walk into nested decls.
14601460
bool walkToDeclPre(Decl *D) override {
14611461
if (auto *closure = dyn_cast<ClosureExpr>(D->getDeclContext()))
1462-
return closure->hasAppliedFunctionBuilder();
1462+
return closure->wasTypeCheckedInEnclosingContext();
14631463
return false;
14641464
}
14651465

lib/Sema/TypeCheckStmt.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ namespace {
140140
}
141141
}
142142

143-
// If the closure has a single expression body or has had a function
144-
// builder applied to it, we need to walk into it with a new sequence.
143+
// If the closure was type checked within its enclosing context,
144+
// we need to walk into it with a new sequence.
145145
// Otherwise, it'll have been separately type-checked.
146-
if (CE->hasSingleExpressionBody() || CE->hasAppliedFunctionBuilder())
146+
if (CE->wasTypeCheckedInEnclosingContext())
147147
CE->getBody()->walk(ContextualizeClosures(CE));
148148

149149
TypeChecker::computeCaptures(CE);

0 commit comments

Comments
 (0)