@@ -1660,26 +1660,6 @@ Type Constraint<T>::getSubjectDependentType(
1660
1660
return subject.get <PotentialArchetype *>()->getDependentType (genericParams);
1661
1661
}
1662
1662
1663
- template <typename T>
1664
- PotentialArchetype *Constraint<T>::realizeSubjectPotentialArchetype(
1665
- GenericSignatureBuilder &builder) const {
1666
- if (auto pa = subject.dyn_cast <PotentialArchetype *>())
1667
- return pa;
1668
-
1669
- auto type = subject.get <Type>();
1670
- auto pa =
1671
- builder.maybeResolveEquivalenceClass (type,
1672
- ArchetypeResolutionKind::WellFormed,
1673
- /* wantExactPotentialArchetype=*/ true )
1674
- .realizePotentialArchetype (builder);
1675
- assert (pa && " Invalid dependent type" );
1676
-
1677
- // Cache the result, so we don't need to realize the potential archetype
1678
- // again.
1679
- subject = pa;
1680
- return pa;
1681
- }
1682
-
1683
1663
template <typename T>
1684
1664
bool Constraint<T>::isSubjectEqualTo(const PotentialArchetype *pa) const {
1685
1665
if (auto subjectPA = subject.dyn_cast <PotentialArchetype *>())
@@ -4127,39 +4107,38 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4127
4107
}
4128
4108
4129
4109
ConstraintResult GenericSignatureBuilder::addSameTypeRequirementToConcrete (
4130
- PotentialArchetype *T,
4131
- Type Concrete,
4132
- const RequirementSource *Source) {
4133
- auto rep = T->getRepresentative ();
4134
- auto equivClass = rep->getOrCreateEquivalenceClass (*this );
4110
+ ResolvedType type,
4111
+ Type concrete,
4112
+ const RequirementSource *source) {
4113
+ auto equivClass = type.getEquivalenceClass (*this );
4135
4114
4136
4115
// Record the concrete type and its source.
4137
4116
equivClass->concreteTypeConstraints .push_back (
4138
- ConcreteConstraint{T, Concrete, Source });
4117
+ ConcreteConstraint{type. getUnresolvedType (), concrete, source });
4139
4118
equivClass->modified (*this );
4140
4119
++NumConcreteTypeConstraints;
4141
4120
4142
4121
// If we've already been bound to a type, match that type.
4143
4122
if (equivClass->concreteType ) {
4144
- return addSameTypeRequirement (equivClass->concreteType , Concrete, Source ,
4123
+ return addSameTypeRequirement (equivClass->concreteType , concrete, source ,
4145
4124
UnresolvedHandlingKind::GenerateConstraints,
4146
4125
SameTypeConflictCheckedLater ());
4147
4126
4148
4127
}
4149
4128
4150
4129
// Record the requirement.
4151
- equivClass->concreteType = Concrete ;
4130
+ equivClass->concreteType = concrete ;
4152
4131
4153
4132
// Make sure the concrete type fulfills the conformance requirements of
4154
4133
// this equivalence class.
4155
4134
for (const auto &conforms : equivClass->conformsTo ) {
4156
- if (!resolveConcreteConformance (rep , conforms.first ))
4135
+ if (!resolveConcreteConformance (type , conforms.first ))
4157
4136
return ConstraintResult::Conflicting;
4158
4137
}
4159
4138
4160
4139
// Eagerly resolve any existing nested types to their concrete forms (others
4161
4140
// will be "concretized" as they are constructed, in getNestedType).
4162
- for (auto equivT : rep-> getEquivalenceClassMembers () ) {
4141
+ for (auto equivT : equivClass-> members ) {
4163
4142
for (auto nested : equivT->getNestedTypes ()) {
4164
4143
concretizeNestedTypeFromConcreteParent (equivT, nested.second .front (),
4165
4144
*this );
@@ -4252,35 +4231,39 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirement(
4252
4231
}
4253
4232
4254
4233
ConstraintResult GenericSignatureBuilder::addSameTypeRequirementDirect (
4255
- ResolvedType paOrT1 , ResolvedType paOrT2 ,
4234
+ ResolvedType type1 , ResolvedType type2 ,
4256
4235
FloatingRequirementSource source,
4257
4236
llvm::function_ref<void (Type, Type)> diagnoseMismatch) {
4258
- // FIXME: Realizes potential archetypes far too early.
4259
- auto t1 = paOrT1.getAsConcreteType ();
4260
- auto *pa1 = t1 ? nullptr : paOrT1.realizePotentialArchetype (*this );
4261
-
4262
- auto t2 = paOrT2.getAsConcreteType ();
4263
- auto *pa2 = t2 ? nullptr : paOrT2.realizePotentialArchetype (*this );
4264
-
4265
- // If both sides of the requirement are type parameters, equate them.
4266
- if (pa1 && pa2) {
4267
- return addSameTypeRequirementBetweenArchetypes (
4268
- pa1, pa2,
4269
- source.getSource (*this ,
4270
- paOrT2.getDependentType (*this )));
4271
- // If just one side is a type parameter, map it to a concrete type.
4272
- } else if (pa1) {
4273
- return addSameTypeRequirementToConcrete (
4274
- pa1, t2,
4275
- source.getSource (*this , paOrT1.getDependentType (*this )));
4276
- } else if (pa2) {
4277
- return addSameTypeRequirementToConcrete (
4278
- pa2, t1,
4279
- source.getSource (*this , paOrT2.getDependentType (*this )));
4280
- } else {
4281
- return addSameTypeRequirementBetweenConcrete (t1, t2, source,
4237
+ auto concreteType1 = type1.getAsConcreteType ();
4238
+ auto concreteType2 = type2.getAsConcreteType ();
4239
+
4240
+ // If both sides of the requirement are concrete, equate them.
4241
+ if (concreteType1 && concreteType2) {
4242
+ return addSameTypeRequirementBetweenConcrete (concreteType1,
4243
+ concreteType2, source,
4282
4244
diagnoseMismatch);
4283
4245
}
4246
+
4247
+ // If one side is concrete, map the other side to that concrete type.
4248
+ if (concreteType1) {
4249
+ return addSameTypeRequirementToConcrete (type2, concreteType1,
4250
+ source.getSource (*this , type2.getDependentType (*this )));
4251
+ }
4252
+
4253
+ if (concreteType2) {
4254
+ return addSameTypeRequirementToConcrete (type1, concreteType2,
4255
+ source.getSource (*this , type1.getDependentType (*this )));
4256
+ }
4257
+
4258
+ // Both sides are type parameters; equate them.
4259
+ // FIXME: Realizes potential archetypes far too early.
4260
+ auto pa1 = type1.realizePotentialArchetype (*this );
4261
+ auto pa2 = type2.realizePotentialArchetype (*this );
4262
+
4263
+ return addSameTypeRequirementBetweenArchetypes (
4264
+ pa1, pa2,
4265
+ source.getSource (*this ,
4266
+ type2.getDependentType (*this )));
4284
4267
}
4285
4268
4286
4269
ConstraintResult GenericSignatureBuilder::addInheritedRequirements (
@@ -5435,7 +5418,7 @@ static bool unionSets(SmallVectorImpl<unsigned> &parents,
5435
5418
static void computeDerivedSameTypeComponents (
5436
5419
GenericSignatureBuilder &builder,
5437
5420
EquivalenceClass *equivClass,
5438
- llvm::SmallDenseMap<PotentialArchetype * , unsigned > &componentOf){
5421
+ llvm::SmallDenseMap<CanType , unsigned > &componentOf){
5439
5422
// Set up the array of "parents" in the union-find data structure.
5440
5423
llvm::SmallDenseMap<CanType, unsigned > parentIndices;
5441
5424
SmallVector<unsigned , 4 > parents;
@@ -5478,18 +5461,20 @@ static void computeDerivedSameTypeComponents(
5478
5461
5479
5462
// If this is the representative, add a component for it.
5480
5463
if (representative == index) {
5481
- componentOf[pa ] = components.size ();
5464
+ componentOf[depType ] = components.size ();
5482
5465
components.push_back (DerivedSameTypeComponent{pa, nullptr });
5483
5466
continue ;
5484
5467
}
5485
5468
5486
5469
// This is not the representative; point at the component of the
5487
5470
// representative.
5488
- auto representativePA = equivClass->members [representative];
5489
- assert (componentOf.count (representativePA) == 1 &&
5471
+ CanType representativeDepTy =
5472
+ equivClass->members [representative]->getDependentType ({ })
5473
+ ->getCanonicalType ();
5474
+ assert (componentOf.count (representativeDepTy) == 1 &&
5490
5475
" Missing representative component?" );
5491
- unsigned componentIndex = componentOf[representativePA ];
5492
- componentOf[pa ] = componentIndex;
5476
+ unsigned componentIndex = componentOf[representativeDepTy ];
5477
+ componentOf[depType ] = componentIndex;
5493
5478
5494
5479
// If this is a better anchor, record it.
5495
5480
if (compareDependentTypes (&pa, &components[componentIndex].anchor ) < 0 )
@@ -5498,13 +5483,12 @@ static void computeDerivedSameTypeComponents(
5498
5483
5499
5484
// If there is a concrete type, figure out the best concrete type anchor
5500
5485
// per component.
5486
+ auto genericParams = builder.getGenericParams ();
5501
5487
for (const auto &concrete : equivClass->concreteTypeConstraints ) {
5502
5488
// Dig out the component associated with constraint.
5503
- Type subjectType =
5504
- concrete.getSubjectDependentType (builder.getGenericParams ());
5505
- auto subjectPA = concrete.realizeSubjectPotentialArchetype (builder);
5506
- assert (componentOf.count (subjectPA) > 0 );
5507
- auto &component = components[componentOf[subjectPA]];
5489
+ Type subjectType = concrete.getSubjectDependentType (genericParams);
5490
+ assert (componentOf.count (subjectType->getCanonicalType ()) > 0 );
5491
+ auto &component = components[componentOf[subjectType->getCanonicalType ()]];
5508
5492
5509
5493
// FIXME: Skip self-derived sources. This means our attempts to "stage"
5510
5494
// construction of self-derived sources really don't work, because we
@@ -5573,16 +5557,17 @@ void IntercomponentEdge::dump() const {
5573
5557
// / nodes \c from and \c to within the given equivalence class.
5574
5558
static bool removalDisconnectsEquivalenceClass (
5575
5559
EquivalenceClass *equivClass,
5576
- llvm::SmallDenseMap<PotentialArchetype * , unsigned > &componentOf,
5560
+ llvm::SmallDenseMap<CanType , unsigned > &componentOf,
5577
5561
std::vector<IntercomponentEdge> &sameTypeEdges,
5578
5562
unsigned edgeIndex,
5579
- PotentialArchetype *from ,
5580
- PotentialArchetype *to ) {
5563
+ CanType fromDepType ,
5564
+ CanType toDepType ) {
5581
5565
// Which component are "from" and "to" in within the intercomponent edges?
5582
- assert (componentOf.count (from) > 0 );
5583
- auto fromComponentIndex = componentOf[from];
5584
- assert (componentOf.count (to) > 0 );
5585
- auto toComponentIndex = componentOf[to];
5566
+ assert (componentOf.count (fromDepType) > 0 );
5567
+ auto fromComponentIndex = componentOf[fromDepType];
5568
+
5569
+ assert (componentOf.count (toDepType) > 0 );
5570
+ auto toComponentIndex = componentOf[toDepType];
5586
5571
5587
5572
// If they're in the same component, they're always connected (due to
5588
5573
// derived edges).
@@ -5616,24 +5601,33 @@ static bool removalDisconnectsEquivalenceClass(
5616
5601
static bool isSelfDerivedNestedTypeNameMatchEdge (
5617
5602
GenericSignatureBuilder &builder,
5618
5603
EquivalenceClass *equivClass,
5619
- llvm::SmallDenseMap<PotentialArchetype * , unsigned > &componentOf,
5604
+ llvm::SmallDenseMap<CanType , unsigned > &componentOf,
5620
5605
std::vector<IntercomponentEdge> &sameTypeEdges,
5621
5606
unsigned edgeIndex) {
5622
5607
const auto &edge = sameTypeEdges[edgeIndex];
5623
- PotentialArchetype *source =
5624
- edge.constraint .realizeSubjectPotentialArchetype (builder );
5608
+ auto genericParams = builder. getGenericParams ();
5609
+ Type sourceType = edge.constraint .getSubjectDependentType (genericParams );
5625
5610
PotentialArchetype *target = edge.constraint .value ;
5626
- while (source->getParent () && target->getParent () &&
5627
- source->getResolvedAssociatedType () ==
5628
- target->getResolvedAssociatedType ()) {
5629
- source = source->getParent ();
5611
+
5612
+ DependentMemberType *sourceDepMemTy;
5613
+ while ((sourceDepMemTy = sourceType->getAs <DependentMemberType>()) &&
5614
+ target->getParent () &&
5615
+ sourceDepMemTy->getAssocType () &&
5616
+ sourceDepMemTy->getAssocType () == target->getResolvedAssociatedType ()){
5617
+ sourceType = sourceDepMemTy->getBase ();
5630
5618
target = target->getParent ();
5631
5619
5632
- if (source->isInSameEquivalenceClassAs (target) &&
5633
- source->getEquivalenceClassIfPresent () == equivClass &&
5620
+ if (target->getEquivalenceClassIfPresent () == equivClass &&
5621
+ builder.maybeResolveEquivalenceClass (
5622
+ sourceType,
5623
+ ArchetypeResolutionKind::WellFormed,
5624
+ /* wantExactPotentialArchetype=*/ false )
5625
+ .getEquivalenceClass (builder) == equivClass &&
5634
5626
!removalDisconnectsEquivalenceClass (equivClass, componentOf,
5635
5627
sameTypeEdges, edgeIndex,
5636
- source, target))
5628
+ sourceType->getCanonicalType (),
5629
+ target->getDependentType ({ })
5630
+ ->getCanonicalType ()))
5637
5631
return true ;
5638
5632
}
5639
5633
@@ -5648,7 +5642,7 @@ static bool isSelfDerivedNestedTypeNameMatchEdge(
5648
5642
static void collapseSameTypeComponentsThroughDelayedRequirements (
5649
5643
GenericSignatureBuilder &builder,
5650
5644
EquivalenceClass *equivClass,
5651
- llvm::SmallDenseMap<PotentialArchetype * , unsigned > &componentOf,
5645
+ llvm::SmallDenseMap<CanType , unsigned > &componentOf,
5652
5646
SmallVectorImpl<unsigned > &collapsedParents,
5653
5647
unsigned &remainingComponents) {
5654
5648
unsigned numCollapsedParents = collapsedParents.size ();
@@ -5660,6 +5654,10 @@ static void collapseSameTypeComponentsThroughDelayedRequirements(
5660
5654
// / Retrieve the component for a type representing a virtual component
5661
5655
auto getTypeVirtualComponent = [&](Type type) {
5662
5656
CanType canType = type->getCanonicalType ();
5657
+ auto knownActual = componentOf.find (canType);
5658
+ if (knownActual != componentOf.end ())
5659
+ return knownActual->second ;
5660
+
5663
5661
auto knownVirtual = virtualComponents.find (canType);
5664
5662
if (knownVirtual != virtualComponents.end ())
5665
5663
return knownVirtual->second ;
@@ -5671,32 +5669,18 @@ static void collapseSameTypeComponentsThroughDelayedRequirements(
5671
5669
};
5672
5670
5673
5671
// / Retrieve the component for the given potential archetype.
5672
+ auto genericParams = builder.getGenericParams ();
5674
5673
auto getPotentialArchetypeVirtualComponent = [&](PotentialArchetype *pa) {
5675
5674
if (pa->getEquivalenceClassIfPresent () == equivClass)
5676
- return componentOf[pa] ;
5675
+ return getTypeVirtualComponent (pa-> getDependentType (genericParams)) ;
5677
5676
5678
5677
// We found a potential archetype in another equivalence class. Treat it
5679
5678
// as a "virtual" component representing that potential archetype's
5680
5679
// equivalence class.
5681
- auto genericParams = builder.getGenericParams ();
5682
5680
return getTypeVirtualComponent (
5683
5681
pa->getRepresentative ()->getDependentType (genericParams));
5684
5682
};
5685
5683
5686
- // / Local function to retrieve the component with which the given type is
5687
- // / associated, for a type that we haven't tried to resolve yet.
5688
- auto getUnknownTypeVirtualComponent = [&](Type type) {
5689
- if (auto pa =
5690
- builder.maybeResolveEquivalenceClass (
5691
- type,
5692
- ArchetypeResolutionKind::AlreadyKnown,
5693
- /* wantExactPotentialArchetype=*/ true )
5694
- .getPotentialArchetypeIfKnown ())
5695
- return getPotentialArchetypeVirtualComponent (pa);
5696
-
5697
- return getTypeVirtualComponent (type);
5698
- };
5699
-
5700
5684
for (const auto &delayedReq : equivClass->delayedRequirements ) {
5701
5685
// Only consider same-type requirements.
5702
5686
if (delayedReq.kind != DelayedRequirement::SameType) continue ;
@@ -5705,13 +5689,13 @@ static void collapseSameTypeComponentsThroughDelayedRequirements(
5705
5689
if (auto lhsPA = delayedReq.lhs .dyn_cast <PotentialArchetype *>())
5706
5690
lhsComponent = getPotentialArchetypeVirtualComponent (lhsPA);
5707
5691
else
5708
- lhsComponent = getUnknownTypeVirtualComponent (delayedReq.lhs .get <Type>());
5692
+ lhsComponent = getTypeVirtualComponent (delayedReq.lhs .get <Type>());
5709
5693
5710
5694
unsigned rhsComponent;
5711
5695
if (auto rhsPA = delayedReq.rhs .dyn_cast <PotentialArchetype *>())
5712
5696
rhsComponent = getPotentialArchetypeVirtualComponent (rhsPA);
5713
5697
else
5714
- rhsComponent = getUnknownTypeVirtualComponent (delayedReq.rhs .get <Type>());
5698
+ rhsComponent = getTypeVirtualComponent (delayedReq.rhs .get <Type>());
5715
5699
5716
5700
// Collapse the sets
5717
5701
if (unionSets (collapsedParents, lhsComponent, rhsComponent,
@@ -5731,7 +5715,7 @@ static void collapseSameTypeComponentsThroughDelayedRequirements(
5731
5715
static void collapseSameTypeComponents (
5732
5716
GenericSignatureBuilder &builder,
5733
5717
EquivalenceClass *equivClass,
5734
- llvm::SmallDenseMap<PotentialArchetype * , unsigned > &componentOf,
5718
+ llvm::SmallDenseMap<CanType , unsigned > &componentOf,
5735
5719
std::vector<IntercomponentEdge> &sameTypeEdges) {
5736
5720
SmallVector<unsigned , 4 > collapsedParents;
5737
5721
for (unsigned i : indices (equivClass->derivedSameTypeComponents )) {
@@ -5851,7 +5835,7 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
5851
5835
5852
5836
// Compute the components in the subgraph of the same-type constraint graph
5853
5837
// that includes only derived constraints.
5854
- llvm::SmallDenseMap<PotentialArchetype * , unsigned > componentOf;
5838
+ llvm::SmallDenseMap<CanType , unsigned > componentOf;
5855
5839
computeDerivedSameTypeComponents (*this , equivClass, componentOf);
5856
5840
5857
5841
// Go through all of the same-type constraints, collecting all of the
@@ -5883,13 +5867,16 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
5883
5867
}
5884
5868
5885
5869
// Determine which component each of the source/destination fall into.
5886
- auto subjectPA = constraint.realizeSubjectPotentialArchetype (*this );
5887
- assert (componentOf.count (subjectPA) > 0 &&
5870
+ CanType subjectType =
5871
+ constraint.getSubjectDependentType ({ })->getCanonicalType ();
5872
+ assert (componentOf.count (subjectType) > 0 &&
5888
5873
" unknown potential archetype?" );
5889
- unsigned firstComponentIdx = componentOf[subjectPA];
5890
- assert (componentOf.count (constraint.value ) > 0 &&
5874
+ unsigned firstComponentIdx = componentOf[subjectType];
5875
+ assert (componentOf.count (
5876
+ constraint.value ->getDependentType ({ })->getCanonicalType ()) > 0 &&
5891
5877
" unknown potential archetype?" );
5892
- unsigned secondComponentIdx = componentOf[constraint.value ];
5878
+ unsigned secondComponentIdx =
5879
+ componentOf[constraint.value ->getDependentType ({ })->getCanonicalType ()];
5893
5880
5894
5881
// Separately track nested-type-name-match constraints.
5895
5882
if (constraint.source ->getRoot ()->kind ==
0 commit comments