@@ -1413,6 +1413,8 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
1413
1413
1414
1414
// Make sure the concrete type fulfills the superclass requirement
1415
1415
// of the archetype.
1416
+ RequirementSource redundantSource (RequirementSource::Redundant,
1417
+ Source.getLoc ());
1416
1418
if (T->Superclass ) {
1417
1419
if (!T->Superclass ->isExactSuperclassOf (Concrete, getLazyResolver ())) {
1418
1420
Diags.diagnose (Source.getLoc (), diag::type_does_not_inherit,
@@ -1422,6 +1424,10 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
1422
1424
.highlight (T->SuperclassSource ->getLoc ());
1423
1425
return true ;
1424
1426
}
1427
+
1428
+ // The superclass requirement is made redundant by the concrete type
1429
+ // assignment.
1430
+ updateRequirementSource (*T->SuperclassSource , redundantSource);
1425
1431
}
1426
1432
1427
1433
// Recursively resolve the associated types to their concrete types.
@@ -1432,7 +1438,7 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
1432
1438
if (auto *concreteArchetype = Concrete->getAs <ArchetypeType>()) {
1433
1439
Type witnessType = concreteArchetype->getNestedType (nested.first );
1434
1440
addSameTypeRequirementToConcrete (nested.second .front (), witnessType,
1435
- Source );
1441
+ redundantSource );
1436
1442
} else if (assocType) {
1437
1443
assert (conformances.count (assocType->getProtocol ()) > 0
1438
1444
&& " missing conformance?" );
@@ -1449,11 +1455,11 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
1449
1455
if (auto witnessPA = resolveArchetype (witnessType)) {
1450
1456
addSameTypeRequirementBetweenArchetypes (nested.second .front (),
1451
1457
witnessPA,
1452
- Source );
1458
+ redundantSource );
1453
1459
} else {
1454
1460
addSameTypeRequirementToConcrete (nested.second .front (),
1455
1461
witnessType,
1456
- Source );
1462
+ redundantSource );
1457
1463
}
1458
1464
}
1459
1465
}
@@ -2173,17 +2179,39 @@ void ArchetypeBuilder::enumerateRequirements(llvm::function_ref<
2173
2179
RequirementSource source)> f) {
2174
2180
// Create anchors for all of the potential archetypes.
2175
2181
// FIXME: This is because we might be missing some from the equivalence
2176
- // classes.
2182
+ // classes. It is an egregious hack.
2177
2183
visitPotentialArchetypes ([&](PotentialArchetype *archetype) {
2178
- archetype->getArchetypeAnchor (*this );
2184
+ ( void ) archetype->getArchetypeAnchor (*this );
2179
2185
});
2180
2186
2181
- // Collect all archetypes, and sort them .
2187
+ // Collect all archetypes.
2182
2188
SmallVector<PotentialArchetype *, 8 > archetypes;
2183
2189
visitPotentialArchetypes ([&](PotentialArchetype *archetype) {
2184
2190
archetypes.push_back (archetype);
2185
2191
});
2186
2192
2193
+ // Remove any invalid potential archetypes or archetypes whose parents are
2194
+ // concrete; they have no requirements.
2195
+ archetypes.erase (
2196
+ std::remove_if (archetypes.begin (), archetypes.end (),
2197
+ [&](PotentialArchetype *archetype) -> bool {
2198
+ // Invalid archetypes are never representatives in well-formed or
2199
+ // corrected signature, so we don't need to visit them.
2200
+ if (archetype->isInvalid ())
2201
+ return true ;
2202
+
2203
+ // If there is a concrete type above us, there are no requirements to
2204
+ // emit.
2205
+ if (archetype->getParent () &&
2206
+ hasConcreteTypeInPath (archetype->getParent ()))
2207
+ return true ;
2208
+
2209
+ // Keep it.
2210
+ return false ;
2211
+ }),
2212
+ archetypes.end ());
2213
+
2214
+ // Sort the archetypes in canonical order.
2187
2215
llvm::array_pod_sort (archetypes.begin (), archetypes.end (),
2188
2216
compareDependentTypes);
2189
2217
@@ -2203,32 +2231,27 @@ void ArchetypeBuilder::enumerateRequirements(llvm::function_ref<
2203
2231
};
2204
2232
2205
2233
for (auto *archetype : archetypes) {
2206
- // Invalid archetypes are never representatives in well-formed or corrected
2207
- // signature, so we don't need to visit them.
2208
- if (archetype->isInvalid ())
2209
- continue ;
2210
-
2211
- // If this type is equivalent to a concrete type, emit the same-type
2212
- // constraint.
2213
- auto rep = archetype->getRepresentative ();
2214
- if (auto concreteType = rep->getConcreteType ()) {
2215
- f (RequirementKind::SameType, archetype, concreteType,
2216
- rep->getConcreteTypeSource ());
2217
- continue ;
2218
- }
2219
-
2220
2234
// Check whether this archetype is one of the anchors within its
2221
- // connected component. If so, we may need to emit an archetype anchor .
2235
+ // connected component. If so, we may need to emit a same-type constraint .
2222
2236
//
2223
2237
// FIXME: O(n) in the number of implied connected components within the
2224
2238
// equivalence class. The equivalence class should be small, but...
2239
+ auto rep = archetype->getRepresentative ();
2225
2240
auto componentAnchors = getSameTypeComponentAnchors (rep);
2226
2241
auto knownAnchor = std::find (componentAnchors.begin (),
2227
2242
componentAnchors.end (),
2228
2243
archetype);
2229
2244
std::function<void ()> deferredSameTypeRequirement;
2230
2245
2231
2246
if (knownAnchor != componentAnchors.end ()) {
2247
+ // If this equivalance class is bound to a concrete type, equate the
2248
+ // anchor with a concrete type.
2249
+ if (auto concreteType = rep->getConcreteType ()) {
2250
+ f (RequirementKind::SameType, archetype, concreteType,
2251
+ rep->getConcreteTypeSource ());
2252
+ continue ;
2253
+ }
2254
+
2232
2255
// If we're at the last anchor in the component, do nothing;
2233
2256
auto nextAnchor = knownAnchor;
2234
2257
++nextAnchor;
0 commit comments