Skip to content

Commit 5063cb5

Browse files
committed
[Constraint solver] Factor out adding a contextual conversion constraint.
1 parent f7744bd commit 5063cb5

File tree

4 files changed

+65
-22
lines changed

4 files changed

+65
-22
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9064,6 +9064,60 @@ void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
90649064
}
90659065
}
90669066

9067+
void ConstraintSystem::addContextualConversionConstraint(
9068+
Expr *expr, ContextualTypeInfo contextualType) {
9069+
Type convertType = contextualType.getType();
9070+
if (convertType.isNull())
9071+
return;
9072+
9073+
// Determine the type of the constraint.
9074+
auto constraintKind = ConstraintKind::Conversion;
9075+
switch (contextualType.purpose) {
9076+
case CTP_ReturnStmt:
9077+
case CTP_ReturnSingleExpr:
9078+
case CTP_Initialization:
9079+
if (Options.contains(
9080+
ConstraintSystemFlags::UnderlyingTypeForOpaqueReturnType))
9081+
constraintKind = ConstraintKind::OpaqueUnderlyingType;
9082+
break;
9083+
9084+
case CTP_CallArgument:
9085+
constraintKind = ConstraintKind::ArgumentConversion;
9086+
break;
9087+
9088+
case CTP_YieldByReference:
9089+
// In a by-reference yield, we expect the contextual type to be an
9090+
// l-value type, so the result must be bound to that.
9091+
constraintKind = ConstraintKind::Bind;
9092+
break;
9093+
9094+
case CTP_ArrayElement:
9095+
case CTP_AssignSource:
9096+
case CTP_CalleeResult:
9097+
case CTP_CannotFail:
9098+
case CTP_Condition:
9099+
case CTP_Unused:
9100+
case CTP_YieldByValue:
9101+
case CTP_ThrowStmt:
9102+
case CTP_EnumCaseRawValue:
9103+
case CTP_DefaultParameter:
9104+
case CTP_ClosureResult:
9105+
case CTP_DictionaryKey:
9106+
case CTP_DictionaryValue:
9107+
case CTP_CoerceOperand:
9108+
case CTP_SubscriptAssignSource:
9109+
case CTP_ForEachStmt:
9110+
break;
9111+
}
9112+
9113+
// Add the constraint.
9114+
bool isForSingleExprFunction = (contextualType.purpose == CTP_ReturnSingleExpr);
9115+
auto *convertTypeLocator = getConstraintLocator(
9116+
expr, LocatorPathElt::ContextualType(isForSingleExprFunction));
9117+
addConstraint(constraintKind, getType(expr), convertType,
9118+
convertTypeLocator, /*isFavored*/ true);
9119+
}
9120+
90679121
Type ConstraintSystem::addJoinConstraint(
90689122
ConstraintLocator *locator,
90699123
ArrayRef<std::pair<Type, ConstraintLocator *>> inputs) {

lib/Sema/CSSolver.cpp

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,37 +1226,23 @@ ConstraintSystem::solveImpl(Expr *&expr,
12261226
// If there is a type that we're expected to convert to, add the conversion
12271227
// constraint.
12281228
if (convertType) {
1229-
auto constraintKind = ConstraintKind::Conversion;
1230-
12311229
auto ctp = getContextualTypePurpose(origExpr);
1232-
if ((ctp == CTP_ReturnStmt ||
1233-
ctp == CTP_ReturnSingleExpr ||
1234-
ctp == CTP_Initialization)
1235-
&& Options.contains(ConstraintSystemFlags::UnderlyingTypeForOpaqueReturnType))
1236-
constraintKind = ConstraintKind::OpaqueUnderlyingType;
1237-
1238-
if (ctp == CTP_CallArgument)
1239-
constraintKind = ConstraintKind::ArgumentConversion;
1240-
1241-
// In a by-reference yield, we expect the contextual type to be an
1242-
// l-value type, so the result must be bound to that.
1243-
if (ctp == CTP_YieldByReference)
1244-
constraintKind = ConstraintKind::Bind;
1245-
1246-
bool isForSingleExprFunction = ctp == CTP_ReturnSingleExpr;
1247-
auto *convertTypeLocator = getConstraintLocator(
1248-
expr, LocatorPathElt::ContextualType(isForSingleExprFunction));
12491230

1231+
// Substitute type variables in for unresolved types.
12501232
if (allowFreeTypeVariables == FreeTypeVariableBinding::UnresolvedType) {
1233+
bool isForSingleExprFunction = (ctp == CTP_ReturnSingleExpr);
1234+
auto *convertTypeLocator = getConstraintLocator(
1235+
expr, LocatorPathElt::ContextualType(isForSingleExprFunction));
1236+
12511237
convertType = convertType.transform([&](Type type) -> Type {
12521238
if (type->is<UnresolvedType>())
12531239
return createTypeVariable(convertTypeLocator, TVO_CanBindToNoEscape);
12541240
return type;
12551241
});
12561242
}
12571243

1258-
addConstraint(constraintKind, getType(expr), convertType,
1259-
convertTypeLocator, /*isFavored*/ true);
1244+
ContextualTypeInfo info{TypeLoc::withoutLoc(convertType), ctp};
1245+
addContextualConversionConstraint(expr, info);
12601246
}
12611247

12621248
// Notify the listener that we've built the constraint system.

lib/Sema/ConstraintSystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,10 @@ class ConstraintSystem {
24132413
void addConstraint(Requirement req, ConstraintLocatorBuilder locator,
24142414
bool isFavored = false);
24152415

2416+
/// Add the appropriate constraint for a contextual conversion.
2417+
void addContextualConversionConstraint(
2418+
Expr *expr, ContextualTypeInfo contextualType);
2419+
24162420
/// Add a "join" constraint between a set of types, producing the common
24172421
/// supertype.
24182422
///

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ enum class TypeResolutionStage : uint8_t;
4747

4848
namespace constraints {
4949
enum class ConstraintKind : char;
50-
enum class SolutionKind : char;
5150
class ConstraintSystem;
5251
class Solution;
5352
class SolutionResult;

0 commit comments

Comments
 (0)