Skip to content

Commit eb61ae7

Browse files
committed
[Type checker] Factor out ConstraintSystem::addJoinConstraint().
Use it for ternary expressions; it'll gain other clients soon.
1 parent f692420 commit eb61ae7

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

lib/Sema/CSGen.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2576,28 +2576,24 @@ namespace {
25762576
}
25772577

25782578
Type visitIfExpr(IfExpr *expr) {
2579-
// The conditional expression must conform to LogicValue.
2579+
// Condition must convert to Bool.
25802580
auto boolDecl = CS.getASTContext().getBoolDecl();
25812581
if (!boolDecl)
25822582
return Type();
25832583

2584-
// Condition must convert to Bool.
25852584
CS.addConstraint(ConstraintKind::Conversion,
25862585
CS.getType(expr->getCondExpr()),
25872586
boolDecl->getDeclaredType(),
25882587
CS.getConstraintLocator(expr->getCondExpr()));
25892588

25902589
// The branches must be convertible to a common type.
2591-
auto resultTy = CS.createTypeVariable(CS.getConstraintLocator(expr),
2592-
TVO_PrefersSubtypeBinding |
2593-
TVO_CanBindToNoEscape);
2594-
CS.addConstraint(ConstraintKind::Conversion,
2595-
CS.getType(expr->getThenExpr()), resultTy,
2596-
CS.getConstraintLocator(expr->getThenExpr()));
2597-
CS.addConstraint(ConstraintKind::Conversion,
2598-
CS.getType(expr->getElseExpr()), resultTy,
2599-
CS.getConstraintLocator(expr->getElseExpr()));
2600-
return resultTy;
2590+
return CS.addJoinConstraint(CS.getConstraintLocator(expr),
2591+
{
2592+
{ CS.getType(expr->getThenExpr()),
2593+
CS.getConstraintLocator(expr->getThenExpr()) },
2594+
{ CS.getType(expr->getElseExpr()),
2595+
CS.getConstraintLocator(expr->getElseExpr()) }
2596+
});
26012597
}
26022598

26032599
virtual Type visitImplicitConversionExpr(ImplicitConversionExpr *expr) {

lib/Sema/CSSimplify.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8075,6 +8075,35 @@ void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
80758075
}
80768076
}
80778077

8078+
Type ConstraintSystem::addJoinConstraint(
8079+
ConstraintLocator *locator,
8080+
ArrayRef<std::pair<Type, ConstraintLocator *>> inputs) {
8081+
switch (inputs.size()) {
8082+
case 0:
8083+
return Type();
8084+
8085+
case 1:
8086+
return inputs.front().first;
8087+
8088+
default:
8089+
// Produce the join below.
8090+
break;
8091+
}
8092+
8093+
// Create a type variable to capture the result of the join.
8094+
Type resultTy = createTypeVariable(locator,
8095+
(TVO_PrefersSubtypeBinding |
8096+
TVO_CanBindToNoEscape));
8097+
8098+
// Introduce conversions from each input type to the type variable.
8099+
for (const auto &input : inputs) {
8100+
addConstraint(
8101+
ConstraintKind::Conversion, input.first, resultTy, input.second);
8102+
}
8103+
8104+
return resultTy;
8105+
}
8106+
80788107
void ConstraintSystem::addExplicitConversionConstraint(
80798108
Type fromType, Type toType,
80808109
bool allowFixes,

lib/Sema/ConstraintSystem.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,6 +2130,17 @@ class ConstraintSystem {
21302130
void addConstraint(Requirement req, ConstraintLocatorBuilder locator,
21312131
bool isFavored = false);
21322132

2133+
/// Add a "join" constraint between a set of types, producing the common
2134+
/// supertype.
2135+
///
2136+
/// Currently, a "join" is modeled by a set of conversion constraints to
2137+
/// a new type variable. At some point, we may want a new constraint kind
2138+
/// to cover the join.
2139+
///
2140+
/// \returns the joined type, which is generally a new type variable.
2141+
Type addJoinConstraint(ConstraintLocator *locator,
2142+
ArrayRef<std::pair<Type, ConstraintLocator *>> inputs);
2143+
21332144
/// Add a key path application constraint to the constraint system.
21342145
void addKeyPathApplicationConstraint(Type keypath, Type root, Type value,
21352146
ConstraintLocatorBuilder locator,

0 commit comments

Comments
 (0)