@@ -1916,10 +1916,12 @@ bool EquivalenceClass::recordConformanceConstraint(
19161916
19171917 // If there is a concrete type that resolves this conformance requirement,
19181918 // record the conformance.
1919- if (!builder.resolveConcreteConformance (type, proto)) {
1919+ bool explicitConformance = !source->isDerivedRequirement ();
1920+
1921+ if (!builder.resolveConcreteConformance (type, proto, explicitConformance)) {
19201922 // Otherwise, determine whether there is a superclass constraint where the
19211923 // superclass conforms to this protocol.
1922- (void )builder.resolveSuperConformance (type, proto);
1924+ (void )builder.resolveSuperConformance (type, proto, explicitConformance );
19231925 }
19241926 }
19251927
@@ -2324,7 +2326,8 @@ void GenericSignatureBuilder::addConditionalRequirements(
23242326
23252327const RequirementSource *
23262328GenericSignatureBuilder::resolveConcreteConformance (ResolvedType type,
2327- ProtocolDecl *proto) {
2329+ ProtocolDecl *proto,
2330+ bool explicitConformance) {
23282331 auto equivClass = type.getEquivalenceClass (*this );
23292332 auto concrete = equivClass->concreteType ;
23302333 if (!concrete) return nullptr ;
@@ -2378,21 +2381,22 @@ GenericSignatureBuilder::resolveConcreteConformance(ResolvedType type,
23782381 equivClass->recordConformanceConstraint (*this , type, proto, concreteSource);
23792382
23802383 // Only infer conditional requirements from explicit sources.
2381- bool hasExplicitSource = llvm::any_of (
2384+ bool explicitConcreteType = llvm::any_of (
23822385 equivClass->concreteTypeConstraints ,
23832386 [](const ConcreteConstraint &constraint) {
23842387 return !constraint.source ->isDerivedRequirement ();
23852388 });
23862389
2387- if (hasExplicitSource ) {
2390+ if (explicitConformance || explicitConcreteType ) {
23882391 addConditionalRequirements (conformance, /* inferForModule=*/ nullptr );
23892392 }
23902393
23912394 return concreteSource;
23922395}
2393- const RequirementSource *GenericSignatureBuilder::resolveSuperConformance (
2394- ResolvedType type,
2395- ProtocolDecl *proto) {
2396+ const RequirementSource *
2397+ GenericSignatureBuilder::resolveSuperConformance (ResolvedType type,
2398+ ProtocolDecl *proto,
2399+ bool explicitConformance) {
23962400 // Get the superclass constraint.
23972401 auto equivClass = type.getEquivalenceClass (*this );
23982402 Type superclass = equivClass->superclass ;
@@ -2418,14 +2422,13 @@ const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
24182422 equivClass->recordConformanceConstraint (*this , type, proto, superclassSource);
24192423
24202424 // Only infer conditional requirements from explicit sources.
2421- bool hasExplicitSource = llvm::any_of (
2422- equivClass->superclassConstraints ,
2423- [](const ConcreteConstraint &constraint) {
2424- return (!constraint.source ->isDerivedRequirement () &&
2425- constraint.source ->getLoc ().isValid ());
2426- });
2425+ bool explicitSuperclass = llvm::any_of (
2426+ equivClass->superclassConstraints ,
2427+ [](const ConcreteConstraint &constraint) {
2428+ return !constraint.source ->isDerivedRequirement ();
2429+ });
24272430
2428- if (hasExplicitSource ) {
2431+ if (explicitConformance || explicitSuperclass ) {
24292432 addConditionalRequirements (conformance, /* inferForModule=*/ nullptr );
24302433 }
24312434
@@ -4410,7 +4413,13 @@ bool GenericSignatureBuilder::updateSuperclass(
44104413 // when the superclass constraint changes.
44114414 auto updateSuperclassConformances = [&] {
44124415 for (const auto &conforms : equivClass->conformsTo ) {
4413- (void )resolveSuperConformance (type, conforms.first );
4416+ bool explicitConformance = std::find_if (
4417+ conforms.second .begin (),
4418+ conforms.second .end (),
4419+ [](const Constraint<ProtocolDecl *> &constraint) {
4420+ return !constraint.source ->isDerivedRequirement ();
4421+ }) != conforms.second .end ();
4422+ (void )resolveSuperConformance (type, conforms.first , explicitConformance);
44144423 }
44154424
44164425 // Eagerly resolve any existing nested types to their concrete forms (others
@@ -4809,8 +4818,15 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenTypeParameters(
48094818 equivClass2->concreteTypeConstraints .begin (),
48104819 equivClass2->concreteTypeConstraints .end ());
48114820
4812- for (const auto &conforms : equivClass->conformsTo )
4813- (void )resolveConcreteConformance (T1, conforms.first );
4821+ for (const auto &conforms : equivClass->conformsTo ) {
4822+ bool explicitConformance = std::find_if (
4823+ conforms.second .begin (),
4824+ conforms.second .end (),
4825+ [](const Constraint<ProtocolDecl *> &constraint) {
4826+ return !constraint.source ->isDerivedRequirement ();
4827+ }) != conforms.second .end ();
4828+ (void )resolveConcreteConformance (T1, conforms.first , explicitConformance);
4829+ }
48144830 }
48154831
48164832 // Make T1 the representative of T2, merging the equivalence classes.
@@ -4946,7 +4962,13 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirementToConcrete(
49464962 // Make sure the concrete type fulfills the conformance requirements of
49474963 // this equivalence class.
49484964 for (const auto &conforms : equivClass->conformsTo ) {
4949- if (!resolveConcreteConformance (type, conforms.first ))
4965+ bool explicitConformance = std::find_if (
4966+ conforms.second .begin (),
4967+ conforms.second .end (),
4968+ [](const Constraint<ProtocolDecl *> &constraint) {
4969+ return !constraint.source ->isDerivedRequirement ();
4970+ }) != conforms.second .end ();
4971+ if (!resolveConcreteConformance (type, conforms.first , explicitConformance))
49504972 return ConstraintResult::Conflicting;
49514973 }
49524974
0 commit comments