@@ -8366,19 +8366,97 @@ static Requirement stripBoundDependentMemberTypes(Requirement req) {
8366
8366
llvm_unreachable (" Bad requirement kind" );
8367
8367
}
8368
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
+
8369
8443
GenericSignature GenericSignatureBuilder::computeGenericSignature (
8370
8444
bool allowConcreteGenericParams,
8371
8445
bool buildingRequirementSignature,
8372
8446
bool rebuildingWithoutRedundantConformances) && {
8373
8447
// Finalize the builder, producing any necessary diagnostics.
8374
8448
finalize (getGenericParams (), allowConcreteGenericParams);
8375
8449
8376
- // Collect the requirements placed on the generic parameter types.
8377
- SmallVector<Requirement, 4 > requirements;
8378
- enumerateRequirements ( getGenericParams (), requirements );
8450
+ if (rebuildingWithoutRedundantConformances) {
8451
+ assert (!buildingRequirementSignature &&
8452
+ " Rebuilding a requirement signature? " );
8379
8453
8380
- // Form the generic signature.
8381
- 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
+ }
8382
8460
8383
8461
// If any of our explicit conformance requirements were implied by
8384
8462
// superclass or concrete same-type requirements, we have to build the
@@ -8389,34 +8467,22 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
8389
8467
// we might end up emitting duplicate diagnostics.
8390
8468
//
8391
8469
// Also, don't do this when building a requirement signature.
8392
- if (!buildingRequirementSignature &&
8470
+ if (!rebuildingWithoutRedundantConformances &&
8471
+ !buildingRequirementSignature &&
8393
8472
!Impl->HadAnyError &&
8394
8473
hasExplicitConformancesImpliedByConcrete ()) {
8395
- NumSignaturesRebuiltWithoutRedundantRequirements++;
8396
-
8397
- if (rebuildingWithoutRedundantConformances) {
8398
- llvm::errs () << " Rebuilt signature still has "
8399
- << " redundant conformance requirements: " ;
8400
- llvm::errs () << sig << " \n " ;
8401
- abort ();
8402
- }
8403
-
8404
- GenericSignatureBuilder newBuilder (Context);
8405
-
8406
- for (auto param : sig->getGenericParams ())
8407
- newBuilder.addGenericParameter (param);
8408
-
8409
- for (auto &req : sig->getRequirements ()) {
8410
- newBuilder.addRequirement (stripBoundDependentMemberTypes (req),
8411
- FloatingRequirementSource::forAbstract (), nullptr );
8412
- }
8413
-
8414
- return std::move (newBuilder).computeGenericSignature (
8474
+ return std::move (*this ).rebuildSignatureWithoutRedundantRequirements (
8415
8475
allowConcreteGenericParams,
8416
- buildingRequirementSignature,
8417
- /* rebuildingWithoutRedundantConformances=*/ true );
8476
+ buildingRequirementSignature);
8418
8477
}
8419
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
+
8420
8486
#ifndef NDEBUG
8421
8487
if (!Impl->HadAnyError ) {
8422
8488
checkGenericSignature (sig.getCanonicalSignature (), *this );
@@ -8526,9 +8592,6 @@ void GenericSignatureBuilder::verifyGenericSignature(ASTContext &context,
8526
8592
context.Diags .diagnose (SourceLoc (), diag::generic_signature_not_minimal,
8527
8593
reqString, sig->getAsString ());
8528
8594
}
8529
-
8530
- // Canonicalize the signature to check that it is canonical.
8531
- (void )newSig.getCanonicalSignature ();
8532
8595
}
8533
8596
}
8534
8597
0 commit comments