Skip to content

Commit 7e402e1

Browse files
committed
[Sema] Stop on-demand type checking for 'VarDecl' in 'TapExpr'
1 parent 8425e1c commit 7e402e1

File tree

6 files changed

+33
-59
lines changed

6 files changed

+33
-59
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4894,7 +4894,7 @@ class VarDecl : public AbstractStorageDecl {
48944894
};
48954895

48964896
protected:
4897-
PointerUnion<PatternBindingDecl *, Stmt *, VarDecl *, Expr *> Parent;
4897+
PointerUnion<PatternBindingDecl *, Stmt *, VarDecl *> Parent;
48984898

48994899
VarDecl(DeclKind kind, bool isStatic, Introducer introducer,
49004900
bool isCaptureList, SourceLoc nameLoc, Identifier name,
@@ -5005,22 +5005,6 @@ class VarDecl : public AbstractStorageDecl {
50055005
Parent = v;
50065006
}
50075007

5008-
/// Returns the parent expression that owns this var decl.
5009-
///
5010-
/// Concrete use cases:
5011-
/// * 'TapExpr' for interpolated string literal expression
5012-
Expr *getParentExpr() const {
5013-
if (!Parent)
5014-
return nullptr;
5015-
return Parent.dyn_cast<Expr *>();
5016-
}
5017-
5018-
/// Set \p e to be the expression that owns this var decl.
5019-
void setParentExpr(Expr *e) {
5020-
assert(e);
5021-
Parent = e;
5022-
}
5023-
50245008
NamedPattern *getNamingPattern() const;
50255009
void setNamingPattern(NamedPattern *Pat);
50265010

include/swift/AST/Expr.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,11 @@ class TapExpr : public Expr {
950950
BraceStmt * getBody() const { return Body; }
951951
void setBody(BraceStmt * b) { Body = b; }
952952

953-
SourceLoc getLoc() const { return getStartLoc(); }
953+
SourceLoc getLoc() const { return SubExpr ? SubExpr->getLoc() : SourceLoc(); }
954954

955-
SourceLoc getStartLoc() const;
955+
SourceLoc getStartLoc() const {
956+
return SubExpr ? SubExpr->getStartLoc() : SourceLoc();
957+
}
956958

957959
SourceLoc getEndLoc() const;
958960

lib/AST/Expr.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,23 +2390,13 @@ TapExpr::TapExpr(Expr * SubExpr, BraceStmt *Body)
23902390
assert(!Body->empty() &&
23912391
Body->getFirstElement().isDecl(DeclKind::Var) &&
23922392
"First element of Body should be a variable to init with the subExpr");
2393-
getVar()->setParentExpr(this);
23942393
}
23952394
}
23962395

23972396
VarDecl * TapExpr::getVar() const {
23982397
return dyn_cast<VarDecl>(Body->getFirstElement().dyn_cast<Decl *>());
23992398
}
24002399

2401-
SourceLoc TapExpr::getStartLoc() const {
2402-
// Include the body in the range, assuming the body follows the SubExpr.
2403-
if (auto *const se = getSubExpr())
2404-
return se->getStartLoc();
2405-
if (auto *const b = getBody())
2406-
return b->getStartLoc();
2407-
return SourceLoc();
2408-
}
2409-
24102400
SourceLoc TapExpr::getEndLoc() const {
24112401
// Include the body in the range, assuming the body follows the SubExpr.
24122402
// Also, be (perhaps overly) defensive about null pointers & invalid

lib/Sema/CSApply.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7697,8 +7697,11 @@ namespace {
76977697
return true;
76987698

76997699
case SolutionApplicationToFunctionResult::Delay: {
7700-
auto closure = cast<ClosureExpr>(fn.getAbstractClosureExpr());
7701-
ClosuresToTypeCheck.push_back(closure);
7700+
if (!Rewriter.cs.Options
7701+
.contains(ConstraintSystemFlags::LeaveClosureBodyUnchecked)) {
7702+
auto closure = cast<ClosureExpr>(fn.getAbstractClosureExpr());
7703+
ClosuresToTypeCheck.push_back(closure);
7704+
}
77027705
return false;
77037706
}
77047707
}
@@ -8275,26 +8278,24 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
82758278
if (!resultTarget)
82768279
return None;
82778280

8278-
if (!Options.contains(ConstraintSystemFlags::LeaveClosureBodyUnchecked)) {
8279-
bool hadError = false;
8280-
8281-
// Visit closures that have non-single expression bodies.
8282-
for (auto *closure : walker.getClosuresToTypeCheck())
8283-
hadError |= TypeChecker::typeCheckClosureBody(closure);
8281+
// Visit closures that have non-single expression bodies.
8282+
bool hadError = false;
82848283

8285-
// Tap expressions too; they should or should not be
8286-
// type-checked under the same conditions as closure bodies.
8287-
for (auto tuple : walker.getTapsToTypeCheck()) {
8288-
auto tap = std::get<0>(tuple);
8289-
auto tapDC = std::get<1>(tuple);
8290-
hadError |= TypeChecker::typeCheckTapBody(tap, tapDC);
8291-
}
8284+
for (auto *closure : walker.getClosuresToTypeCheck())
8285+
hadError |= TypeChecker::typeCheckClosureBody(closure);
82928286

8293-
// If any of them failed to type check, bail.
8294-
if (hadError)
8295-
return None;
8287+
// Tap expressions too; they should or should not be
8288+
// type-checked under the same conditions as closure bodies.
8289+
for (auto tuple : walker.getTapsToTypeCheck()) {
8290+
auto tap = std::get<0>(tuple);
8291+
auto tapDC = std::get<1>(tuple);
8292+
hadError |= TypeChecker::typeCheckTapBody(tap, tapDC);
82968293
}
82978294

8295+
// If any of them failed to type check, bail.
8296+
if (hadError)
8297+
return None;
8298+
82988299
rewriter.finalize();
82998300

83008301
return resultTarget;

lib/Sema/TypeCheckDecl.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,20 +2242,12 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const {
22422242

22432243
case DeclKind::Var: {
22442244
auto *VD = cast<VarDecl>(D);
2245-
Type interfaceType;
2246-
if (auto *parentE = VD->getParentExpr()) {
2247-
// Type check the ASTNode that contains the parent 'TapExpr' if it
2248-
// hasn't.
2249-
if (!parentE->getType())
2250-
swift::typeCheckASTNodeAtLoc(VD->getDeclContext(), parentE->getLoc());
2251-
interfaceType = parentE->getType();
2252-
} else if (auto *namingPattern = VD->getNamingPattern()) {
2253-
interfaceType = namingPattern->getType();
2254-
}
2255-
2256-
if (!interfaceType)
2245+
auto *namingPattern = VD->getNamingPattern();
2246+
if (!namingPattern) {
22572247
return ErrorType::get(Context);
2248+
}
22582249

2250+
Type interfaceType = namingPattern->getType();
22592251
if (interfaceType->hasArchetype())
22602252
interfaceType = interfaceType->mapTypeOutOfContext();
22612253

lib/Sema/TypeCheckStmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,11 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(Evaluator &evaluator,
19131913
if (SM.isBeforeInBuffer(endLoc, Loc))
19141914
return {false, E};
19151915

1916+
// Don't walk into 'TapExpr'. They should be type checked with parent
1917+
// 'InterpolatedStringLiteralExpr'.
1918+
if (isa<TapExpr>(E))
1919+
return {false, E};
1920+
19161921
if (auto closure = dyn_cast<ClosureExpr>(E)) {
19171922
// NOTE: When a client wants to type check a closure signature, it
19181923
// requests with closure's 'getLoc()' location.

0 commit comments

Comments
 (0)