@@ -803,7 +803,7 @@ static Type formProtocolRelativeType(ProtocolDecl *proto,
803
803
PotentialArchetype *basePA,
804
804
PotentialArchetype *pa) {
805
805
// Basis case: we've hit the base potential archetype.
806
- if (basePA-> isInSameEquivalenceClassAs (pa) )
806
+ if (basePA == pa )
807
807
return proto->getSelfInterfaceType ();
808
808
809
809
// Recursive case: form a dependent member type.
@@ -846,6 +846,9 @@ const RequirementSource *FloatingRequirementSource::getSource(
846
846
protocolReq.protocol , protocolReq.inferred ,
847
847
protocolReq.written );
848
848
}
849
+
850
+ case NestedTypeNameMatch:
851
+ return RequirementSource::forNestedTypeNameMatch (pa);
849
852
}
850
853
851
854
llvm_unreachable (" Unhandled FloatingPointRequirementSourceKind in switch." );
@@ -878,6 +881,7 @@ bool FloatingRequirementSource::isExplicit() const {
878
881
return true ;
879
882
880
883
case Inferred:
884
+ case NestedTypeNameMatch:
881
885
return false ;
882
886
883
887
case AbstractProtocol:
@@ -926,6 +930,7 @@ FloatingRequirementSource FloatingRequirementSource::asInferred(
926
930
927
931
case Inferred:
928
932
case Resolved:
933
+ case NestedTypeNameMatch:
929
934
return *this ;
930
935
931
936
case AbstractProtocol:
@@ -941,7 +946,7 @@ bool FloatingRequirementSource::isRecursive(
941
946
llvm::SmallSet<std::pair<CanType, ProtocolDecl *>, 4 > visitedAssocReqs;
942
947
for (auto storedSource = storage.dyn_cast <const RequirementSource *>();
943
948
storedSource; storedSource = storedSource->parent ) {
944
- if (storedSource->kind != RequirementSource::ProtocolRequirement )
949
+ if (! storedSource->isProtocolRequirement () )
945
950
continue ;
946
951
947
952
if (!visitedAssocReqs.insert (
@@ -950,6 +955,22 @@ bool FloatingRequirementSource::isRecursive(
950
955
return true ;
951
956
}
952
957
958
+ // For a nested type match, look for another type with that name.
959
+ // FIXME: Actually, look for 5 of them. This is totally bogus.
960
+ if (kind == NestedTypeNameMatch) {
961
+ unsigned grossCount = 0 ;
962
+ auto pa = storage.dyn_cast <const RequirementSource *>()
963
+ ->getAffectedPotentialArchetype ();
964
+ while (auto parent = pa->getParent ()) {
965
+ if (pa->getNestedName () == nestedName) {
966
+ if (++grossCount > 4 ) return true ;
967
+ }
968
+
969
+
970
+ pa = parent;
971
+ }
972
+ }
973
+
953
974
return false ;
954
975
}
955
976
@@ -1083,6 +1104,50 @@ bool EquivalenceClass::isConformanceSatisfiedBySuperclass(
1083
1104
return false ;
1084
1105
}
1085
1106
1107
+ void EquivalenceClass::dump (llvm::raw_ostream &out) const {
1108
+ out << " Equivalence class represented by "
1109
+ << members.front ()->getRepresentative ()->getDebugName () << " :\n " ;
1110
+ out << " Members: " ;
1111
+ interleave (members, [&](PotentialArchetype *pa) {
1112
+ out << pa->getDebugName ();
1113
+ }, [&]() {
1114
+ out << " , " ;
1115
+ });
1116
+ out << " \n Conformances:" ;
1117
+ interleave (conformsTo,
1118
+ [&](const std::pair<
1119
+ ProtocolDecl *,
1120
+ std::vector<Constraint<ProtocolDecl *>>> &entry) {
1121
+ out << entry.first ->getNameStr ();
1122
+ },
1123
+ [&] { out << " , " ; });
1124
+ out << " \n Same-type constraints:" ;
1125
+ for (const auto &entry : sameTypeConstraints) {
1126
+ out << " \n " << entry.first ->getDebugName () << " == " ;
1127
+ interleave (entry.second ,
1128
+ [&](const Constraint<PotentialArchetype *> &constraint) {
1129
+ out << constraint.value ->getDebugName ();
1130
+
1131
+ if (constraint.source ->isDerivedRequirement ())
1132
+ out << " [derived]" ;
1133
+ }, [&] {
1134
+ out << " , " ;
1135
+ });
1136
+ }
1137
+ if (concreteType)
1138
+ out << " \n Concrete type: " << concreteType.getString ();
1139
+ if (superclass)
1140
+ out << " \n Superclass: " << superclass.getString ();
1141
+ if (layout)
1142
+ out << " \n Layout: " << layout.getString ();
1143
+
1144
+ out << " \n " ;
1145
+ }
1146
+
1147
+ void EquivalenceClass::dump () const {
1148
+ dump (llvm::errs ());
1149
+ }
1150
+
1086
1151
ConstraintResult GenericSignatureBuilder::handleUnresolvedRequirement (
1087
1152
RequirementKind kind,
1088
1153
UnresolvedType lhs,
@@ -1398,7 +1463,13 @@ PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
1398
1463
if (auto parent = getParent ()) {
1399
1464
// For a nested type, retrieve the parent archetype anchor first.
1400
1465
auto parentAnchor = parent->getArchetypeAnchor (builder);
1401
- anchor = parentAnchor->getNestedArchetypeAnchor (getNestedName (), builder);
1466
+ anchor = parentAnchor->getNestedArchetypeAnchor (
1467
+ getNestedName (), builder,
1468
+ NestedTypeUpdate::ResolveExisting);
1469
+
1470
+ // FIXME: Hack for cases where we couldn't resolve the nested type.
1471
+ if (!anchor)
1472
+ anchor = rep;
1402
1473
} else {
1403
1474
anchor = rep;
1404
1475
}
@@ -2791,14 +2862,16 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
2791
2862
}
2792
2863
2793
2864
// Recursively merge the associated types of T2 into T1.
2865
+ auto dependentT1 = T1->getDependentType ({ }, /* allowUnresolved=*/ true );
2794
2866
for (auto equivT2 : equivClass2Members) {
2795
2867
for (auto T2Nested : equivT2->NestedTypes ) {
2796
- auto T1Nested = T1->getNestedType (T2Nested.first , *this );
2797
- if (isErrorResult (addSameTypeRequirement (
2798
- T1Nested, T2Nested.second .front (),
2799
- RequirementSource::forNestedTypeNameMatch (T1Nested),
2800
- UnresolvedHandlingKind::GenerateConstraints,
2801
- DiagnoseSameTypeConflict{Diags, Source, T1Nested})))
2868
+ Type nestedT1 = DependentMemberType::get (dependentT1, T2Nested.first );
2869
+ if (isErrorResult (
2870
+ addSameTypeRequirement (
2871
+ nestedT1, T2Nested.second .front (),
2872
+ FloatingRequirementSource::forNestedTypeNameMatch (
2873
+ Source, T2Nested.first ),
2874
+ UnresolvedHandlingKind::GenerateConstraints)))
2802
2875
return ConstraintResult::Conflicting;
2803
2876
}
2804
2877
}
@@ -3809,8 +3882,12 @@ Constraint<T> GenericSignatureBuilder::checkConstraintList(
3809
3882
3810
3883
namespace {
3811
3884
// / Remove self-derived sources from the given vector of constraints.
3885
+ // /
3886
+ // / \returns true if any derived-via-concrete constraints were found.
3812
3887
template <typename T>
3813
- void removeSelfDerived (std::vector<Constraint<T>> &constraints) {
3888
+ bool removeSelfDerived (std::vector<Constraint<T>> &constraints,
3889
+ bool dropDerivedViaConcrete = true ) {
3890
+ bool anyDerivedViaConcrete = false ;
3814
3891
// Remove self-derived constraints.
3815
3892
Optional<Constraint<T>> remainingConcrete;
3816
3893
constraints.erase (
@@ -3824,6 +3901,11 @@ namespace {
3824
3901
if (!derivedViaConcrete)
3825
3902
return false ;
3826
3903
3904
+ anyDerivedViaConcrete = true ;
3905
+
3906
+ if (!dropDerivedViaConcrete)
3907
+ return false ;
3908
+
3827
3909
// Drop derived-via-concrete requirements.
3828
3910
if (!remainingConcrete)
3829
3911
remainingConcrete = constraint;
@@ -3836,6 +3918,7 @@ namespace {
3836
3918
constraints.push_back (*remainingConcrete);
3837
3919
3838
3920
assert (!constraints.empty () && " All constraints were self-derived!" );
3921
+ return anyDerivedViaConcrete;
3839
3922
}
3840
3923
}
3841
3924
@@ -4191,11 +4274,13 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
4191
4274
equivClass = pa->getEquivalenceClassIfPresent ();
4192
4275
assert (equivClass && " Equivalence class disappeared?" );
4193
4276
4277
+ bool anyDerivedViaConcrete = false ;
4194
4278
for (auto &entry : equivClass->sameTypeConstraints ) {
4195
4279
auto &constraints = entry.second ;
4196
4280
4197
4281
// Remove self-derived constraints.
4198
- removeSelfDerived (constraints);
4282
+ if (removeSelfDerived (constraints, /* dropDerivedViaConcrete=*/ false ))
4283
+ anyDerivedViaConcrete = true ;
4199
4284
4200
4285
// Sort the constraints, so we get a deterministic ordering of diagnostics.
4201
4286
llvm::array_pod_sort (constraints.begin (), constraints.end ());
@@ -4272,6 +4357,18 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
4272
4357
}
4273
4358
}
4274
4359
4360
+ // If there were any derived-via-concrete constraints, drop them now before
4361
+ // we emit other diagnostics.
4362
+ if (anyDerivedViaConcrete) {
4363
+ for (auto &entry : equivClass->sameTypeConstraints ) {
4364
+ auto &constraints = entry.second ;
4365
+
4366
+ // Remove derived-via-concrete constraints.
4367
+ (void )removeSelfDerived (constraints);
4368
+ anyDerivedViaConcrete = true ;
4369
+ }
4370
+ }
4371
+
4275
4372
// Walk through each of the components, checking the intracomponent edges.
4276
4373
// This will diagnose any explicitly-specified requirements within a
4277
4374
// component, all of which are redundant.
0 commit comments