Skip to content

Commit 5494a1f

Browse files
committed
[Associated type inference] Factor out “abstract” witness inference.
NFC to reduce the size of the “find solutions” function.
1 parent 077a8a1 commit 5494a1f

File tree

2 files changed

+50
-45
lines changed

2 files changed

+50
-45
lines changed

lib/Sema/TypeCheckProtocol.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,14 @@ class AssociatedTypeInference {
734734
/// known to the compiler.
735735
Type computeDerivedTypeWitness(AssociatedTypeDecl *assocType);
736736

737+
/// Compute a type witness without using a specific potential witness,
738+
/// e.g., using a fixed type (from a refined protocol), default type
739+
/// on an associated type, or deriving the type.
740+
///
741+
/// \param allowDerived Whether to allow "derived" type witnesses.
742+
Type computeAbstractTypeWitness(AssociatedTypeDecl *assocType,
743+
bool allowDerived);
744+
737745
/// Substitute the current type witnesses into the given interface type.
738746
Type substCurrentTypeWitnesses(Type type);
739747

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,42 @@ Type AssociatedTypeInference::computeDerivedTypeWitness(
857857
return derivedType;
858858
}
859859

860+
Type
861+
AssociatedTypeInference::computeAbstractTypeWitness(
862+
AssociatedTypeDecl *assocType,
863+
bool allowDerived) {
864+
// We don't have a type witness for this associated type, so go
865+
// looking for more options.
866+
if (Type concreteType = computeFixedTypeWitness(assocType))
867+
return concreteType;
868+
869+
// If we can form a default type, do so.
870+
if (Type defaultType = computeDefaultTypeWitness(assocType))
871+
return defaultType;
872+
873+
// If we can derive a type witness, do so.
874+
if (allowDerived) {
875+
if (Type derivedType = computeDerivedTypeWitness(assocType))
876+
return derivedType;
877+
}
878+
879+
// If there is a generic parameter of the named type, use that.
880+
if (auto gpList = dc->getGenericParamsOfContext()) {
881+
GenericTypeParamDecl *foundGP = nullptr;
882+
for (auto gp : *gpList) {
883+
if (gp->getName() == assocType->getName()) {
884+
foundGP = gp;
885+
break;
886+
}
887+
}
888+
889+
if (foundGP)
890+
return dc->mapTypeIntoContext(foundGP->getDeclaredInterfaceType());
891+
}
892+
893+
return Type();
894+
}
895+
860896
Type AssociatedTypeInference::substCurrentTypeWitnesses(Type type) {
861897
// Local function that folds dependent member types with non-dependent
862898
// bases into actual member references.
@@ -1150,58 +1186,19 @@ void AssociatedTypeInference::findSolutionsRec(
11501186
continue;
11511187
}
11521188

1153-
// We don't have a type witness for this associated type, so go
1154-
// looking for more options.
1155-
if (Type concreteType = computeFixedTypeWitness(assocType)) {
1156-
if (concreteType->hasError()) {
1189+
// Try to compute the type without the aid of a specific potential
1190+
// witness.
1191+
if (Type type = computeAbstractTypeWitness(assocType,
1192+
/*allowDerived=*/true)) {
1193+
if (type->hasError()) {
11571194
recordMissing();
11581195
return;
11591196
}
11601197

1161-
typeWitnesses.insert(assocType, {concreteType, reqDepth});
1198+
typeWitnesses.insert(assocType, {type, reqDepth});
11621199
continue;
11631200
}
11641201

1165-
// If we can form a default type, do so.
1166-
if (Type defaultType = computeDefaultTypeWitness(assocType)) {
1167-
if (defaultType->hasError()) {
1168-
recordMissing();
1169-
return;
1170-
}
1171-
1172-
typeWitnesses.insert(assocType, {defaultType, reqDepth});
1173-
continue;
1174-
}
1175-
1176-
// If we can derive a type witness, do so.
1177-
if (Type derivedType = computeDerivedTypeWitness(assocType)) {
1178-
if (derivedType->hasError()) {
1179-
recordMissing();
1180-
return;
1181-
}
1182-
1183-
typeWitnesses.insert(assocType, {derivedType, reqDepth});
1184-
continue;
1185-
}
1186-
1187-
// If there is a generic parameter of the named type, use that.
1188-
if (auto gpList = dc->getGenericParamsOfContext()) {
1189-
GenericTypeParamDecl *foundGP = nullptr;
1190-
for (auto gp : *gpList) {
1191-
if (gp->getName() == assocType->getName()) {
1192-
foundGP = gp;
1193-
break;
1194-
}
1195-
}
1196-
1197-
if (foundGP) {
1198-
auto gpType = dc->mapTypeIntoContext(
1199-
foundGP->getDeclaredInterfaceType());
1200-
typeWitnesses.insert(assocType, {gpType, reqDepth});
1201-
continue;
1202-
}
1203-
}
1204-
12051202
// The solution is incomplete.
12061203
recordMissing();
12071204
return;

0 commit comments

Comments
 (0)