Skip to content

Commit 26943c5

Browse files
committed
Revert "AssociatedTypeInference: Delete old code for computing abstract type witnesses"
This reverts commit 98567e8.
1 parent d58bd27 commit 26943c5

File tree

2 files changed

+161
-5
lines changed

2 files changed

+161
-5
lines changed

lib/Sema/TypeCheckProtocol.h

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,61 @@ CheckTypeWitnessResult checkTypeWitness(Type type,
100100
const NormalProtocolConformance *Conf,
101101
SubstOptions options = None);
102102

103+
/// Describes the means of inferring an abstract type witness.
104+
enum class AbstractTypeWitnessKind : uint8_t {
105+
/// The type witness was inferred via a same-type-to-concrete constraint
106+
/// in a protocol requirement signature.
107+
Fixed,
108+
109+
/// The type witness was inferred via a defaulted associated type.
110+
Default,
111+
112+
/// The type witness was inferred to a generic parameter of the
113+
/// conforming type.
114+
GenericParam,
115+
};
116+
117+
/// A type witness inferred without the aid of a specific potential
118+
/// value witness.
119+
class AbstractTypeWitness {
120+
AbstractTypeWitnessKind Kind;
121+
AssociatedTypeDecl *AssocType;
122+
Type TheType;
123+
124+
/// When this is a default type witness, the declaration responsible for it.
125+
/// May not necessarilly match \c AssocType.
126+
AssociatedTypeDecl *DefaultedAssocType;
127+
128+
AbstractTypeWitness(AbstractTypeWitnessKind Kind,
129+
AssociatedTypeDecl *AssocType, Type TheType,
130+
AssociatedTypeDecl *DefaultedAssocType)
131+
: Kind(Kind), AssocType(AssocType), TheType(TheType),
132+
DefaultedAssocType(DefaultedAssocType) {
133+
assert(AssocType && TheType);
134+
}
135+
136+
public:
137+
static AbstractTypeWitness forFixed(AssociatedTypeDecl *assocType, Type type);
138+
139+
static AbstractTypeWitness forDefault(AssociatedTypeDecl *assocType,
140+
Type type,
141+
AssociatedTypeDecl *defaultedAssocType);
142+
143+
static AbstractTypeWitness forGenericParam(AssociatedTypeDecl *assocType,
144+
Type type);
145+
146+
public:
147+
AbstractTypeWitnessKind getKind() const { return Kind; }
148+
149+
AssociatedTypeDecl *getAssocType() const { return AssocType; }
150+
151+
Type getType() const { return TheType; }
152+
153+
AssociatedTypeDecl *getDefaultedAssocType() const {
154+
return DefaultedAssocType;
155+
}
156+
};
157+
103158
/// The set of associated types that have been inferred by matching
104159
/// the given value witness to its corresponding requirement.
105160
struct InferredAssociatedTypesByWitness {
@@ -1076,16 +1131,24 @@ class AssociatedTypeInference {
10761131
ConformanceChecker &checker,
10771132
const llvm::SetVector<AssociatedTypeDecl *> &assocTypes);
10781133

1134+
/// Compute a "fixed" type witness for an associated type, e.g.,
1135+
/// if the refined protocol requires it to be equivalent to some other type.
1136+
Type computeFixedTypeWitness(AssociatedTypeDecl *assocType);
1137+
10791138
/// Compute the default type witness from an associated type default,
10801139
/// if there is one.
1081-
Optional<std::pair<AssociatedTypeDecl *, Type>>
1140+
Optional<AbstractTypeWitness>
10821141
computeDefaultTypeWitness(AssociatedTypeDecl *assocType) const;
10831142

10841143
/// Compute the "derived" type witness for an associated type that is
10851144
/// known to the compiler.
10861145
std::pair<Type, TypeDecl *>
10871146
computeDerivedTypeWitness(AssociatedTypeDecl *assocType);
10881147

1148+
/// Compute a type witness without using a specific potential witness.
1149+
Optional<AbstractTypeWitness>
1150+
computeAbstractTypeWitness(AssociatedTypeDecl *assocType);
1151+
10891152
/// Collect abstract type witnesses and feed them to the given system.
10901153
void collectAbstractTypeWitnesses(
10911154
TypeWitnessSystem &system,

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,25 @@ STATISTIC(NumDuplicateSolutionStates,
4444

4545
using namespace swift;
4646

47+
AbstractTypeWitness AbstractTypeWitness::forFixed(AssociatedTypeDecl *assocType,
48+
Type type) {
49+
return AbstractTypeWitness(AbstractTypeWitnessKind::Fixed, assocType, type,
50+
nullptr);
51+
}
52+
53+
AbstractTypeWitness
54+
AbstractTypeWitness::forDefault(AssociatedTypeDecl *assocType, Type type,
55+
AssociatedTypeDecl *defaultedAssocType) {
56+
return AbstractTypeWitness(AbstractTypeWitnessKind::Default, assocType, type,
57+
defaultedAssocType);
58+
}
59+
60+
AbstractTypeWitness
61+
AbstractTypeWitness::forGenericParam(AssociatedTypeDecl *assocType, Type type) {
62+
return AbstractTypeWitness(AbstractTypeWitnessKind::GenericParam, assocType,
63+
type, nullptr);
64+
}
65+
4766
void InferredAssociatedTypesByWitness::dump() const {
4867
dump(llvm::errs(), 0);
4968
}
@@ -798,7 +817,56 @@ AssociatedTypeDecl *AssociatedTypeInference::findDefaultedAssociatedType(
798817
return results.size() == 1 ? results.front() : nullptr;
799818
}
800819

801-
Optional<std::pair<AssociatedTypeDecl *, Type>>
820+
Type AssociatedTypeInference::computeFixedTypeWitness(
821+
AssociatedTypeDecl *assocType) {
822+
Type resultType;
823+
824+
// Look at all of the inherited protocols to determine whether they
825+
// require a fixed type for this associated type.
826+
for (auto conformedProto : adoptee->getAnyNominal()->getAllProtocols()) {
827+
if (conformedProto != assocType->getProtocol() &&
828+
!conformedProto->inheritsFrom(assocType->getProtocol()))
829+
continue;
830+
831+
auto sig = conformedProto->getGenericSignature();
832+
833+
// FIXME: The RequirementMachine will assert on re-entrant construction.
834+
// We should find a more principled way of breaking this cycle.
835+
if (ctx.isRecursivelyConstructingRequirementMachine(sig.getCanonicalSignature()) ||
836+
ctx.isRecursivelyConstructingRequirementMachine(conformedProto) ||
837+
conformedProto->isComputingRequirementSignature())
838+
continue;
839+
840+
auto selfTy = conformedProto->getSelfInterfaceType();
841+
if (!sig->requiresProtocol(selfTy, assocType->getProtocol()))
842+
continue;
843+
844+
auto structuralTy = DependentMemberType::get(selfTy, assocType->getName());
845+
const auto ty = sig.getCanonicalTypeInContext(structuralTy);
846+
847+
// A dependent member type with an identical base and name indicates that
848+
// the protocol does not same-type constrain it in any way; move on to
849+
// the next protocol.
850+
if (auto *const memberTy = ty->getAs<DependentMemberType>()) {
851+
if (memberTy->getBase()->isEqual(selfTy) &&
852+
memberTy->getName() == assocType->getName())
853+
continue;
854+
}
855+
856+
if (!resultType) {
857+
resultType = ty;
858+
continue;
859+
}
860+
861+
// FIXME: Bailing out on ambiguity.
862+
if (!resultType->isEqual(ty))
863+
return Type();
864+
}
865+
866+
return resultType;
867+
}
868+
869+
Optional<AbstractTypeWitness>
802870
AssociatedTypeInference::computeDefaultTypeWitness(
803871
AssociatedTypeDecl *assocType) const {
804872
// Go find a default definition.
@@ -814,7 +882,8 @@ AssociatedTypeInference::computeDefaultTypeWitness(
814882
if (defaultType->hasError())
815883
return None;
816884

817-
return std::make_pair(defaultedAssocType, defaultType);
885+
return AbstractTypeWitness::forDefault(assocType, defaultType,
886+
defaultedAssocType);
818887
}
819888

820889
std::pair<Type, TypeDecl *>
@@ -845,6 +914,29 @@ AssociatedTypeInference::computeDerivedTypeWitness(
845914
return result;
846915
}
847916

917+
Optional<AbstractTypeWitness>
918+
AssociatedTypeInference::computeAbstractTypeWitness(
919+
AssociatedTypeDecl *assocType) {
920+
// We don't have a type witness for this associated type, so go
921+
// looking for more options.
922+
if (Type concreteType = computeFixedTypeWitness(assocType))
923+
return AbstractTypeWitness::forFixed(assocType, concreteType);
924+
925+
// If we can form a default type, do so.
926+
if (const auto &typeWitness = computeDefaultTypeWitness(assocType))
927+
return typeWitness;
928+
929+
// If there is a generic parameter of the named type, use that.
930+
if (auto genericSig = dc->getGenericSignatureOfContext()) {
931+
for (auto gp : genericSig.getInnermostGenericParams()) {
932+
if (gp->getName() == assocType->getName())
933+
return AbstractTypeWitness::forGenericParam(assocType, gp);
934+
}
935+
}
936+
937+
return None;
938+
}
939+
848940
void AssociatedTypeInference::collectAbstractTypeWitnesses(
849941
TypeWitnessSystem &system,
850942
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const {
@@ -878,8 +970,9 @@ void AssociatedTypeInference::collectAbstractTypeWitnesses(
878970
}
879971

880972
// If we find a default type definition, feed it to the system.
881-
if (const auto declAndType = computeDefaultTypeWitness(assocType)) {
882-
system.addDefaultTypeWitness(declAndType->second, declAndType->first);
973+
if (const auto &typeWitness = computeDefaultTypeWitness(assocType)) {
974+
system.addDefaultTypeWitness(typeWitness->getType(),
975+
typeWitness->getDefaultedAssocType());
883976
} else {
884977
// As a last resort, look for a generic parameter that matches the name
885978
// of the associated type.

0 commit comments

Comments
 (0)