Skip to content

Commit fbb78cd

Browse files
committed
[Sema] Convert placeholder types to type vars wherever we open generics
Rename `openUnboundGenericTypes` to `convertInferableTypes`. In addition to unbound generics, this method also converts placeholder types to fresh type variables.
1 parent 65521b5 commit fbb78cd

File tree

4 files changed

+30
-22
lines changed

4 files changed

+30
-22
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3759,14 +3759,14 @@ class ConstraintSystem {
37593759
Type openUnboundGenericType(GenericTypeDecl *decl, Type parentTy,
37603760
ConstraintLocatorBuilder locator);
37613761

3762-
/// "Open" the given type by replacing any occurrences of unbound
3763-
/// generic types with bound generic types with fresh type variables as
3764-
/// generic arguments.
3762+
/// Replace placeholder types with fresh type variables, and unbound generic
3763+
/// types with bound generic types whose generic args are fresh type
3764+
/// variables.
37653765
///
3766-
/// \param type The type to open.
3766+
/// \param type The type on which to perform the conversion.
37673767
///
3768-
/// \returns The opened type.
3769-
Type openUnboundGenericTypes(Type type, ConstraintLocatorBuilder locator);
3768+
/// \returns The converted type.
3769+
Type convertInferableTypes(Type type, ConstraintLocatorBuilder locator);
37703770

37713771
/// "Open" the given type by replacing any occurrences of generic
37723772
/// parameter types and dependent member types with fresh type variables.

lib/Sema/CSBindings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,7 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const {
16461646
auto *dstLocator = TypeVar->getImpl().getLocator();
16471647

16481648
if (Binding.hasDefaultedLiteralProtocol()) {
1649-
type = cs.openUnboundGenericTypes(type, dstLocator);
1649+
type = cs.convertInferableTypes(type, dstLocator);
16501650
type = type->reconstituteSugar(/*recursive=*/false);
16511651
}
16521652

lib/Sema/CSGen.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,11 @@ namespace {
12411241
// FIXME: We should eliminate this case.
12421242
if (auto *PD = dyn_cast<ParamDecl>(VD)) {
12431243
if (!CS.hasType(PD)) {
1244-
if (knownType && knownType->hasUnboundGenericType())
1245-
knownType = CS.openUnboundGenericTypes(knownType, locator);
1244+
if (knownType &&
1245+
(knownType->hasUnboundGenericType() ||
1246+
knownType->hasPlaceholder())) {
1247+
knownType = CS.convertInferableTypes(knownType, locator);
1248+
}
12461249

12471250
CS.setType(
12481251
PD, knownType ? knownType
@@ -1311,7 +1314,7 @@ namespace {
13111314
if (E->isImplicit()) {
13121315
type = CS.getInstanceType(CS.cacheType(E));
13131316
assert(type && "Implicit type expr must have type set!");
1314-
type = CS.openUnboundGenericTypes(type, locator);
1317+
type = CS.convertInferableTypes(type, locator);
13151318
} else if (CS.hasType(E)) {
13161319
// If there's a type already set into the constraint system, honor it.
13171320
// FIXME: This supports the result builder transform, which sneakily
@@ -1992,7 +1995,7 @@ namespace {
19921995
Type externalType;
19931996
if (param->getTypeRepr()) {
19941997
auto declaredTy = CS.getVarType(param);
1995-
externalType = CS.openUnboundGenericTypes(declaredTy, paramLoc);
1998+
externalType = CS.convertInferableTypes(declaredTy, paramLoc);
19961999
} else {
19972000
// Let's allow parameters which haven't been explicitly typed
19982001
// to become holes by default, this helps in situations like
@@ -2208,7 +2211,7 @@ namespace {
22082211
// Look through reference storage types.
22092212
type = type->getReferenceStorageReferent();
22102213

2211-
Type openedType = CS.openUnboundGenericTypes(type, locator);
2214+
Type openedType = CS.convertInferableTypes(type, locator);
22122215
assert(openedType);
22132216

22142217
auto *subPattern = cast<TypedPattern>(pattern)->getSubPattern();
@@ -2369,7 +2372,7 @@ namespace {
23692372
// contained within the type resolver.
23702373
if (const auto preresolvedTy = enumPattern->getParentType()) {
23712374
const auto openedTy =
2372-
CS.openUnboundGenericTypes(preresolvedTy, patternMatchLoc);
2375+
CS.convertInferableTypes(preresolvedTy, patternMatchLoc);
23732376
assert(openedTy);
23742377
return openedTy;
23752378
}
@@ -3604,7 +3607,7 @@ static bool generateWrappedPropertyTypeConstraints(
36043607
auto *typeRepr = wrapperAttributes[i]->getTypeRepr();
36053608
auto *locator =
36063609
cs.getConstraintLocator(typeRepr, LocatorPathElt::ContextualType());
3607-
wrapperType = cs.openUnboundGenericTypes(rawWrapperType, locator);
3610+
wrapperType = cs.convertInferableTypes(rawWrapperType, locator);
36083611
cs.addConstraint(ConstraintKind::Equal, wrapperType, wrappedValueType,
36093612
locator);
36103613
cs.setContextualType(typeRepr, TypeLoc::withoutLoc(wrappedValueType),
@@ -3891,7 +3894,7 @@ bool ConstraintSystem::generateConstraints(
38913894
auto *wrappedVar = target.getAsUninitializedWrappedVar();
38923895
auto *outermostWrapper = wrappedVar->getAttachedPropertyWrappers().front();
38933896
auto *typeRepr = outermostWrapper->getTypeRepr();
3894-
auto backingType = openUnboundGenericTypes(outermostWrapper->getType(),
3897+
auto backingType = convertInferableTypes(outermostWrapper->getType(),
38953898
getConstraintLocator(typeRepr));
38963899
setType(typeRepr, backingType);
38973900

lib/Sema/ConstraintSystem.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ Optional<std::pair<unsigned, Expr *>> ConstraintSystem::getExprDepthAndParent(
652652
Type ConstraintSystem::openUnboundGenericType(
653653
GenericTypeDecl *decl, Type parentTy, ConstraintLocatorBuilder locator) {
654654
if (parentTy) {
655-
parentTy = openUnboundGenericTypes(parentTy, locator);
655+
parentTy = convertInferableTypes(parentTy, locator);
656656
}
657657

658658
// Open up the generic type.
@@ -777,17 +777,22 @@ static void checkNestedTypeConstraints(ConstraintSystem &cs, Type type,
777777
checkNestedTypeConstraints(cs, parentTy, locator);
778778
}
779779

780-
Type ConstraintSystem::openUnboundGenericTypes(
780+
Type ConstraintSystem::convertInferableTypes(
781781
Type type, ConstraintLocatorBuilder locator) {
782782
assert(!type->getCanonicalType()->hasTypeParameter());
783783

784-
if (!type->hasUnboundGenericType())
784+
if (!type->hasUnboundGenericType() && !type->hasPlaceholder())
785785
return type;
786786

787787
type = type.transform([&](Type type) -> Type {
788788
if (auto unbound = type->getAs<UnboundGenericType>()) {
789789
return openUnboundGenericType(unbound->getDecl(), unbound->getParent(),
790790
locator);
791+
} else if (type->is<PlaceholderType>()) {
792+
return createTypeVariable(getConstraintLocator(locator),
793+
TVO_CanBindToNoEscape |
794+
TVO_PrefersSubtypeBinding |
795+
TVO_CanBindToHole);
791796
}
792797

793798
return type;
@@ -1220,8 +1225,8 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
12201225

12211226
checkNestedTypeConstraints(*this, type, locator);
12221227

1223-
// Open the type.
1224-
type = openUnboundGenericTypes(type, locator);
1228+
// Convert any placeholder types and open generics.
1229+
type = convertInferableTypes(type, locator);
12251230

12261231
// Module types are not wrapped in metatypes.
12271232
if (type->is<ModuleType>())
@@ -1476,8 +1481,8 @@ ConstraintSystem::getTypeOfMemberReference(
14761481

14771482
checkNestedTypeConstraints(*this, memberTy, locator);
14781483

1479-
// Open the type if it was a reference to a generic type.
1480-
memberTy = openUnboundGenericTypes(memberTy, locator);
1484+
// Convert any placeholders and open any generics.
1485+
memberTy = convertInferableTypes(memberTy, locator);
14811486

14821487
// Wrap it in a metatype.
14831488
memberTy = MetatypeType::get(memberTy);

0 commit comments

Comments
 (0)