Skip to content

Commit 852585e

Browse files
authored
Merge pull request #28179 from CodaFi/destroyer-of-hearts
[NFC] Drop More Type Checkers
2 parents f5f214d + 1b75dbd commit 852585e

36 files changed

+427
-444
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
SWIFT_TYPEID(AncestryFlags)
1919
SWIFT_TYPEID(CtorInitializerKind)
20+
SWIFT_TYPEID(FunctionBuilderClosurePreCheck)
2021
SWIFT_TYPEID(GenericSignature)
2122
SWIFT_TYPEID(ImplicitMemberAction)
2223
SWIFT_TYPEID(ParamSpecifier)
@@ -28,6 +29,7 @@ SWIFT_TYPEID(Type)
2829
SWIFT_TYPEID(TypePair)
2930
SWIFT_TYPEID(TypeWitnessAndDecl)
3031
SWIFT_TYPEID(Witness)
32+
SWIFT_TYPEID_NAMED(ClosureExpr *, ClosureExpr)
3133
SWIFT_TYPEID_NAMED(ConstructorDecl *, ConstructorDecl)
3234
SWIFT_TYPEID_NAMED(CustomAttr *, CustomAttr)
3335
SWIFT_TYPEID_NAMED(Decl *, Decl)

include/swift/AST/ASTTypeIDs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ namespace swift {
2323

2424
class AbstractFunctionDecl;
2525
class BraceStmt;
26+
class ClosureExpr;
2627
class ConstructorDecl;
2728
class CustomAttr;
2829
class Decl;
2930
class EnumDecl;
31+
enum class FunctionBuilderClosurePreCheck : uint8_t;
3032
class GenericParamList;
3133
class GenericSignature;
3234
class GenericTypeParamType;

include/swift/AST/Expr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5407,6 +5407,9 @@ Expr *packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc,
54075407
[](const Expr *E) -> Type {
54085408
return E->getType();
54095409
});
5410+
5411+
void simple_display(llvm::raw_ostream &out, const ClosureExpr *CE);
5412+
54105413
} // end namespace swift
54115414

54125415
#endif

include/swift/AST/TypeCheckRequests.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,36 @@ class ValueWitnessRequest
17451745
void cacheResult(Witness value) const;
17461746
};
17471747

1748+
enum class FunctionBuilderClosurePreCheck : uint8_t {
1749+
/// There were no problems pre-checking the closure.
1750+
Okay,
1751+
1752+
/// There was an error pre-checking the closure.
1753+
Error,
1754+
1755+
/// The closure has a return statement.
1756+
HasReturnStmt,
1757+
};
1758+
1759+
class PreCheckFunctionBuilderRequest
1760+
: public SimpleRequest<PreCheckFunctionBuilderRequest,
1761+
FunctionBuilderClosurePreCheck(ClosureExpr *),
1762+
CacheKind::Cached> {
1763+
public:
1764+
using SimpleRequest::SimpleRequest;
1765+
1766+
private:
1767+
friend SimpleRequest;
1768+
1769+
// Evaluation.
1770+
llvm::Expected<FunctionBuilderClosurePreCheck>
1771+
evaluate(Evaluator &evaluator, ClosureExpr *closure) const;
1772+
1773+
public:
1774+
// Separate caching.
1775+
bool isCached() const { return true; }
1776+
};
1777+
17481778
// Allow AnyValue to compare two Type values, even though Type doesn't
17491779
// support ==.
17501780
template<>
@@ -1767,6 +1797,7 @@ AnyValue::Holder<GenericSignature>::equals(const HolderBase &other) const {
17671797
void simple_display(llvm::raw_ostream &out, Type value);
17681798
void simple_display(llvm::raw_ostream &out, const TypeRepr *TyR);
17691799
void simple_display(llvm::raw_ostream &out, ImplicitMemberAction action);
1800+
void simple_display(llvm::raw_ostream &out, FunctionBuilderClosurePreCheck pck);
17701801

17711802
#define SWIFT_TYPEID_ZONE TypeChecker
17721803
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ SWIFT_REQUEST(TypeChecker, HasUserDefinedDesignatedInitRequest,
176176
bool(NominalTypeDecl *), Cached, NoLocationInfo)
177177
SWIFT_REQUEST(TypeChecker, HasMemberwiseInitRequest,
178178
bool(StructDecl *), Cached, NoLocationInfo)
179+
SWIFT_REQUEST(TypeChecker, PreCheckFunctionBuilderRequest,
180+
FunctionBuilderClosurePreCheck(ClosureExpr *),
181+
Cached, NoLocationInfo)
179182
SWIFT_REQUEST(TypeChecker, ResolveImplicitMemberRequest,
180183
bool(NominalTypeDecl *, ImplicitMemberAction), Uncached,
181184
NoLocationInfo)

lib/AST/Expr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,6 +2246,19 @@ SourceLoc TapExpr::getEndLoc() const {
22462246
return SourceLoc();
22472247
}
22482248

2249+
void swift::simple_display(llvm::raw_ostream &out, const ClosureExpr *CE) {
2250+
if (!CE) {
2251+
out << "(null)";
2252+
return;
2253+
}
2254+
2255+
if (CE->hasSingleExpressionBody()) {
2256+
out << "single expression closure";
2257+
} else {
2258+
out << "closure";
2259+
}
2260+
}
2261+
22492262
// See swift/Basic/Statistic.h for declaration: this enables tracing Exprs, is
22502263
// defined here to avoid too much layering violation / circular linkage
22512264
// dependency.

lib/AST/TypeCheckRequests.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,3 +1113,22 @@ Optional<Witness> ValueWitnessRequest::getCachedResult() const {
11131113
void ValueWitnessRequest::cacheResult(Witness type) const {
11141114
// FIXME: Refactor this to be the thing that warms the cache.
11151115
}
1116+
1117+
//----------------------------------------------------------------------------//
1118+
// PreCheckFunctionBuilderRequest computation.
1119+
//----------------------------------------------------------------------------//
1120+
1121+
void swift::simple_display(llvm::raw_ostream &out,
1122+
FunctionBuilderClosurePreCheck value) {
1123+
switch (value) {
1124+
case FunctionBuilderClosurePreCheck::Okay:
1125+
out << "okay";
1126+
break;
1127+
case FunctionBuilderClosurePreCheck::HasReturnStmt:
1128+
out << "has return statement";
1129+
break;
1130+
case FunctionBuilderClosurePreCheck::Error:
1131+
out << "error";
1132+
break;
1133+
}
1134+
}

lib/Sema/BuilderTransform.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/NameLookup.h"
2323
#include "swift/AST/NameLookupRequests.h"
2424
#include "swift/AST/ParameterList.h"
25+
#include "swift/AST/TypeCheckRequests.h"
2526
#include "llvm/ADT/DenseMap.h"
2627
#include "llvm/ADT/SmallVector.h"
2728
#include <iterator>
@@ -516,7 +517,9 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder(
516517

517518
// Pre-check the closure body: pre-check any expressions in it and look
518519
// for return statements.
519-
switch (TC.preCheckFunctionBuilderClosureBody(closure)) {
520+
auto request = PreCheckFunctionBuilderRequest{closure};
521+
switch (evaluateOrDefault(getASTContext().evaluator, request,
522+
FunctionBuilderClosurePreCheck::Error)) {
520523
case FunctionBuilderClosurePreCheck::Okay:
521524
// If the pre-check was okay, apply the function-builder transform.
522525
break;
@@ -582,7 +585,7 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder(
582585
// that CSGen might have.
583586
//
584587
// TODO: just build the AST the way we want it in the first place.
585-
if (TC.preCheckExpression(singleExpr, closure))
588+
if (ConstraintSystem::preCheckExpression(singleExpr, closure))
586589
return getTypeMatchFailure(locator);
587590

588591
singleExpr = generateConstraints(singleExpr, closure);
@@ -617,13 +620,12 @@ namespace {
617620

618621
/// Pre-check all the expressions in the closure body.
619622
class PreCheckFunctionBuilderClosure : public ASTWalker {
620-
TypeChecker &TC;
621623
ClosureExpr *Closure;
622624
bool HasReturnStmt = false;
623625
bool HasError = false;
624626
public:
625-
PreCheckFunctionBuilderClosure(TypeChecker &tc, ClosureExpr *closure)
626-
: TC(tc), Closure(closure) {}
627+
PreCheckFunctionBuilderClosure(ClosureExpr *closure)
628+
: Closure(closure) {}
627629

628630
FunctionBuilderClosurePreCheck run() {
629631
Stmt *oldBody = Closure->getBody();
@@ -649,7 +651,7 @@ class PreCheckFunctionBuilderClosure : public ASTWalker {
649651
// Pre-check the expression. If this fails, abort the walk immediately.
650652
// Otherwise, replace the expression with the result of pre-checking.
651653
// In either case, don't recurse into the expression.
652-
if (TC.preCheckExpression(E, /*DC*/ Closure)) {
654+
if (ConstraintSystem::preCheckExpression(E, /*DC*/ Closure)) {
653655
HasError = true;
654656
return std::make_pair(false, nullptr);
655657
}
@@ -671,21 +673,12 @@ class PreCheckFunctionBuilderClosure : public ASTWalker {
671673

672674
}
673675

674-
FunctionBuilderClosurePreCheck
675-
TypeChecker::preCheckFunctionBuilderClosureBody(ClosureExpr *closure) {
676+
llvm::Expected<FunctionBuilderClosurePreCheck>
677+
PreCheckFunctionBuilderRequest::evaluate(Evaluator &eval,
678+
ClosureExpr *closure) const {
676679
// Single-expression closures should already have been pre-checked.
677680
if (closure->hasSingleExpressionBody())
678681
return FunctionBuilderClosurePreCheck::Okay;
679682

680-
// Check whether we've already done this analysis.
681-
auto it = precheckedFunctionBuilderClosures.find(closure);
682-
if (it != precheckedFunctionBuilderClosures.end())
683-
return it->second;
684-
685-
auto result = PreCheckFunctionBuilderClosure(*this, closure).run();
686-
687-
// Cache the result.
688-
precheckedFunctionBuilderClosures.insert(std::make_pair(closure, result));
689-
690-
return result;
683+
return PreCheckFunctionBuilderClosure(closure).run();
691684
}

lib/Sema/CSApply.cpp

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ namespace {
458458
refExpr = declRefExpr;
459459
}
460460

461-
auto resultTy = cs.getTypeChecker().typeCheckExpression(
461+
auto resultTy = TypeChecker::typeCheckExpression(
462462
refExpr, cs.DC, TypeLoc::withoutLoc(expectedFnType),
463463
CTP_CannotFail);
464464
if (!resultTy)
@@ -2818,7 +2818,7 @@ namespace {
28182818
//
28192819
// The result is that in Swift 5, 'try?' avoids producing nested optionals.
28202820

2821-
if (!cs.getTypeChecker().getLangOpts().isSwiftVersionAtLeast(5)) {
2821+
if (!cs.getASTContext().LangOpts.isSwiftVersionAtLeast(5)) {
28222822
// Nothing to do for Swift 4 and earlier!
28232823
return simplifyExprType(expr);
28242824
}
@@ -3124,7 +3124,7 @@ namespace {
31243124
auto castContextKind =
31253125
SuppressDiagnostics ? CheckedCastContextKind::None
31263126
: CheckedCastContextKind::IsExpr;
3127-
auto castKind = cs.getTypeChecker().typeCheckCheckedCast(
3127+
auto castKind = TypeChecker::typeCheckCheckedCast(
31283128
fromType, toType, castContextKind, cs.DC, expr->getLoc(), sub,
31293129
expr->getCastTypeLoc().getSourceRange());
31303130

@@ -3531,7 +3531,7 @@ namespace {
35313531

35323532
solution.setExprTypes(sub);
35333533

3534-
if (cs.getTypeChecker().convertToType(sub, toType, cs.DC))
3534+
if (TypeChecker::convertToType(sub, toType, cs.DC))
35353535
return nullptr;
35363536

35373537
cs.cacheExprTypes(sub);
@@ -3576,7 +3576,7 @@ namespace {
35763576
: CheckedCastContextKind::ForcedCast;
35773577

35783578
auto fromType = cs.getType(sub);
3579-
auto castKind = cs.getTypeChecker().typeCheckCheckedCast(
3579+
auto castKind = TypeChecker::typeCheckCheckedCast(
35803580
fromType, toType, castContextKind, cs.DC, expr->getLoc(), sub,
35813581
expr->getCastTypeLoc().getSourceRange());
35823582
switch (castKind) {
@@ -3657,7 +3657,7 @@ namespace {
36573657
: CheckedCastContextKind::ConditionalCast;
36583658

36593659
auto fromType = cs.getType(sub);
3660-
auto castKind = cs.getTypeChecker().typeCheckCheckedCast(
3660+
auto castKind = TypeChecker::typeCheckCheckedCast(
36613661
fromType, toType, castContextKind, cs.DC, expr->getLoc(), sub,
36623662
expr->getCastTypeLoc().getSourceRange());
36633663
switch (castKind) {
@@ -3875,7 +3875,7 @@ namespace {
38753875
Expr *callExpr = CallExpr::createImplicit(ctx, fnRef, { argExpr },
38763876
{ Identifier() });
38773877

3878-
auto resultTy = cs.getTypeChecker().typeCheckExpression(
3878+
auto resultTy = TypeChecker::typeCheckExpression(
38793879
callExpr, cs.DC, TypeLoc::withoutLoc(valueType), CTP_CannotFail);
38803880
assert(resultTy && "Conversion cannot fail!");
38813881
(void)resultTy;
@@ -4494,8 +4494,8 @@ namespace {
44944494
cs.cacheType(outerClosure);
44954495

44964496
// The inner closure at least will definitely have a capture.
4497-
cs.TC.ClosuresWithUncomputedCaptures.push_back(outerClosure);
4498-
cs.TC.ClosuresWithUncomputedCaptures.push_back(closure);
4497+
cs.getTypeChecker().ClosuresWithUncomputedCaptures.push_back(outerClosure);
4498+
cs.getTypeChecker().ClosuresWithUncomputedCaptures.push_back(closure);
44994499

45004500
// let outerApply = "\( outerClosure )( \(E) )"
45014501
auto outerApply = CallExpr::createImplicit(ctx, outerClosure, {E}, {});
@@ -4787,7 +4787,7 @@ getCallerDefaultArg(ConstraintSystem &cs, DeclContext *dc,
47874787
// Convert the literal to the appropriate type.
47884788
auto defArgType =
47894789
param->getInterfaceType().subst(owner.getSubstitutions());
4790-
auto resultTy = cs.getTypeChecker().typeCheckParameterDefault(
4790+
auto resultTy = TypeChecker::typeCheckParameterDefault(
47914791
init, dc, defArgType,
47924792
/*isAutoClosure=*/param->isAutoClosure(),
47934793
/*canFail=*/false);
@@ -5408,7 +5408,7 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, AnyFunctionType *funcType,
54085408
arg, closureType->getResult(),
54095409
locator.withPathElement(ConstraintLocator::AutoclosureResult));
54105410

5411-
convertedArg = cs.TC.buildAutoClosureExpr(dc, arg, closureType);
5411+
convertedArg = TypeChecker::buildAutoClosureExpr(dc, arg, closureType);
54125412
cs.cacheExprTypes(convertedArg);
54135413
} else {
54145414
convertedArg = coerceToType(
@@ -5676,12 +5676,10 @@ static Expr *buildElementConversion(ExprRewriter &rewriter,
56765676
ConstraintLocatorBuilder locator,
56775677
Expr *element) {
56785678
auto &cs = rewriter.getConstraintSystem();
5679-
5680-
auto &tc = rewriter.getConstraintSystem().getTypeChecker();
56815679
if (bridged &&
5682-
tc.typeCheckCheckedCast(srcType, destType,
5683-
CheckedCastContextKind::None, cs.DC,
5684-
SourceLoc(), nullptr, SourceRange())
5680+
TypeChecker::typeCheckCheckedCast(srcType, destType,
5681+
CheckedCastContextKind::None, cs.DC,
5682+
SourceLoc(), nullptr, SourceRange())
56855683
!= CheckedCastKind::Coercion) {
56865684
if (auto conversion =
56875685
rewriter.buildObjCBridgeExpr(element, destType, locator))
@@ -7443,14 +7441,14 @@ Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr,
74437441
if (!skipClosures) {
74447442
bool hadError = false;
74457443
for (auto *closure : walker.getClosuresToTypeCheck())
7446-
hadError |= getTypeChecker().typeCheckClosureBody(closure);
7444+
hadError |= TypeChecker::typeCheckClosureBody(closure);
74477445

74487446
// Tap expressions too; they should or should not be
74497447
// type-checked under the same conditions as closure bodies.
74507448
for (auto tuple : walker.getTapsToTypeCheck()) {
74517449
auto tap = std::get<0>(tuple);
74527450
auto tapDC = std::get<1>(tuple);
7453-
hadError |= getTypeChecker().typeCheckTapBody(tap, tapDC);
7451+
hadError |= TypeChecker::typeCheckTapBody(tap, tapDC);
74547452
}
74557453

74567454
// If any of them failed to type check, bail.

0 commit comments

Comments
 (0)