Skip to content

Commit a36bdff

Browse files
authored
Merge pull request #8657 from DougGregor/gsb-dependent-type-cleanup
2 parents 3adc327 + fb80237 commit a36bdff

File tree

2 files changed

+78
-76
lines changed

2 files changed

+78
-76
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ class GenericSignatureBuilder {
280280
bool addTypeRequirement(UnresolvedType subject,
281281
UnresolvedType constraint,
282282
FloatingRequirementSource source,
283-
Type dependentType,
284283
llvm::SmallPtrSetImpl<ProtocolDecl *> *visited
285284
= nullptr);
286285

@@ -314,25 +313,13 @@ class GenericSignatureBuilder {
314313
const RequirementSource *Source);
315314

316315
/// Add a new layout requirement to the subject.
317-
///
318-
/// FIXME: The "dependent type" is the subject type pre-substitution. We
319-
/// should be able to compute this!
320316
bool addLayoutRequirement(UnresolvedType subject,
321317
LayoutConstraint layout,
322-
FloatingRequirementSource source,
323-
Type dependentType);
318+
FloatingRequirementSource source);
324319

325320
/// Add the requirements placed on the given type parameter
326321
/// to the given potential archetype.
327-
///
328-
/// \param dependentType A dependent type thar describes \c pa relative to
329-
/// its protocol, for protocol requirements.
330-
///
331-
/// FIXME: \c dependentType will be derivable from \c parentSource and \c pa
332-
/// when we're no longer putting conformance requirements directly on the
333-
/// representative.
334322
bool addInheritedRequirements(TypeDecl *decl, PotentialArchetype *pa,
335-
Type dependentType,
336323
const RequirementSource *parentSource,
337324
llvm::SmallPtrSetImpl<ProtocolDecl *> &visited);
338325

@@ -891,6 +878,10 @@ class GenericSignatureBuilder::RequirementSource final
891878
/// Retrieve the potential archetype at the root.
892879
PotentialArchetype *getRootPotentialArchetype() const;
893880

881+
/// Retrieve the potential archetype to which this source refers.
882+
PotentialArchetype *getAffectedPotentialArchetype(
883+
GenericSignatureBuilder &builder) const;
884+
894885
/// Whether the requirement is inferred or derived from an inferred
895886
/// requirment.
896887
bool isInferredRequirement() const {
@@ -1073,8 +1064,7 @@ class GenericSignatureBuilder::FloatingRequirementSource {
10731064

10741065
/// Retrieve the complete requirement source rooted at the given potential
10751066
/// archetype.
1076-
const RequirementSource *getSource(PotentialArchetype *pa,
1077-
Type dependentType) const;
1067+
const RequirementSource *getSource(PotentialArchetype *pa) const;
10781068

10791069
/// Retrieve the source location for this requirement.
10801070
SourceLoc getLoc() const;
@@ -1355,6 +1345,12 @@ class GenericSignatureBuilder::PotentialArchetype {
13551345
/// the number of associated type references.
13561346
unsigned getNestingDepth() const;
13571347

1348+
/// Determine whether two potential archetypes are in the same equivalence
1349+
/// class.
1350+
bool isInSameEquivalenceClassAs(const PotentialArchetype *other) const {
1351+
return getRepresentative() == other->getRepresentative();
1352+
}
1353+
13581354
/// Retrieve the equivalence class, if it's already present.
13591355
///
13601356
/// Otherwise, return null.

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 66 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -491,36 +491,10 @@ const RequirementSource *RequirementSource::forNestedTypeNameMatch(
491491
0, WrittenRequirementLoc());
492492
}
493493

494-
/// "Re-root" the given type parameter on the protocol's "Self", which replaces
495-
/// the
496-
static Type rerootOnProtocolSelf(Type depTy, ProtocolDecl *protocol) {
497-
if (auto depMemTy = depTy->getAs<DependentMemberType>()) {
498-
// FIXME: Allowing an identifier here is a hack.
499-
if (auto assocType = depMemTy->getAssocType()) {
500-
return DependentMemberType::get(
501-
rerootOnProtocolSelf(depMemTy->getBase(), protocol),
502-
assocType);
503-
}
504-
505-
return DependentMemberType::get(
506-
rerootOnProtocolSelf(depMemTy->getBase(), protocol),
507-
depMemTy->getName());
508-
}
509-
510-
assert(depTy->is<GenericTypeParamType>() && "not a type parameter!");
511-
return protocol->getSelfInterfaceType();
512-
}
513-
514494
const RequirementSource *RequirementSource::viaProtocolRequirement(
515495
GenericSignatureBuilder &builder, Type dependentType,
516496
ProtocolDecl *protocol,
517497
GenericSignatureBuilder::WrittenRequirementLoc writtenLoc) const {
518-
// Re-root the dependent type on the protocol.
519-
// FIXME: we really want to canonicalize w.r.t. the requirement signature of
520-
// the protocol, but it might not have been computed yet.
521-
if (dependentType)
522-
dependentType = rerootOnProtocolSelf(dependentType, protocol);
523-
524498
REQUIREMENT_SOURCE_FACTORY_BODY(
525499
(nodeID, ProtocolRequirement, this,
526500
dependentType.getPointer(), protocol,
@@ -576,6 +550,31 @@ PotentialArchetype *RequirementSource::getRootPotentialArchetype() const {
576550
return root->storage.rootArchetype;
577551
}
578552

553+
PotentialArchetype *RequirementSource::getAffectedPotentialArchetype(GenericSignatureBuilder &builder) const {
554+
switch (kind) {
555+
case RequirementSource::Parent:
556+
return parent->getAffectedPotentialArchetype(builder)
557+
->getNestedType(getAssociatedType(), builder);
558+
559+
case RequirementSource::NestedTypeNameMatch:
560+
return getRootPotentialArchetype();
561+
562+
case RequirementSource::Explicit:
563+
case RequirementSource::Inferred:
564+
case RequirementSource::RequirementSignatureSelf:
565+
return getRootPotentialArchetype();
566+
567+
case RequirementSource::Concrete:
568+
case RequirementSource::Superclass:
569+
return parent->getAffectedPotentialArchetype(builder);
570+
571+
case RequirementSource::ProtocolRequirement:
572+
return replaceSelfWithPotentialArchetype(
573+
parent->getAffectedPotentialArchetype(builder),
574+
getStoredType());
575+
}
576+
}
577+
579578
Type RequirementSource::getStoredType() const {
580579
switch (storageKind) {
581580
case StorageKind::RootArchetype:
@@ -778,9 +777,25 @@ void RequirementSource::print(llvm::raw_ostream &out,
778777
}
779778
}
780779

780+
/// Form the dependent type such that the given protocol's \c Self can be
781+
/// replaced by \c basePA to reach \c pa.
782+
static Type formProtocolRelativeType(ProtocolDecl *proto,
783+
PotentialArchetype *basePA,
784+
PotentialArchetype *pa) {
785+
// Basis case: we've hit the base potential archetype.
786+
if (basePA->isInSameEquivalenceClassAs(pa))
787+
return proto->getSelfInterfaceType();
788+
789+
// Recursive case: form a dependent member type.
790+
auto baseType = formProtocolRelativeType(proto, basePA, pa->getParent());
791+
if (auto assocType = pa->getResolvedAssociatedType())
792+
return DependentMemberType::get(baseType, assocType);
793+
794+
return DependentMemberType::get(baseType, pa->getNestedName());
795+
}
796+
781797
const RequirementSource *FloatingRequirementSource::getSource(
782-
PotentialArchetype *pa,
783-
Type dependentType) const {
798+
PotentialArchetype *pa) const {
784799
switch (kind) {
785800
case Resolved:
786801
return storage.get<const RequirementSource *>();
@@ -796,9 +811,15 @@ const RequirementSource *FloatingRequirementSource::getSource(
796811
return RequirementSource::forInferred(pa, storage.get<const TypeRepr *>());
797812

798813
case AbstractProtocol: {
799-
// FIXME: dependent type would be derivable from \c pa and \c this if we
800-
// were sure to never "re-root" \c pa by placing the requirement on
801-
// the representative of the equivalence class.
814+
// Derive the dependent type on which this requirement was written. It is
815+
// the path from
816+
auto baseSource = storage.get<const RequirementSource *>();
817+
auto baseSourcePA =
818+
baseSource->getAffectedPotentialArchetype(*pa->getBuilder());
819+
820+
auto dependentType =
821+
formProtocolRelativeType(protocolReq.protocol, baseSourcePA, pa);
822+
802823
return storage.get<const RequirementSource *>()
803824
->viaProtocolRequirement(*pa->getBuilder(), dependentType,
804825
protocolReq.protocol, protocolReq.written);
@@ -2113,9 +2134,7 @@ bool GenericSignatureBuilder::addGenericParameterRequirements(
21132134

21142135
// Add the requirements from the declaration.
21152136
llvm::SmallPtrSet<ProtocolDecl *, 8> visited;
2116-
return addInheritedRequirements(GenericParam, PA,
2117-
GenericParam->getDeclaredInterfaceType(),
2118-
nullptr, visited);
2137+
return addInheritedRequirements(GenericParam, PA, nullptr, visited);
21192138
}
21202139

21212140
void GenericSignatureBuilder::addGenericParameter(GenericTypeParamType *GenericParam) {
@@ -2226,8 +2245,7 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
22262245
if (auto resolver = getLazyResolver())
22272246
resolver->resolveInheritedProtocols(Proto);
22282247

2229-
if (addInheritedRequirements(Proto, PAT, Proto->getSelfInterfaceType(),
2230-
Source, Visited))
2248+
if (addInheritedRequirements(Proto, PAT, Source, Visited))
22312249
return true;
22322250

22332251
// Add any requirements in the where clause on the protocol.
@@ -2246,9 +2264,7 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
22462264
auto AssocPA = T->getNestedType(AssocType, *this);
22472265

22482266
if (AssocPA != T) {
2249-
if (addInheritedRequirements(AssocType, AssocPA,
2250-
AssocType->getDeclaredInterfaceType(),
2251-
Source, Visited))
2267+
if (addInheritedRequirements(AssocType, AssocPA, Source, Visited))
22522268
return true;
22532269
}
22542270
if (auto WhereClause = AssocType->getTrailingWhereClause()) {
@@ -2298,8 +2314,7 @@ bool GenericSignatureBuilder::addLayoutRequirementDirect(
22982314
bool GenericSignatureBuilder::addLayoutRequirement(
22992315
UnresolvedType subject,
23002316
LayoutConstraint layout,
2301-
FloatingRequirementSource source,
2302-
Type dependentType) {
2317+
FloatingRequirementSource source) {
23032318
// Resolve the subject.
23042319
auto resolvedSubject = resolve(subject, source);
23052320
if (!resolvedSubject) {
@@ -2325,8 +2340,7 @@ bool GenericSignatureBuilder::addLayoutRequirement(
23252340
}
23262341

23272342
auto pa = resolvedSubject->getPotentialArchetype();
2328-
return addLayoutRequirementDirect(pa, layout,
2329-
source.getSource(pa, dependentType));
2343+
return addLayoutRequirementDirect(pa, layout, source.getSource(pa));
23302344
}
23312345

23322346
bool GenericSignatureBuilder::updateSuperclass(
@@ -2424,7 +2438,6 @@ bool GenericSignatureBuilder::addTypeRequirement(
24242438
UnresolvedType subject,
24252439
UnresolvedType constraint,
24262440
FloatingRequirementSource source,
2427-
Type dependentType,
24282441
llvm::SmallPtrSetImpl<ProtocolDecl *> *visited) {
24292442
// Make sure we always have a "visited" set to pass down.
24302443
SmallPtrSet<ProtocolDecl *, 4> visitedSet;
@@ -2503,7 +2516,7 @@ bool GenericSignatureBuilder::addTypeRequirement(
25032516
auto subjectPA = resolvedSubject->getPotentialArchetype();
25042517
assert(subjectPA && "No potential archetype?");
25052518

2506-
auto resolvedSource = source.getSource(subjectPA, dependentType);
2519+
auto resolvedSource = source.getSource(subjectPA);
25072520

25082521
// Protocol requirements.
25092522
if (constraintType->isExistentialType()) {
@@ -2813,15 +2826,12 @@ bool GenericSignatureBuilder::addSameTypeRequirementDirect(
28132826
// If both sides of the requirement are type parameters, equate them.
28142827
if (pa1 && pa2) {
28152828
return addSameTypeRequirementBetweenArchetypes(pa1, pa2,
2816-
source.getSource(pa1,
2817-
Type()));
2829+
source.getSource(pa1));
28182830
// If just one side is a type parameter, map it to a concrete type.
28192831
} else if (pa1) {
2820-
return addSameTypeRequirementToConcrete(pa1, t2,
2821-
source.getSource(pa1, Type()));
2832+
return addSameTypeRequirementToConcrete(pa1, t2, source.getSource(pa1));
28222833
} else if (pa2) {
2823-
return addSameTypeRequirementToConcrete(pa2, t1,
2824-
source.getSource(pa2, Type()));
2834+
return addSameTypeRequirementToConcrete(pa2, t1, source.getSource(pa2));
28252835
} else {
28262836
return addSameTypeRequirementBetweenConcrete(t1, t2, source,
28272837
diagnoseMismatch);
@@ -2853,7 +2863,6 @@ void GenericSignatureBuilder::markPotentialArchetypeRecursive(
28532863
bool GenericSignatureBuilder::addInheritedRequirements(
28542864
TypeDecl *decl,
28552865
PotentialArchetype *pa,
2856-
Type dependentType,
28572866
const RequirementSource *parentSource,
28582867
llvm::SmallPtrSetImpl<ProtocolDecl *> &visited) {
28592868
if (isa<AssociatedTypeDecl>(decl) &&
@@ -2891,8 +2900,7 @@ bool GenericSignatureBuilder::addInheritedRequirements(
28912900
};
28922901

28932902
// Protocol requirement.
2894-
return addTypeRequirement(pa, inheritedType, getFloatingSource(),
2895-
dependentType, &visited);
2903+
return addTypeRequirement(pa, inheritedType, getFloatingSource(), &visited);
28962904
});
28972905
}
28982906

@@ -2916,12 +2924,12 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
29162924
case RequirementReprKind::LayoutConstraint:
29172925
return addLayoutRequirement(subst(Req->getSubject()),
29182926
Req->getLayoutConstraint(),
2919-
source, Req->getSubject());
2927+
source);
29202928

29212929
case RequirementReprKind::TypeConstraint:
29222930
return addTypeRequirement(subst(Req->getSubject()),
29232931
subst(Req->getConstraint()),
2924-
source, Req->getSubject());
2932+
source);
29252933

29262934
case RequirementReprKind::SameType:
29272935
// Require that at least one side of the requirement contain a type
@@ -2973,14 +2981,12 @@ bool GenericSignatureBuilder::addRequirement(
29732981
case RequirementKind::Conformance:
29742982
return addTypeRequirement(subst(req.getFirstType()),
29752983
subst(req.getSecondType()),
2976-
source, req.getFirstType(),
2977-
&Visited);
2984+
source, &Visited);
29782985

29792986
case RequirementKind::Layout:
29802987
return addLayoutRequirement(subst(req.getFirstType()),
29812988
req.getLayoutConstraint(),
2982-
source,
2983-
req.getFirstType());
2989+
source);
29842990

29852991
case RequirementKind::SameType:
29862992
return addSameTypeRequirement(

0 commit comments

Comments
 (0)