@@ -7860,8 +7860,6 @@ void GenericSignatureBuilder::checkConcreteTypeConstraints(
7860
7860
diag::same_type_conflict,
7861
7861
diag::redundant_same_type_to_concrete,
7862
7862
diag::same_type_redundancy_here);
7863
-
7864
- equivClass->concreteType = resolvedConcreteType;
7865
7863
}
7866
7864
7867
7865
void GenericSignatureBuilder::checkSuperclassConstraints (
@@ -7898,9 +7896,6 @@ void GenericSignatureBuilder::checkSuperclassConstraints(
7898
7896
diag::redundant_superclass_constraint,
7899
7897
diag::superclass_redundancy_here);
7900
7898
7901
- // Record the resolved superclass type.
7902
- equivClass->superclass = resolvedSuperclass;
7903
-
7904
7899
// If we have a concrete type, check it.
7905
7900
// FIXME: Substitute into the concrete type.
7906
7901
if (equivClass->concreteType ) {
@@ -8097,6 +8092,8 @@ void GenericSignatureBuilder::enumerateRequirements(
8097
8092
// If this equivalence class is bound to a concrete type, equate the
8098
8093
// anchor with a concrete type.
8099
8094
if (Type concreteType = equivClass.concreteType ) {
8095
+ concreteType = getCanonicalTypeInContext (concreteType, genericParams);
8096
+
8100
8097
// If the parent of this anchor is also a concrete type, don't
8101
8098
// create a requirement.
8102
8099
if (!subjectType->is <GenericTypeParamType>() &&
@@ -8152,14 +8149,15 @@ void GenericSignatureBuilder::enumerateRequirements(
8152
8149
continue ;
8153
8150
8154
8151
// If we have a superclass, produce a superclass requirement
8155
- if (equivClass.superclass &&
8156
- !equivClass.recursiveSuperclassType &&
8157
- !equivClass.superclass ->hasError ()) {
8158
- if (hasNonRedundantRequirementSource<Type>(
8152
+ if (auto superclass = equivClass.superclass ) {
8153
+ superclass = getCanonicalTypeInContext (superclass, genericParams);
8154
+
8155
+ if (!equivClass.recursiveSuperclassType &&
8156
+ hasNonRedundantRequirementSource<Type>(
8159
8157
equivClass.superclassConstraints ,
8160
8158
RequirementKind::Superclass, *this )) {
8161
8159
recordRequirement (RequirementKind::Superclass,
8162
- subjectType, equivClass. superclass );
8160
+ subjectType, superclass);
8163
8161
}
8164
8162
}
8165
8163
@@ -8183,25 +8181,16 @@ void GenericSignatureBuilder::enumerateRequirements(
8183
8181
}
8184
8182
}
8185
8183
8186
- // Sort the protocols in canonical order.
8187
- llvm::array_pod_sort (protocols.begin (), protocols.end (),
8188
- TypeDecl::compare);
8189
-
8190
8184
// Enumerate the conformance requirements.
8191
8185
for (auto proto : protocols) {
8192
8186
recordRequirement (RequirementKind::Conformance, subjectType, proto);
8193
8187
}
8194
8188
}
8195
8189
}
8196
8190
8197
- // Sort the subject types in canonical order. This needs to be a stable sort
8198
- // so that the relative order of requirements that have the same subject type
8199
- // is preserved.
8200
- std::stable_sort (requirements.begin (), requirements.end (),
8201
- [](const Requirement &lhs, const Requirement &rhs) {
8202
- return compareDependentTypes (lhs.getFirstType (),
8203
- rhs.getFirstType ()) < 0 ;
8204
- });
8191
+ // Sort the requirements in canonical order.
8192
+ llvm::array_pod_sort (requirements.begin (), requirements.end (),
8193
+ compareRequirements);
8205
8194
}
8206
8195
8207
8196
void GenericSignatureBuilder::dump () {
@@ -8377,19 +8366,97 @@ static Requirement stripBoundDependentMemberTypes(Requirement req) {
8377
8366
llvm_unreachable (" Bad requirement kind" );
8378
8367
}
8379
8368
8369
+ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequirements (
8370
+ bool allowConcreteGenericParams,
8371
+ bool buildingRequirementSignature) && {
8372
+ NumSignaturesRebuiltWithoutRedundantRequirements++;
8373
+
8374
+ GenericSignatureBuilder newBuilder (Context);
8375
+
8376
+ for (auto param : getGenericParams ())
8377
+ newBuilder.addGenericParameter (param);
8378
+
8379
+ auto newSource = FloatingRequirementSource::forAbstract ();
8380
+
8381
+ for (const auto &req : Impl->ExplicitRequirements ) {
8382
+ assert (req.getKind () != RequirementKind::SameType &&
8383
+ " Should not see same-type requirement here" );
8384
+
8385
+ if (isRedundantExplicitRequirement (req))
8386
+ continue ;
8387
+
8388
+ auto subjectType = req.getSource ()->getStoredType ();
8389
+ subjectType = stripBoundDependentMemberTypes (subjectType);
8390
+ subjectType =
8391
+ resolveDependentMemberTypes (*this , subjectType,
8392
+ ArchetypeResolutionKind::WellFormed);
8393
+
8394
+ if (auto optReq = createRequirement (req.getKind (), subjectType, req.getRHS (),
8395
+ getGenericParams ())) {
8396
+ auto newReq = stripBoundDependentMemberTypes (*optReq);
8397
+ newBuilder.addRequirement (newReq, newSource, nullptr );
8398
+ }
8399
+ }
8400
+
8401
+ for (const auto &req : Impl->ExplicitSameTypeRequirements ) {
8402
+ auto resolveType = [this ](Type t) -> Type {
8403
+ t = stripBoundDependentMemberTypes (t);
8404
+ if (t->is <GenericTypeParamType>()) {
8405
+ return t;
8406
+ } else if (auto *depMemTy = t->getAs <DependentMemberType>()) {
8407
+ auto resolvedBaseTy =
8408
+ resolveDependentMemberTypes (*this , depMemTy->getBase (),
8409
+ ArchetypeResolutionKind::WellFormed);
8410
+
8411
+
8412
+ if (resolvedBaseTy->isTypeParameter ()) {
8413
+ return DependentMemberType::get (resolvedBaseTy, depMemTy->getName ());
8414
+ } else {
8415
+ return resolveDependentMemberTypes (*this , t,
8416
+ ArchetypeResolutionKind::WellFormed);
8417
+ }
8418
+ } else {
8419
+ return t;
8420
+ }
8421
+ };
8422
+
8423
+ auto subjectType = resolveType (req.getFirstType ());
8424
+ auto constraintType = resolveType (req.getSecondType ());
8425
+
8426
+ auto newReq = stripBoundDependentMemberTypes (
8427
+ Requirement (RequirementKind::SameType,
8428
+ subjectType, constraintType));
8429
+
8430
+ newBuilder.addRequirement (newReq, newSource, nullptr );
8431
+ }
8432
+
8433
+ // Wipe out the internal state of the old builder, since we don't need it anymore.
8434
+ Impl.reset ();
8435
+
8436
+ // Build a new signature using the new builder.
8437
+ return std::move (newBuilder).computeGenericSignature (
8438
+ allowConcreteGenericParams,
8439
+ buildingRequirementSignature,
8440
+ /* rebuildingWithoutRedundantConformances=*/ true );
8441
+ }
8442
+
8380
8443
GenericSignature GenericSignatureBuilder::computeGenericSignature (
8381
8444
bool allowConcreteGenericParams,
8382
8445
bool buildingRequirementSignature,
8383
8446
bool rebuildingWithoutRedundantConformances) && {
8384
8447
// Finalize the builder, producing any necessary diagnostics.
8385
8448
finalize (getGenericParams (), allowConcreteGenericParams);
8386
8449
8387
- // Collect the requirements placed on the generic parameter types.
8388
- SmallVector<Requirement, 4 > requirements;
8389
- enumerateRequirements ( getGenericParams (), requirements );
8450
+ if (rebuildingWithoutRedundantConformances) {
8451
+ assert (!buildingRequirementSignature &&
8452
+ " Rebuilding a requirement signature? " );
8390
8453
8391
- // Form the generic signature.
8392
- auto sig = GenericSignature::get (getGenericParams (), requirements);
8454
+ assert (!Impl->HadAnyError &&
8455
+ " Rebuilt signature had errors" );
8456
+
8457
+ assert (!hasExplicitConformancesImpliedByConcrete () &&
8458
+ " Rebuilt signature still had redundant conformance requirements" );
8459
+ }
8393
8460
8394
8461
// If any of our explicit conformance requirements were implied by
8395
8462
// superclass or concrete same-type requirements, we have to build the
@@ -8400,34 +8467,22 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
8400
8467
// we might end up emitting duplicate diagnostics.
8401
8468
//
8402
8469
// Also, don't do this when building a requirement signature.
8403
- if (!buildingRequirementSignature &&
8470
+ if (!rebuildingWithoutRedundantConformances &&
8471
+ !buildingRequirementSignature &&
8404
8472
!Impl->HadAnyError &&
8405
8473
hasExplicitConformancesImpliedByConcrete ()) {
8406
- NumSignaturesRebuiltWithoutRedundantRequirements++;
8407
-
8408
- if (rebuildingWithoutRedundantConformances) {
8409
- llvm::errs () << " Rebuilt signature still has "
8410
- << " redundant conformance requirements: " ;
8411
- llvm::errs () << sig << " \n " ;
8412
- abort ();
8413
- }
8414
-
8415
- GenericSignatureBuilder newBuilder (Context);
8416
-
8417
- for (auto param : sig->getGenericParams ())
8418
- newBuilder.addGenericParameter (param);
8419
-
8420
- for (auto &req : sig->getRequirements ()) {
8421
- newBuilder.addRequirement (stripBoundDependentMemberTypes (req),
8422
- FloatingRequirementSource::forAbstract (), nullptr );
8423
- }
8424
-
8425
- return std::move (newBuilder).computeGenericSignature (
8474
+ return std::move (*this ).rebuildSignatureWithoutRedundantRequirements (
8426
8475
allowConcreteGenericParams,
8427
- buildingRequirementSignature,
8428
- /* rebuildingWithoutRedundantConformances=*/ true );
8476
+ buildingRequirementSignature);
8429
8477
}
8430
8478
8479
+ // Collect the requirements placed on the generic parameter types.
8480
+ SmallVector<Requirement, 4 > requirements;
8481
+ enumerateRequirements (getGenericParams (), requirements);
8482
+
8483
+ // Form the generic signature.
8484
+ auto sig = GenericSignature::get (getGenericParams (), requirements);
8485
+
8431
8486
#ifndef NDEBUG
8432
8487
if (!Impl->HadAnyError ) {
8433
8488
checkGenericSignature (sig.getCanonicalSignature (), *this );
@@ -8537,9 +8592,6 @@ void GenericSignatureBuilder::verifyGenericSignature(ASTContext &context,
8537
8592
context.Diags .diagnose (SourceLoc (), diag::generic_signature_not_minimal,
8538
8593
reqString, sig->getAsString ());
8539
8594
}
8540
-
8541
- // Canonicalize the signature to check that it is canonical.
8542
- (void )newSig.getCanonicalSignature ();
8543
8595
}
8544
8596
}
8545
8597
0 commit comments