@@ -363,6 +363,89 @@ bool ArchetypeBuilder::PotentialArchetype::hasConcreteTypeInPath() const {
363
363
return false ;
364
364
}
365
365
366
+ // / Canonical ordering for dependent types in generic signatures.
367
+ static int compareDependentTypes (
368
+ ArchetypeBuilder::PotentialArchetype * const * pa,
369
+ ArchetypeBuilder::PotentialArchetype * const * pb) {
370
+ auto a = *pa, b = *pb;
371
+
372
+ // Fast-path check for equality.
373
+ if (a == b)
374
+ return 0 ;
375
+
376
+ // Ordering is as follows:
377
+ // - Generic params
378
+ if (a->isGenericParam () && b->isGenericParam ())
379
+ return a->getGenericParamKey () < b->getGenericParamKey () ? -1 : +1 ;
380
+
381
+ // A generic parameter is always ordered before a nested type.
382
+ if (a->isGenericParam () != b->isGenericParam ())
383
+ return a->isGenericParam () ? -1 : +1 ;
384
+
385
+ // - Dependent members
386
+ auto ppa = a->getParent ();
387
+ auto ppb = b->getParent ();
388
+
389
+ // - by base, so t_0_n.`P.T` < t_1_m.`P.T`
390
+ if (int compareBases = compareDependentTypes (&ppa, &ppb))
391
+ return compareBases;
392
+
393
+ // - by name, so t_n_m.`P.T` < t_n_m.`P.U`
394
+ if (int compareNames = a->getName ().str ().compare (b->getName ().str ()))
395
+ return compareNames;
396
+
397
+ if (auto *aa = a->getResolvedAssociatedType ()) {
398
+ if (auto *ab = b->getResolvedAssociatedType ()) {
399
+ // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
400
+ auto protoa = aa->getProtocol ();
401
+ auto protob = ab->getProtocol ();
402
+ if (int compareProtocols
403
+ = ProtocolType::compareProtocols (&protoa, &protob))
404
+ return compareProtocols;
405
+ } else {
406
+ // A resolved archetype is always ordered before an unresolved one.
407
+ return -1 ;
408
+ }
409
+ }
410
+
411
+ // A resolved archetype is always ordered before an unresolved one.
412
+ if (b->getResolvedAssociatedType ())
413
+ return +1 ;
414
+
415
+ // Make sure typealiases are properly ordered, to avoid crashers.
416
+ // FIXME: Ideally we would eliminate typealiases earlier.
417
+ if (auto *aa = a->getTypeAliasDecl ()) {
418
+ if (auto *ab = b->getTypeAliasDecl ()) {
419
+ // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
420
+ auto protoa = aa->getDeclContext ()->getAsProtocolOrProtocolExtensionContext ();
421
+ auto protob = ab->getDeclContext ()->getAsProtocolOrProtocolExtensionContext ();
422
+ if (int compareProtocols
423
+ = ProtocolType::compareProtocols (&protoa, &protob))
424
+ return compareProtocols;
425
+ }
426
+
427
+ // A resolved archetype is always ordered before an unresolved one.
428
+ return -1 ;
429
+ }
430
+
431
+ // A resolved archetype is always ordered before an unresolved one.
432
+ if (b->getTypeAliasDecl ())
433
+ return +1 ;
434
+
435
+ // Along the error path where one or both of the potential archetypes was
436
+ // renamed due to typo correction,
437
+ if (a->wasRenamed () || b->wasRenamed ()) {
438
+ if (a->wasRenamed () != b->wasRenamed ())
439
+ return a->wasRenamed () ? +1 : -1 ;
440
+
441
+ if (int compareNames = a->getOriginalName ().str ().compare (
442
+ b->getOriginalName ().str ()))
443
+ return compareNames;
444
+ }
445
+
446
+ llvm_unreachable (" potential archetype total order failure" );
447
+ }
448
+
366
449
bool ArchetypeBuilder::PotentialArchetype::isBetterArchetypeAnchor (
367
450
PotentialArchetype *other) const {
368
451
auto concrete = hasConcreteTypeInPath ();
@@ -1065,88 +1148,6 @@ bool ArchetypeBuilder::addSuperclassRequirement(PotentialArchetype *T,
1065
1148
return false ;
1066
1149
}
1067
1150
1068
- // / Canonical ordering for dependent types in generic signatures.
1069
- static int compareDependentTypes (ArchetypeBuilder::PotentialArchetype * const * pa,
1070
- ArchetypeBuilder::PotentialArchetype * const * pb) {
1071
- auto a = *pa, b = *pb;
1072
-
1073
- // Fast-path check for equality.
1074
- if (a == b)
1075
- return 0 ;
1076
-
1077
- // Ordering is as follows:
1078
- // - Generic params
1079
- if (a->isGenericParam () && b->isGenericParam ())
1080
- return a->getGenericParamKey () < b->getGenericParamKey () ? -1 : +1 ;
1081
-
1082
- // A generic parameter is always ordered before a nested type.
1083
- if (a->isGenericParam () != b->isGenericParam ())
1084
- return a->isGenericParam () ? -1 : +1 ;
1085
-
1086
- // - Dependent members
1087
- auto ppa = a->getParent ();
1088
- auto ppb = b->getParent ();
1089
-
1090
- // - by base, so t_0_n.`P.T` < t_1_m.`P.T`
1091
- if (int compareBases = compareDependentTypes (&ppa, &ppb))
1092
- return compareBases;
1093
-
1094
- // - by name, so t_n_m.`P.T` < t_n_m.`P.U`
1095
- if (int compareNames = a->getName ().str ().compare (b->getName ().str ()))
1096
- return compareNames;
1097
-
1098
- if (auto *aa = a->getResolvedAssociatedType ()) {
1099
- if (auto *ab = b->getResolvedAssociatedType ()) {
1100
- // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
1101
- auto protoa = aa->getProtocol ();
1102
- auto protob = ab->getProtocol ();
1103
- if (int compareProtocols
1104
- = ProtocolType::compareProtocols (&protoa, &protob))
1105
- return compareProtocols;
1106
- } else {
1107
- // A resolved archetype is always ordered before an unresolved one.
1108
- return -1 ;
1109
- }
1110
- }
1111
-
1112
- // A resolved archetype is always ordered before an unresolved one.
1113
- if (b->getResolvedAssociatedType ())
1114
- return +1 ;
1115
-
1116
- // Make sure typealiases are properly ordered, to avoid crashers.
1117
- // FIXME: Ideally we would eliminate typealiases earlier.
1118
- if (auto *aa = a->getTypeAliasDecl ()) {
1119
- if (auto *ab = b->getTypeAliasDecl ()) {
1120
- // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
1121
- auto protoa = aa->getDeclContext ()->getAsProtocolOrProtocolExtensionContext ();
1122
- auto protob = ab->getDeclContext ()->getAsProtocolOrProtocolExtensionContext ();
1123
- if (int compareProtocols
1124
- = ProtocolType::compareProtocols (&protoa, &protob))
1125
- return compareProtocols;
1126
- }
1127
-
1128
- // A resolved archetype is always ordered before an unresolved one.
1129
- return -1 ;
1130
- }
1131
-
1132
- // A resolved archetype is always ordered before an unresolved one.
1133
- if (b->getTypeAliasDecl ())
1134
- return +1 ;
1135
-
1136
- // Along the error path where one or both of the potential archetypes was
1137
- // renamed due to typo correction,
1138
- if (a->wasRenamed () || b->wasRenamed ()) {
1139
- if (a->wasRenamed () != b->wasRenamed ())
1140
- return a->wasRenamed () ? +1 : -1 ;
1141
-
1142
- if (int compareNames = a->getOriginalName ().str ().compare (
1143
- b->getOriginalName ().str ()))
1144
- return compareNames;
1145
- }
1146
-
1147
- llvm_unreachable (" potential archetype total order failure" );
1148
- }
1149
-
1150
1151
bool ArchetypeBuilder::addSameTypeRequirementBetweenArchetypes (
1151
1152
PotentialArchetype *T1,
1152
1153
PotentialArchetype *T2,
@@ -1161,23 +1162,9 @@ bool ArchetypeBuilder::addSameTypeRequirementBetweenArchetypes(
1161
1162
return false ;
1162
1163
1163
1164
// Decide which potential archetype is to be considered the representative.
1164
- // We necessarily prefer potential archetypes rooted at parameters that come
1165
- // from outer generic parameter lists, since those generic parameters will
1166
- // have archetypes bound in the outer context.
1167
- //
1168
- // FIXME: The above comment is mostly obsolete, so why can't we just use
1169
- // compareDependentTypes() here?
1170
- auto T1Param = T1->getRootGenericParamKey ();
1171
- auto T2Param = T2->getRootGenericParamKey ();
1172
- unsigned T1Depth = T1->getNestingDepth ();
1173
- unsigned T2Depth = T2->getNestingDepth ();
1174
- auto T1Key = std::make_tuple (T1->wasRenamed (), +T1Param.Depth ,
1175
- +T1Param.Index , T1Depth);
1176
- auto T2Key = std::make_tuple (T2->wasRenamed (), +T2Param.Depth ,
1177
- +T2Param.Index , T2Depth);
1178
- if (T2Key < T1Key ||
1179
- (T2Key == T1Key &&
1180
- compareDependentTypes (&T2, &T1) < 0 ))
1165
+ // It doesn't specifically matter which we use, but it's a minor optimization
1166
+ // to prefer the canonical type.
1167
+ if (compareDependentTypes (&T2, &T1) < 0 )
1181
1168
std::swap (T1, T2);
1182
1169
1183
1170
// Merge any concrete constraints.
0 commit comments