@@ -730,6 +730,8 @@ struct GenericSignatureBuilder::Implementation {
730
730
std::vector<ConflictingConcreteTypeRequirement>
731
731
ConflictingConcreteTypeRequirements;
732
732
733
+ llvm::DenseSet<ExplicitRequirement> ExplicitConformancesImpliedByConcrete;
734
+
733
735
#ifndef NDEBUG
734
736
// / Whether we've already computed redundant requiremnts.
735
737
bool computedRedundantRequirements = false ;
@@ -1094,12 +1096,14 @@ const RequirementSource *RequirementSource::getMinimalConformanceSource(
1094
1096
ArchetypeResolutionKind::WellFormed);
1095
1097
assert (parentEquivClass && " Not a well-formed type?" );
1096
1098
1097
- if (parentEquivClass->concreteType )
1098
- derivedViaConcrete = true ;
1099
- else if (parentEquivClass->superclass &&
1100
- builder.lookupConformance (parentEquivClass->superclass ,
1101
- source->getProtocolDecl ()))
1102
- derivedViaConcrete = true ;
1099
+ if (requirementSignatureSelfProto) {
1100
+ if (parentEquivClass->concreteType )
1101
+ derivedViaConcrete = true ;
1102
+ else if (parentEquivClass->superclass &&
1103
+ builder.lookupConformance (parentEquivClass->superclass ,
1104
+ source->getProtocolDecl ()))
1105
+ derivedViaConcrete = true ;
1106
+ }
1103
1107
1104
1108
// The parent potential archetype must conform to the protocol in which
1105
1109
// this requirement resides. Add this constraint.
@@ -6256,6 +6260,20 @@ static bool typeConflictsWithLayoutConstraint(Type t, LayoutConstraint layout) {
6256
6260
return false ;
6257
6261
}
6258
6262
6263
+ static bool isConcreteConformance (const EquivalenceClass &equivClass,
6264
+ ProtocolDecl *proto,
6265
+ GenericSignatureBuilder &builder) {
6266
+ if (equivClass.concreteType &&
6267
+ builder.lookupConformance (equivClass.concreteType , proto)) {
6268
+ return true ;
6269
+ } else if (equivClass.superclass &&
6270
+ builder.lookupConformance (equivClass.superclass , proto)) {
6271
+ return true ;
6272
+ }
6273
+
6274
+ return false ;
6275
+ }
6276
+
6259
6277
void GenericSignatureBuilder::computeRedundantRequirements () {
6260
6278
assert (!Impl->computedRedundantRequirements &&
6261
6279
" Already computed redundant requirements" );
@@ -6289,6 +6307,14 @@ void GenericSignatureBuilder::computeRedundantRequirements() {
6289
6307
6290
6308
// FIXME: Check for a conflict via the concrete type.
6291
6309
exact.push_back (constraint);
6310
+
6311
+ if (!source->isDerivedRequirement ()) {
6312
+ if (isConcreteConformance (equivClass, entry.first , *this )) {
6313
+ Impl->ExplicitConformancesImpliedByConcrete .insert (
6314
+ ExplicitRequirement::fromExplicitConstraint (
6315
+ RequirementKind::Conformance, constraint));
6316
+ }
6317
+ }
6292
6318
}
6293
6319
6294
6320
graph.addConstraintsFromEquivClass (RequirementKind::Conformance,
@@ -7176,6 +7202,9 @@ void GenericSignatureBuilder::diagnoseRedundantRequirements() const {
7176
7202
7177
7203
for (auto otherReq : found->second ) {
7178
7204
auto *otherSource = otherReq.getSource ();
7205
+ if (otherSource->isInferredRequirement ())
7206
+ continue ;
7207
+
7179
7208
auto otherLoc = otherSource->getLoc ();
7180
7209
if (otherLoc.isInvalid ())
7181
7210
continue ;
@@ -7213,6 +7242,9 @@ void GenericSignatureBuilder::diagnoseRedundantRequirements() const {
7213
7242
7214
7243
for (auto otherReq : found->second ) {
7215
7244
auto *otherSource = otherReq.getSource ();
7245
+ if (otherSource->isInferredRequirement ())
7246
+ continue ;
7247
+
7216
7248
auto otherLoc = otherSource->getLoc ();
7217
7249
if (otherLoc.isInvalid ())
7218
7250
continue ;
@@ -7252,6 +7284,9 @@ void GenericSignatureBuilder::diagnoseRedundantRequirements() const {
7252
7284
7253
7285
for (auto otherReq : found->second ) {
7254
7286
auto *otherSource = otherReq.getSource ();
7287
+ if (otherSource->isInferredRequirement ())
7288
+ continue ;
7289
+
7255
7290
auto otherLoc = otherSource->getLoc ();
7256
7291
if (otherLoc.isInvalid ())
7257
7292
continue ;
@@ -8159,7 +8194,7 @@ void GenericSignatureBuilder::checkLayoutConstraints(
8159
8194
}
8160
8195
8161
8196
bool GenericSignatureBuilder::isRedundantExplicitRequirement (
8162
- ExplicitRequirement req) const {
8197
+ const ExplicitRequirement & req) const {
8163
8198
assert (Impl->computedRedundantRequirements &&
8164
8199
" Must ensure computeRedundantRequirements() is called first" );
8165
8200
auto &redundantReqs = Impl->RedundantRequirements ;
@@ -8466,23 +8501,6 @@ static void checkGenericSignature(CanGenericSignature canSig,
8466
8501
}
8467
8502
#endif
8468
8503
8469
- bool GenericSignatureBuilder::hasExplicitConformancesImpliedByConcrete () const {
8470
- for (auto pair : Impl->RedundantRequirements ) {
8471
- if (pair.first .getKind () != RequirementKind::Conformance)
8472
- continue ;
8473
-
8474
- for (auto impliedByReq : pair.second ) {
8475
- if (impliedByReq.getKind () == RequirementKind::Superclass)
8476
- return true ;
8477
-
8478
- if (impliedByReq.getKind () == RequirementKind::SameType)
8479
- return true ;
8480
- }
8481
- }
8482
-
8483
- return false ;
8484
- }
8485
-
8486
8504
static Type stripBoundDependentMemberTypes (Type t) {
8487
8505
if (auto *depMemTy = t->getAs <DependentMemberType>()) {
8488
8506
return DependentMemberType::get (
@@ -8532,7 +8550,8 @@ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequir
8532
8550
assert (req.getKind () != RequirementKind::SameType &&
8533
8551
" Should not see same-type requirement here" );
8534
8552
8535
- if (isRedundantExplicitRequirement (req))
8553
+ if (isRedundantExplicitRequirement (req) &&
8554
+ Impl->ExplicitConformancesImpliedByConcrete .count (req))
8536
8555
continue ;
8537
8556
8538
8557
auto subjectType = req.getSource ()->getStoredType ();
@@ -8618,8 +8637,12 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
8618
8637
assert (!Impl->HadAnyError &&
8619
8638
" Rebuilt signature had errors" );
8620
8639
8621
- assert (!hasExplicitConformancesImpliedByConcrete () &&
8622
- " Rebuilt signature still had redundant conformance requirements" );
8640
+ #ifndef NDEBUG
8641
+ for (const auto &req : Impl->ExplicitConformancesImpliedByConcrete ) {
8642
+ assert (!isRedundantExplicitRequirement (req) &&
8643
+ " Rebuilt signature still had redundant conformance requirements" );
8644
+ }
8645
+ #endif
8623
8646
}
8624
8647
8625
8648
// If any of our explicit conformance requirements were implied by
@@ -8634,7 +8657,7 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
8634
8657
if (!rebuildingWithoutRedundantConformances &&
8635
8658
!buildingRequirementSignature &&
8636
8659
!Impl->HadAnyError &&
8637
- hasExplicitConformancesImpliedByConcrete ()) {
8660
+ !Impl-> ExplicitConformancesImpliedByConcrete . empty ()) {
8638
8661
return std::move (*this ).rebuildSignatureWithoutRedundantRequirements (
8639
8662
allowConcreteGenericParams,
8640
8663
buildingRequirementSignature);
0 commit comments