Skip to content

Commit 8868d76

Browse files
committed
AssociatedTypeInference: Add TypeWitnessSystem-oriented version of 'computeAbstractTypeWitness'
1 parent 50adc64 commit 8868d76

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

lib/Sema/TypeCheckProtocol.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ class AssociatedTypeInference {
11071107
/// Compute the default type witness from an associated type default,
11081108
/// if there is one.
11091109
Optional<AbstractTypeWitness>
1110-
computeDefaultTypeWitness(AssociatedTypeDecl *assocType);
1110+
computeDefaultTypeWitness(AssociatedTypeDecl *assocType) const;
11111111

11121112
/// Compute the "derived" type witness for an associated type that is
11131113
/// known to the compiler.
@@ -1118,6 +1118,11 @@ class AssociatedTypeInference {
11181118
Optional<AbstractTypeWitness>
11191119
computeAbstractTypeWitness(AssociatedTypeDecl *assocType);
11201120

1121+
/// Collect abstract type witnesses and feed them to the given system.
1122+
void collectAbstractTypeWitnesses(
1123+
TypeWitnessSystem &system,
1124+
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const;
1125+
11211126
/// Substitute the current type witnesses into the given interface type.
11221127
Type substCurrentTypeWitnesses(Type type);
11231128

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ Type AssociatedTypeInference::computeFixedTypeWitness(
868868

869869
Optional<AbstractTypeWitness>
870870
AssociatedTypeInference::computeDefaultTypeWitness(
871-
AssociatedTypeDecl *assocType) {
871+
AssociatedTypeDecl *assocType) const {
872872
// Go find a default definition.
873873
auto *const defaultedAssocType = findDefaultedAssociatedType(assocType);
874874
if (!defaultedAssocType)
@@ -937,6 +937,57 @@ AssociatedTypeInference::computeAbstractTypeWitness(
937937
return None;
938938
}
939939

940+
void AssociatedTypeInference::collectAbstractTypeWitnesses(
941+
TypeWitnessSystem &system,
942+
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const {
943+
// First, look at all the protocols the adoptee conforms to and feed the
944+
// same-type constraints in their requirement signatures to the system.
945+
for (auto *const conformedProto :
946+
adoptee->getAnyNominal()->getAllProtocols(/*sorted=*/true)) {
947+
// FIXME: The RequirementMachine will assert on re-entrant construction.
948+
// We should find a more principled way of breaking this cycle.
949+
if (ctx.isRecursivelyConstructingRequirementMachine(
950+
conformedProto->getGenericSignature().getCanonicalSignature()) ||
951+
ctx.isRecursivelyConstructingRequirementMachine(conformedProto) ||
952+
conformedProto->isComputingRequirementSignature())
953+
continue;
954+
955+
for (const auto &req :
956+
conformedProto->getRequirementSignature().getRequirements()) {
957+
if (req.getKind() != RequirementKind::SameType) {
958+
continue;
959+
}
960+
961+
system.addSameTypeRequirement(req);
962+
}
963+
}
964+
965+
// If the same-type constraints weren't enough to resolve an associated type,
966+
// look for more options.
967+
for (auto *const assocType : unresolvedAssocTypes) {
968+
if (system.hasResolvedTypeWitness(assocType->getName())) {
969+
continue;
970+
}
971+
972+
// If we find a default type definition, feed it to the system.
973+
if (const auto &typeWitness = computeDefaultTypeWitness(assocType)) {
974+
system.addDefaultTypeWitness(typeWitness->getType(),
975+
typeWitness->getDefaultedAssocType());
976+
} else {
977+
// As a last resort, look for a generic parameter that matches the name
978+
// of the associated type.
979+
if (auto genericSig = dc->getGenericSignatureOfContext()) {
980+
for (auto *gp : genericSig.getInnermostGenericParams()) {
981+
if (gp->getName() == assocType->getName()) {
982+
system.addTypeWitness(assocType->getName(),
983+
dc->mapTypeIntoContext(gp));
984+
}
985+
}
986+
}
987+
}
988+
}
989+
}
990+
940991
Type AssociatedTypeInference::substCurrentTypeWitnesses(Type type) {
941992
// Local function that folds dependent member types with non-dependent
942993
// bases into actual member references.

0 commit comments

Comments
 (0)