Skip to content

Commit 5c58bb8

Browse files
committed
[CSGen] Bring back performance hack for named patterns with an initializer expression
Unfortunately we still need this performance hack because otherwise e.g. if initializer returns a tuple its type is going to be connected to a type variable representing a pattern type, which means all of the tuple element types are going to form a single constraint system component. Resolves: rdar://problem/60961087
1 parent 80ac793 commit 5c58bb8

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

lib/Sema/CSGen.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,8 +2286,30 @@ namespace {
22862286
case PatternKind::Named: {
22872287
auto var = cast<NamedPattern>(pattern)->getDecl();
22882288

2289-
Type varType = CS.createTypeVariable(
2290-
CS.getConstraintLocator(locator), TVO_CanBindToNoEscape);
2289+
Type varType;
2290+
2291+
// If we have a type from an initializer expression, and that
2292+
// expression does not produce an InOut type, use it. This
2293+
// will avoid exponential typecheck behavior in the case of
2294+
// tuples, nested arrays, and dictionary literals.
2295+
//
2296+
// FIXME: This should be handled in the solver, not here.
2297+
//
2298+
// Otherwise, create a new type variable.
2299+
bool assumedInitializerType = false;
2300+
if (!var->hasNonPatternBindingInit() &&
2301+
!var->hasAttachedPropertyWrapper()) {
2302+
if (auto boundExpr = locator.trySimplifyToExpr()) {
2303+
if (!boundExpr->isSemanticallyInOutExpr()) {
2304+
varType = CS.getType(boundExpr)->getRValueType();
2305+
assumedInitializerType = true;
2306+
}
2307+
}
2308+
}
2309+
2310+
if (!assumedInitializerType)
2311+
varType = CS.createTypeVariable(CS.getConstraintLocator(locator),
2312+
TVO_CanBindToNoEscape);
22912313

22922314
// When we are supposed to bind pattern variables, create a fresh
22932315
// type variable and a one-way constraint to assign it to either the
@@ -2308,7 +2330,19 @@ namespace {
23082330
ROK = OA->get();
23092331
switch (optionalityOf(ROK)) {
23102332
case ReferenceOwnershipOptionality::Required:
2333+
if (assumedInitializerType) {
2334+
// Already Optional<T>
2335+
if (varType->getOptionalObjectType())
2336+
break;
2337+
2338+
// Create a fresh type variable to handle overloaded expressions.
2339+
if (varType->is<TypeVariableType>())
2340+
varType = CS.createTypeVariable(CS.getConstraintLocator(locator),
2341+
TVO_CanBindToNoEscape);
2342+
}
2343+
23112344
varType = TypeChecker::getOptionalType(var->getLoc(), varType);
2345+
23122346
if (oneWayVarType) {
23132347
oneWayVarType =
23142348
TypeChecker::getOptionalType(var->getLoc(), oneWayVarType);

0 commit comments

Comments
 (0)