Skip to content

Commit 301e042

Browse files
committed
Add PreCheckFunctionBuilderRequest
Drop a cache out of the type checker.
1 parent 535150c commit 301e042

File tree

9 files changed

+81
-40
lines changed

9 files changed

+81
-40
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: 8 additions & 14 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 (getTypeChecker().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;
@@ -670,21 +673,12 @@ class PreCheckFunctionBuilderClosure : public ASTWalker {
670673

671674
}
672675

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

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

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -530,17 +530,6 @@ enum class CheckedCastContextKind {
530530
EnumElementPattern,
531531
};
532532

533-
enum class FunctionBuilderClosurePreCheck : uint8_t {
534-
/// There were no problems pre-checking the closure.
535-
Okay,
536-
537-
/// There was an error pre-checking the closure.
538-
Error,
539-
540-
/// The closure has a return statement.
541-
HasReturnStmt,
542-
};
543-
544533
/// The Swift type checker, which takes a parsed AST and performs name binding,
545534
/// type checking, and semantic analysis to produce a type-annotated AST.
546535
class TypeChecker final {
@@ -600,11 +589,6 @@ class TypeChecker final {
600589
/// function bodies.
601590
bool SkipNonInlinableFunctionBodies = false;
602591

603-
/// Closure expressions whose bodies have already been prechecked as
604-
/// part of trying to apply a function builder.
605-
llvm::DenseMap<ClosureExpr *, FunctionBuilderClosurePreCheck>
606-
precheckedFunctionBuilderClosures;
607-
608592
TypeChecker(ASTContext &Ctx);
609593
friend class ASTContext;
610594
friend class constraints::ConstraintSystem;
@@ -1075,16 +1059,6 @@ class TypeChecker final {
10751059
/// struct or class.
10761060
static void addImplicitConstructors(NominalTypeDecl *typeDecl);
10771061

1078-
/// Pre-check the body of the given closure, which we are about to
1079-
/// generate constraints for.
1080-
///
1081-
/// This mutates the body of the closure, but only in ways that should be
1082-
/// valid even if we end up not actually applying the function-builder
1083-
/// transform: it just does a normal pre-check of all the expressions in
1084-
/// the closure.
1085-
FunctionBuilderClosurePreCheck
1086-
preCheckFunctionBuilderClosureBody(ClosureExpr *closure);
1087-
10881062
/// \name Name lookup
10891063
///
10901064
/// Routines that perform name lookup.

0 commit comments

Comments
 (0)