@@ -491,36 +491,10 @@ const RequirementSource *RequirementSource::forNestedTypeNameMatch(
491
491
0 , WrittenRequirementLoc ());
492
492
}
493
493
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
-
514
494
const RequirementSource *RequirementSource::viaProtocolRequirement (
515
495
GenericSignatureBuilder &builder, Type dependentType,
516
496
ProtocolDecl *protocol,
517
497
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
-
524
498
REQUIREMENT_SOURCE_FACTORY_BODY (
525
499
(nodeID, ProtocolRequirement, this ,
526
500
dependentType.getPointer (), protocol,
@@ -576,6 +550,31 @@ PotentialArchetype *RequirementSource::getRootPotentialArchetype() const {
576
550
return root->storage .rootArchetype ;
577
551
}
578
552
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
+
579
578
Type RequirementSource::getStoredType () const {
580
579
switch (storageKind) {
581
580
case StorageKind::RootArchetype:
@@ -778,9 +777,25 @@ void RequirementSource::print(llvm::raw_ostream &out,
778
777
}
779
778
}
780
779
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
+
781
797
const RequirementSource *FloatingRequirementSource::getSource (
782
- PotentialArchetype *pa,
783
- Type dependentType) const {
798
+ PotentialArchetype *pa) const {
784
799
switch (kind) {
785
800
case Resolved:
786
801
return storage.get <const RequirementSource *>();
@@ -796,9 +811,15 @@ const RequirementSource *FloatingRequirementSource::getSource(
796
811
return RequirementSource::forInferred (pa, storage.get <const TypeRepr *>());
797
812
798
813
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
+
802
823
return storage.get <const RequirementSource *>()
803
824
->viaProtocolRequirement (*pa->getBuilder (), dependentType,
804
825
protocolReq.protocol , protocolReq.written );
@@ -2113,9 +2134,7 @@ bool GenericSignatureBuilder::addGenericParameterRequirements(
2113
2134
2114
2135
// Add the requirements from the declaration.
2115
2136
llvm::SmallPtrSet<ProtocolDecl *, 8 > visited;
2116
- return addInheritedRequirements (GenericParam, PA,
2117
- GenericParam->getDeclaredInterfaceType (),
2118
- nullptr , visited);
2137
+ return addInheritedRequirements (GenericParam, PA, nullptr , visited);
2119
2138
}
2120
2139
2121
2140
void GenericSignatureBuilder::addGenericParameter (GenericTypeParamType *GenericParam) {
@@ -2226,8 +2245,7 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
2226
2245
if (auto resolver = getLazyResolver ())
2227
2246
resolver->resolveInheritedProtocols (Proto);
2228
2247
2229
- if (addInheritedRequirements (Proto, PAT, Proto->getSelfInterfaceType (),
2230
- Source, Visited))
2248
+ if (addInheritedRequirements (Proto, PAT, Source, Visited))
2231
2249
return true ;
2232
2250
2233
2251
// Add any requirements in the where clause on the protocol.
@@ -2246,9 +2264,7 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
2246
2264
auto AssocPA = T->getNestedType (AssocType, *this );
2247
2265
2248
2266
if (AssocPA != T) {
2249
- if (addInheritedRequirements (AssocType, AssocPA,
2250
- AssocType->getDeclaredInterfaceType (),
2251
- Source, Visited))
2267
+ if (addInheritedRequirements (AssocType, AssocPA, Source, Visited))
2252
2268
return true ;
2253
2269
}
2254
2270
if (auto WhereClause = AssocType->getTrailingWhereClause ()) {
@@ -2298,8 +2314,7 @@ bool GenericSignatureBuilder::addLayoutRequirementDirect(
2298
2314
bool GenericSignatureBuilder::addLayoutRequirement (
2299
2315
UnresolvedType subject,
2300
2316
LayoutConstraint layout,
2301
- FloatingRequirementSource source,
2302
- Type dependentType) {
2317
+ FloatingRequirementSource source) {
2303
2318
// Resolve the subject.
2304
2319
auto resolvedSubject = resolve (subject, source);
2305
2320
if (!resolvedSubject) {
@@ -2325,8 +2340,7 @@ bool GenericSignatureBuilder::addLayoutRequirement(
2325
2340
}
2326
2341
2327
2342
auto pa = resolvedSubject->getPotentialArchetype ();
2328
- return addLayoutRequirementDirect (pa, layout,
2329
- source.getSource (pa, dependentType));
2343
+ return addLayoutRequirementDirect (pa, layout, source.getSource (pa));
2330
2344
}
2331
2345
2332
2346
bool GenericSignatureBuilder::updateSuperclass (
@@ -2424,7 +2438,6 @@ bool GenericSignatureBuilder::addTypeRequirement(
2424
2438
UnresolvedType subject,
2425
2439
UnresolvedType constraint,
2426
2440
FloatingRequirementSource source,
2427
- Type dependentType,
2428
2441
llvm::SmallPtrSetImpl<ProtocolDecl *> *visited) {
2429
2442
// Make sure we always have a "visited" set to pass down.
2430
2443
SmallPtrSet<ProtocolDecl *, 4 > visitedSet;
@@ -2503,7 +2516,7 @@ bool GenericSignatureBuilder::addTypeRequirement(
2503
2516
auto subjectPA = resolvedSubject->getPotentialArchetype ();
2504
2517
assert (subjectPA && " No potential archetype?" );
2505
2518
2506
- auto resolvedSource = source.getSource (subjectPA, dependentType );
2519
+ auto resolvedSource = source.getSource (subjectPA);
2507
2520
2508
2521
// Protocol requirements.
2509
2522
if (constraintType->isExistentialType ()) {
@@ -2813,15 +2826,12 @@ bool GenericSignatureBuilder::addSameTypeRequirementDirect(
2813
2826
// If both sides of the requirement are type parameters, equate them.
2814
2827
if (pa1 && pa2) {
2815
2828
return addSameTypeRequirementBetweenArchetypes (pa1, pa2,
2816
- source.getSource (pa1,
2817
- Type ()));
2829
+ source.getSource (pa1));
2818
2830
// If just one side is a type parameter, map it to a concrete type.
2819
2831
} else if (pa1) {
2820
- return addSameTypeRequirementToConcrete (pa1, t2,
2821
- source.getSource (pa1, Type ()));
2832
+ return addSameTypeRequirementToConcrete (pa1, t2, source.getSource (pa1));
2822
2833
} else if (pa2) {
2823
- return addSameTypeRequirementToConcrete (pa2, t1,
2824
- source.getSource (pa2, Type ()));
2834
+ return addSameTypeRequirementToConcrete (pa2, t1, source.getSource (pa2));
2825
2835
} else {
2826
2836
return addSameTypeRequirementBetweenConcrete (t1, t2, source,
2827
2837
diagnoseMismatch);
@@ -2853,7 +2863,6 @@ void GenericSignatureBuilder::markPotentialArchetypeRecursive(
2853
2863
bool GenericSignatureBuilder::addInheritedRequirements (
2854
2864
TypeDecl *decl,
2855
2865
PotentialArchetype *pa,
2856
- Type dependentType,
2857
2866
const RequirementSource *parentSource,
2858
2867
llvm::SmallPtrSetImpl<ProtocolDecl *> &visited) {
2859
2868
if (isa<AssociatedTypeDecl>(decl) &&
@@ -2891,8 +2900,7 @@ bool GenericSignatureBuilder::addInheritedRequirements(
2891
2900
};
2892
2901
2893
2902
// Protocol requirement.
2894
- return addTypeRequirement (pa, inheritedType, getFloatingSource (),
2895
- dependentType, &visited);
2903
+ return addTypeRequirement (pa, inheritedType, getFloatingSource (), &visited);
2896
2904
});
2897
2905
}
2898
2906
@@ -2916,12 +2924,12 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
2916
2924
case RequirementReprKind::LayoutConstraint:
2917
2925
return addLayoutRequirement (subst (Req->getSubject ()),
2918
2926
Req->getLayoutConstraint (),
2919
- source, Req-> getSubject () );
2927
+ source);
2920
2928
2921
2929
case RequirementReprKind::TypeConstraint:
2922
2930
return addTypeRequirement (subst (Req->getSubject ()),
2923
2931
subst (Req->getConstraint ()),
2924
- source, Req-> getSubject () );
2932
+ source);
2925
2933
2926
2934
case RequirementReprKind::SameType:
2927
2935
// Require that at least one side of the requirement contain a type
@@ -2973,14 +2981,12 @@ bool GenericSignatureBuilder::addRequirement(
2973
2981
case RequirementKind::Conformance:
2974
2982
return addTypeRequirement (subst (req.getFirstType ()),
2975
2983
subst (req.getSecondType ()),
2976
- source, req.getFirstType (),
2977
- &Visited);
2984
+ source, &Visited);
2978
2985
2979
2986
case RequirementKind::Layout:
2980
2987
return addLayoutRequirement (subst (req.getFirstType ()),
2981
2988
req.getLayoutConstraint (),
2982
- source,
2983
- req.getFirstType ());
2989
+ source);
2984
2990
2985
2991
case RequirementKind::SameType:
2986
2992
return addSameTypeRequirement (
0 commit comments