@@ -1758,6 +1758,37 @@ SourceLoc FloatingRequirementSource::getLoc() const {
17581758 return SourceLoc ();
17591759}
17601760
1761+ bool FloatingRequirementSource::isDerived () const {
1762+ switch (kind) {
1763+ case Explicit:
1764+ case Inferred:
1765+ case NestedTypeNameMatch:
1766+ return false ;
1767+
1768+ case AbstractProtocol:
1769+ switch (storage.get <const RequirementSource *>()->kind ) {
1770+ case RequirementSource::RequirementSignatureSelf:
1771+ return false ;
1772+
1773+ case RequirementSource::Concrete:
1774+ case RequirementSource::Explicit:
1775+ case RequirementSource::Inferred:
1776+ case RequirementSource::NestedTypeNameMatch:
1777+ case RequirementSource::Parent:
1778+ case RequirementSource::ProtocolRequirement:
1779+ case RequirementSource::InferredProtocolRequirement:
1780+ case RequirementSource::Superclass:
1781+ case RequirementSource::Layout:
1782+ case RequirementSource::EquivalentType:
1783+ return true ;
1784+ }
1785+
1786+ case Resolved:
1787+ return storage.get <const RequirementSource *>()->isDerivedRequirement ();
1788+ }
1789+ llvm_unreachable (" unhandled kind" );
1790+ }
1791+
17611792bool FloatingRequirementSource::isExplicit () const {
17621793 switch (kind) {
17631794 case Explicit:
@@ -2556,9 +2587,20 @@ GenericSignatureBuilder::resolveConcreteConformance(ResolvedType type,
25562587 } else {
25572588 concreteSource = concreteSource->viaConcrete (*this , conformance);
25582589 equivClass->recordConformanceConstraint (*this , type, proto, concreteSource);
2559- if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2560- concreteSource->getLoc ()))
2561- return nullptr ;
2590+
2591+ // Only infer conditional requirements from explicit sources.
2592+ bool hasExplicitSource = llvm::any_of (
2593+ equivClass->concreteTypeConstraints ,
2594+ [](const ConcreteConstraint &constraint) {
2595+ return (!constraint.source ->isDerivedRequirement () &&
2596+ constraint.source ->getLoc ().isValid ());
2597+ });
2598+
2599+ if (hasExplicitSource) {
2600+ if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2601+ concreteSource->getLoc ()))
2602+ return nullptr ;
2603+ }
25622604 }
25632605
25642606 return concreteSource;
@@ -2590,9 +2632,20 @@ const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
25902632
25912633 superclassSource = superclassSource->viaSuperclass (*this , conformance);
25922634 equivClass->recordConformanceConstraint (*this , type, proto, superclassSource);
2593- if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2594- superclassSource->getLoc ()))
2595- return nullptr ;
2635+
2636+ // Only infer conditional requirements from explicit sources.
2637+ bool hasExplicitSource = llvm::any_of (
2638+ equivClass->superclassConstraints ,
2639+ [](const ConcreteConstraint &constraint) {
2640+ return (!constraint.source ->isDerivedRequirement () &&
2641+ constraint.source ->getLoc ().isValid ());
2642+ });
2643+
2644+ if (hasExplicitSource) {
2645+ if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2646+ superclassSource->getLoc ()))
2647+ return nullptr ;
2648+ }
25962649
25972650 return superclassSource;
25982651}
@@ -4599,9 +4652,12 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
45994652
46004653 // FIXME: diagnose if there's no conformance.
46014654 if (conformance) {
4602- if (addConditionalRequirements (conformance, inferForModule,
4603- source.getLoc ()))
4604- return ConstraintResult::Conflicting;
4655+ // Only infer conditional requirements from explicit sources.
4656+ if (!source.isDerived ()) {
4657+ if (addConditionalRequirements (conformance, inferForModule,
4658+ source.getLoc ()))
4659+ return ConstraintResult::Conflicting;
4660+ }
46054661 }
46064662 }
46074663 }
0 commit comments