@@ -6349,8 +6349,9 @@ void
6349
6349
GenericSignatureBuilder::finalize (TypeArrayView<GenericTypeParamType> genericParams,
6350
6350
bool allowConcreteGenericParams,
6351
6351
const ProtocolDecl *requirementSignatureSelfProto) {
6352
- // Process any delayed requirements that we can handle now.
6353
- processDelayedRequirements ();
6352
+ diagnoseProtocolRefinement (requirementSignatureSelfProto);
6353
+ diagnoseRedundantRequirements ();
6354
+ diagnoseConflictingConcreteTypeRequirements (requirementSignatureSelfProto);
6354
6355
6355
6356
{
6356
6357
// In various places below, we iterate over the list of equivalence classes
@@ -6383,11 +6384,6 @@ GenericSignatureBuilder::finalize(TypeArrayView<GenericTypeParamType> genericPar
6383
6384
}
6384
6385
}
6385
6386
6386
- computeRedundantRequirements (requirementSignatureSelfProto);
6387
- diagnoseProtocolRefinement (requirementSignatureSelfProto);
6388
- diagnoseRedundantRequirements ();
6389
- diagnoseConflictingConcreteTypeRequirements (requirementSignatureSelfProto);
6390
-
6391
6387
assert (!Impl->finalized && " Already finalized builder" );
6392
6388
#ifndef NDEBUG
6393
6389
Impl->finalized = true ;
@@ -7006,7 +7002,8 @@ void GenericSignatureBuilder::diagnoseProtocolRefinement(
7006
7002
}
7007
7003
}
7008
7004
7009
- void GenericSignatureBuilder::diagnoseRedundantRequirements () const {
7005
+ void GenericSignatureBuilder::diagnoseRedundantRequirements (
7006
+ bool onlyDiagnoseExplicitConformancesImpliedByConcrete) const {
7010
7007
for (const auto &req : Impl->ExplicitRequirements ) {
7011
7008
auto *source = req.getSource ();
7012
7009
auto loc = source->getLoc ();
@@ -7024,6 +7021,10 @@ void GenericSignatureBuilder::diagnoseRedundantRequirements() const {
7024
7021
if (found == Impl->RedundantRequirements .end ())
7025
7022
continue ;
7026
7023
7024
+ if (onlyDiagnoseExplicitConformancesImpliedByConcrete &&
7025
+ Impl->ExplicitConformancesImpliedByConcrete .count (req) == 0 )
7026
+ continue ;
7027
+
7027
7028
// Don't diagnose explicit requirements that are implied by
7028
7029
// inferred requirements.
7029
7030
if (llvm::all_of (found->second ,
@@ -8418,14 +8419,20 @@ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequir
8418
8419
requirementSignatureSource);
8419
8420
}
8420
8421
8421
- auto newSource = [&]() {
8422
+ auto getRebuiltSource = [&](const RequirementSource *source) {
8423
+ assert (!source->isDerivedRequirement ());
8424
+
8422
8425
if (auto *proto = const_cast <ProtocolDecl *>(requirementSignatureSelfProto)) {
8423
8426
return FloatingRequirementSource::viaProtocolRequirement (
8424
- requirementSignatureSource, proto, /* inferred=*/ false );
8427
+ requirementSignatureSource, proto, source->getLoc (),
8428
+ source->isInferredRequirement ());
8425
8429
}
8426
8430
8427
- return FloatingRequirementSource::forAbstract ();
8428
- }();
8431
+ if (source->isInferredRequirement ())
8432
+ return FloatingRequirementSource::forInferred (source->getLoc ());
8433
+
8434
+ return FloatingRequirementSource::forExplicit (source->getLoc ());
8435
+ };
8429
8436
8430
8437
for (const auto &req : Impl->ExplicitRequirements ) {
8431
8438
assert (req.getKind () != RequirementKind::SameType &&
@@ -8449,7 +8456,7 @@ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequir
8449
8456
!resolvedSubjectType->isTypeParameter ()) {
8450
8457
newBuilder.addRequirement (Requirement (RequirementKind::SameType,
8451
8458
subjectType, resolvedSubjectType),
8452
- newSource , nullptr );
8459
+ getRebuiltSource (req. getSource ()) , nullptr );
8453
8460
continue ;
8454
8461
}
8455
8462
@@ -8458,7 +8465,8 @@ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequir
8458
8465
if (auto optReq = createRequirement (req.getKind (), resolvedSubjectType,
8459
8466
req.getRHS (), getGenericParams ())) {
8460
8467
auto newReq = stripBoundDependentMemberTypes (*optReq);
8461
- newBuilder.addRequirement (newReq, newSource, nullptr );
8468
+ newBuilder.addRequirement (newReq, getRebuiltSource (req.getSource ()),
8469
+ nullptr );
8462
8470
}
8463
8471
}
8464
8472
@@ -8491,7 +8499,8 @@ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequir
8491
8499
Requirement (RequirementKind::SameType,
8492
8500
subjectType, constraintType));
8493
8501
8494
- newBuilder.addRequirement (newReq, newSource, nullptr );
8502
+ newBuilder.addRequirement (newReq, getRebuiltSource (req.getSource ()),
8503
+ nullptr );
8495
8504
}
8496
8505
8497
8506
// Wipe out the internal state of the old builder, since we don't need it anymore.
@@ -8506,22 +8515,10 @@ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequir
8506
8515
GenericSignature GenericSignatureBuilder::computeGenericSignature (
8507
8516
bool allowConcreteGenericParams,
8508
8517
const ProtocolDecl *requirementSignatureSelfProto) && {
8509
- // Finalize the builder, producing any necessary diagnostics.
8510
- finalize (getGenericParams (),
8511
- allowConcreteGenericParams,
8512
- requirementSignatureSelfProto);
8513
-
8514
- if (Impl->RebuildingWithoutRedundantConformances ) {
8515
- assert (!Impl->HadAnyError &&
8516
- " Rebuilt signature had errors" );
8518
+ // Process any delayed requirements that we can handle now.
8519
+ processDelayedRequirements ();
8517
8520
8518
- #ifndef NDEBUG
8519
- for (const auto &req : Impl->ExplicitConformancesImpliedByConcrete ) {
8520
- assert (!isRedundantExplicitRequirement (req) &&
8521
- " Rebuilt signature still had redundant conformance requirements" );
8522
- }
8523
- #endif
8524
- }
8521
+ computeRedundantRequirements (requirementSignatureSelfProto);
8525
8522
8526
8523
// If any of our explicit conformance requirements were implied by
8527
8524
// superclass or concrete same-type requirements, we have to build the
@@ -8535,12 +8532,30 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
8535
8532
if (!Impl->RebuildingWithoutRedundantConformances &&
8536
8533
!Impl->HadAnyError &&
8537
8534
!Impl->ExplicitConformancesImpliedByConcrete .empty ()) {
8535
+ diagnoseRedundantRequirements (
8536
+ /* onlyDiagnoseExplicitConformancesImpliedByConcrete=*/ true );
8537
+
8538
8538
return std::move (*this ).rebuildSignatureWithoutRedundantRequirements (
8539
8539
allowConcreteGenericParams,
8540
8540
requirementSignatureSelfProto);
8541
8541
}
8542
8542
8543
- // Collect the requirements placed on the generic parameter types.
8543
+ if (Impl->RebuildingWithoutRedundantConformances ) {
8544
+ #ifndef NDEBUG
8545
+ for (const auto &req : Impl->ExplicitConformancesImpliedByConcrete ) {
8546
+ assert (!isRedundantExplicitRequirement (req) &&
8547
+ " Rebuilt signature still had redundant conformance requirements" );
8548
+ }
8549
+ #endif
8550
+ }
8551
+
8552
+ // Diagnose redundant requirements, check for recursive concrete types
8553
+ // and compute minimized same-type requirements.
8554
+ finalize (getGenericParams (),
8555
+ allowConcreteGenericParams,
8556
+ requirementSignatureSelfProto);
8557
+
8558
+ // Collect all non-redundant explicit requirements.
8544
8559
SmallVector<Requirement, 4 > requirements;
8545
8560
enumerateRequirements (getGenericParams (), requirements);
8546
8561
0 commit comments