Skip to content

Commit 364770e

Browse files
committed
[Constraint system] Remove typeCheckBinding’s ExprTypeCheckListener.
Sink the solution-application code from typeCheckBinding’s ExprTypeCheckListener subclass into normal solution application, allowing us to eliminate this subclass entirely. Down to one…
1 parent c1c7112 commit 364770e

File tree

2 files changed

+52
-66
lines changed

2 files changed

+52
-66
lines changed

lib/Sema/CSApply.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7227,6 +7227,49 @@ bool ConstraintSystem::applySolutionFixes(const Solution &solution) {
72277227
return diagnosedAnyErrors;
72287228
}
72297229

7230+
/// Apply the given solution to the initialization target.
7231+
///
7232+
/// \returns the resulting initialiation expression.
7233+
static Expr *applySolutionToInitialization(
7234+
Solution &solution, SolutionApplicationTarget target, Expr *expr) {
7235+
auto wrappedVar = target.getInitializationWrappedVar();
7236+
Type initType;
7237+
if (wrappedVar) {
7238+
initType = solution.getType(expr);
7239+
} else {
7240+
initType = solution.getType(target.getInitializationPattern());
7241+
}
7242+
7243+
{
7244+
// Figure out what type the constraints decided on.
7245+
auto ty = solution.simplifyType(initType);
7246+
initType = ty->getRValueType()->reconstituteSugar(/*recursive =*/false);
7247+
}
7248+
7249+
// Convert the initializer to the type of the pattern.
7250+
auto &cs = solution.getConstraintSystem();
7251+
auto locator =
7252+
cs.getConstraintLocator(expr, LocatorPathElt::ContextualType());
7253+
expr = solution.coerceToType(expr, initType, locator);
7254+
if (!expr)
7255+
return nullptr;
7256+
7257+
// Record the property wrapper type and note that the initializer has
7258+
// been subsumed by the backing property.
7259+
if (wrappedVar) {
7260+
ASTContext &ctx = cs.getASTContext();
7261+
wrappedVar->getParentPatternBinding()->setInitializerSubsumed(0);
7262+
ctx.setSideCachedPropertyWrapperBackingPropertyType(
7263+
wrappedVar, initType->mapTypeOutOfContext());
7264+
7265+
// Record the semantic initializer on the outermost property wrapper.
7266+
wrappedVar->getAttachedPropertyWrappers().front()
7267+
->setSemanticInit(expr);
7268+
}
7269+
7270+
return expr;
7271+
}
7272+
72307273
/// Apply a given solution to the expression, producing a fully
72317274
/// type-checked expression.
72327275
Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
@@ -7265,6 +7308,14 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
72657308
if (!rewrittenExpr)
72667309
return None;
72677310

7311+
/// Handle application for initializations.
7312+
if (target.getExprContextualTypePurpose() == CTP_Initialization) {
7313+
rewrittenExpr = applySolutionToInitialization(
7314+
solution, target, rewrittenExpr);
7315+
if (!rewrittenExpr)
7316+
return None;
7317+
}
7318+
72687319
result.setExpr(rewrittenExpr);
72697320
} else {
72707321
auto fn = *target.getAsFunction();

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,79 +2413,14 @@ TypeChecker::getTypeOfCompletionOperator(DeclContext *DC, Expr *LHS,
24132413
bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
24142414
DeclContext *DC,
24152415
Type patternType) {
2416-
2417-
/// Type checking listener for pattern binding initializers.
2418-
class BindingListener : public ExprTypeCheckListener {
2419-
ASTContext &context;
2420-
2421-
SolutionApplicationTarget target;
2422-
2423-
/// The locator we're using.
2424-
ConstraintLocator *Locator;
2425-
2426-
/// The variable to that has property wrappers that have been applied to the initializer expression.
2427-
VarDecl *wrappedVar = nullptr;
2428-
2429-
public:
2430-
explicit BindingListener(ASTContext &ctx, SolutionApplicationTarget target)
2431-
: context(ctx), target(target), Locator(nullptr) {
2432-
wrappedVar = target.getInitializationWrappedVar();
2433-
}
2434-
2435-
bool builtConstraints(ConstraintSystem &cs, Expr *expr) override {
2436-
// The expression has been pre-checked; save it in case we fail later.
2437-
Locator = cs.getConstraintLocator(expr, LocatorPathElt::ContextualType());
2438-
return false;
2439-
}
2440-
2441-
Expr *appliedSolution(Solution &solution, Expr *expr) override {
2442-
Type initType;
2443-
if (wrappedVar) {
2444-
initType = solution.getType(expr);
2445-
} else {
2446-
initType = solution.getType(target.getInitializationPattern());
2447-
}
2448-
2449-
{
2450-
// Figure out what type the constraints decided on.
2451-
auto ty = solution.simplifyType(initType);
2452-
initType = ty->getRValueType()->reconstituteSugar(/*recursive =*/false);
2453-
}
2454-
2455-
// Convert the initializer to the type of the pattern.
2456-
expr = solution.coerceToType(expr, initType, Locator);
2457-
if (!expr)
2458-
return nullptr;
2459-
2460-
// Record the property wrapper type and note that the initializer has
2461-
// been subsumed by the backing property.
2462-
if (wrappedVar) {
2463-
wrappedVar->getParentPatternBinding()->setInitializerSubsumed(0);
2464-
context.setSideCachedPropertyWrapperBackingPropertyType(
2465-
wrappedVar, initType->mapTypeOutOfContext());
2466-
2467-
// Record the semantic initializer on the outermost property wrapper.
2468-
wrappedVar->getAttachedPropertyWrappers().front()
2469-
->setSemanticInit(expr);
2470-
}
2471-
2472-
return expr;
2473-
}
2474-
};
2475-
24762416
auto &Context = DC->getASTContext();
24772417
auto target = SolutionApplicationTarget::forInitialization(
24782418
initializer, DC, patternType, pattern);
24792419
initializer = target.getAsExpr();
24802420

2481-
BindingListener listener(Context, target);
2482-
if (!initializer)
2483-
return true;
2484-
24852421
// Type-check the initializer.
24862422
bool unresolvedTypeExprs = false;
2487-
auto resultTarget = typeCheckExpression(target, unresolvedTypeExprs,
2488-
None, &listener);
2423+
auto resultTarget = typeCheckExpression(target, unresolvedTypeExprs);
24892424

24902425
if (resultTarget) {
24912426
initializer = resultTarget->getAsExpr();

0 commit comments

Comments
 (0)