Skip to content

Commit 7fabab8

Browse files
author
Benjamin Driscoll
committed
[TypeChecker] handle UnresolvedTypes in setContextualType
We used to handle these in an equivalent way in `generateConstraints`, but, when most of the `generateConstraints` logic got moved to `setContextualType`, the `UnresolvedType` logic was simply removed.
1 parent 2c7f5e4 commit 7fabab8

File tree

5 files changed

+33
-60
lines changed

5 files changed

+33
-60
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,8 +3017,9 @@ class ConstraintSystem {
30173017
/// and creating type variables for placeholders).
30183018
///
30193019
/// May only be called once per AST node.
3020-
void setContextualType(ASTNode node, TypeLoc T,
3021-
ContextualTypePurpose purpose);
3020+
void setContextualType(ASTNode node, TypeLoc T, ContextualTypePurpose purpose,
3021+
FreeTypeVariableBinding allowFreeTypeVariables =
3022+
FreeTypeVariableBinding::Disallow);
30223023

30233024
Optional<ContextualTypeInfo> getContextualTypeInfo(ASTNode node) const {
30243025
auto known = contextualTypes.find(node);

lib/Sema/CSGen.cpp

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3810,51 +3810,8 @@ bool ConstraintSystem::generateConstraints(
38103810
convertType = contextType;
38113811

38123812
// Determine whether we know more about the contextual type.
3813-
ContextualTypePurpose ctp = target.getExprContextualTypePurpose();
3814-
// auto *convertTypeLocator =
3815-
// getConstraintLocator(expr, LocatorPathElt::ContextualType(ctp));
3816-
3817-
// FIXME [OPAQUE SUPPORT]: most of this got moved to `setContextualType`,
3818-
// but `UnresolvedTypes` aren't handled there, so they are broken now!!!
3819-
3820-
// auto getLocator = [&](Type ty) -> ConstraintLocator * {
3821-
// // If we have a placeholder originating from a PlaceholderTypeRepr,
3822-
// // tack that on to the locator.
3823-
// if (auto *placeholderTy = ty->getAs<PlaceholderType>())
3824-
// if (auto *placeholderRepr = placeholderTy->getOriginator()
3825-
// .dyn_cast<PlaceholderTypeRepr *>())
3826-
// return getConstraintLocator(
3827-
// convertTypeLocator,
3828-
// LocatorPathElt::PlaceholderType(placeholderRepr));
3829-
// return convertTypeLocator;
3830-
//};
3831-
3832-
// Substitute type variables in for placeholder types (and unresolved
3833-
// types, if allowed).
3834-
// if (allowFreeTypeVariables == FreeTypeVariableBinding::UnresolvedType)
3835-
// {
3836-
// convertType = convertType.transform([&](Type type) -> Type {
3837-
// if (type->is<UnresolvedType>() || type->is<PlaceholderType>()) {
3838-
// return createTypeVariable(getLocator(type),
3839-
// TVO_CanBindToNoEscape |
3840-
// TVO_PrefersSubtypeBinding |
3841-
// TVO_CanBindToHole);
3842-
// }
3843-
// return type;
3844-
// });
3845-
//} else {
3846-
// convertType = convertType.transform([&](Type type) -> Type {
3847-
// if (type->is<PlaceholderType>()) {
3848-
// return createTypeVariable(getLocator(type),
3849-
// TVO_CanBindToNoEscape |
3850-
// TVO_PrefersSubtypeBinding |
3851-
// TVO_CanBindToHole);
3852-
// }
3853-
// return type;
3854-
// });
3855-
//}
3856-
3857-
addContextualConversionConstraint(expr, convertType, ctp);
3813+
addContextualConversionConstraint(expr, convertType,
3814+
target.getExprContextualTypePurpose());
38583815
}
38593816

38603817
// For an initialization target, generate constraints for the pattern.

lib/Sema/ConstraintSystem.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5699,29 +5699,42 @@ Type ConstraintSystem::getVarType(const VarDecl *var) {
56995699
});
57005700
}
57015701

5702-
void ConstraintSystem::setContextualType(ASTNode node, TypeLoc T,
5703-
ContextualTypePurpose purpose) {
5702+
void ConstraintSystem::setContextualType(
5703+
ASTNode node, TypeLoc T, ContextualTypePurpose purpose,
5704+
FreeTypeVariableBinding allowFreeTypeVariables) {
57045705
assert(bool(node) && "Expected non-null expression!");
57055706
assert(contextualTypes.count(node) == 0 &&
57065707
"Already set this contextual type");
57075708

57085709
auto contextualType = T.getType();
5710+
bool transformUnresolved =
5711+
allowFreeTypeVariables == FreeTypeVariableBinding::UnresolvedType;
5712+
57095713
if (contextualType) {
57105714
contextualType = contextualType.transform([&](Type type) -> Type {
57115715
// TODO [OPAQUE SUPPORT]: perhaps we could provide better locators here?
57125716
auto *locator =
57135717
getConstraintLocator(node, LocatorPathElt::ContextualType(purpose));
57145718

5715-
if (type->is<OpaqueTypeArchetypeType>()) {
5719+
if (type->is<OpaqueTypeArchetypeType>())
57165720
return openOpaqueType(type, locator);
5717-
}
57185721

5719-
if (type->is<PlaceholderType>()) {
5722+
if (auto *placeholderType = type->getAs<PlaceholderType>()) {
5723+
if (auto *placeholderRepr = placeholderType->getOriginator()
5724+
.dyn_cast<PlaceholderTypeRepr *>())
5725+
locator = getConstraintLocator(
5726+
locator, LocatorPathElt::PlaceholderType(placeholderRepr));
5727+
57205728
return createTypeVariable(locator, TVO_CanBindToNoEscape |
57215729
TVO_PrefersSubtypeBinding |
57225730
TVO_CanBindToHole);
57235731
}
57245732

5733+
if (transformUnresolved && type->is<UnresolvedType>())
5734+
return createTypeVariable(locator, TVO_CanBindToNoEscape |
5735+
TVO_PrefersSubtypeBinding |
5736+
TVO_CanBindToHole);
5737+
57255738
return type;
57265739
});
57275740
}

lib/Sema/TypeCheckCodeCompletion.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
407407
expr->setType(Type());
408408
SolutionApplicationTarget target(
409409
expr, dc, CTP_Unused, Type(), /*isDiscarded=*/false);
410+
cs.setContextualType(expr, target.getExprContextualTypeLoc(),
411+
target.getExprContextualTypePurpose(),
412+
allowFreeTypeVariables);
410413
auto viable = cs.solve(target, allowFreeTypeVariables);
411414
if (!viable) {
412415
recoverOriginalType();

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -382,24 +382,23 @@ TypeChecker::typeCheckExpression(
382382
target.getExprContextualType(),
383383
target.getExprContextualTypePurpose());
384384

385+
// If the client can handle unresolved type variables, leave them in the
386+
// system.
387+
auto allowFreeTypeVariables = FreeTypeVariableBinding::Disallow;
388+
385389
// Tell the constraint system what the contextual type is. This is used in
386390
// constraint generation, informs diagnostics, and is a hint for various
387391
// performance optimizations.
388-
cs.setContextualType(
389-
expr,
390-
target.getExprContextualTypeLoc(),
391-
target.getExprContextualTypePurpose());
392+
cs.setContextualType(expr, target.getExprContextualTypeLoc(),
393+
target.getExprContextualTypePurpose(),
394+
allowFreeTypeVariables);
392395

393396
// Try to shrink the system by reducing disjunction domains. This
394397
// goes through every sub-expression and generate its own sub-system, to
395398
// try to reduce the domains of those subexpressions.
396399
cs.shrink(expr);
397400
target.setExpr(expr);
398401

399-
// If the client can handle unresolved type variables, leave them in the
400-
// system.
401-
auto allowFreeTypeVariables = FreeTypeVariableBinding::Disallow;
402-
403402
// Attempt to solve the constraint system.
404403
auto viable = cs.solve(target, allowFreeTypeVariables);
405404
if (!viable) {

0 commit comments

Comments
 (0)