@@ -1758,6 +1758,37 @@ SourceLoc FloatingRequirementSource::getLoc() const {
1758
1758
return SourceLoc ();
1759
1759
}
1760
1760
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
+
1761
1792
bool FloatingRequirementSource::isExplicit () const {
1762
1793
switch (kind) {
1763
1794
case Explicit:
@@ -2556,9 +2587,20 @@ GenericSignatureBuilder::resolveConcreteConformance(ResolvedType type,
2556
2587
} else {
2557
2588
concreteSource = concreteSource->viaConcrete (*this , conformance);
2558
2589
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
+ }
2562
2604
}
2563
2605
2564
2606
return concreteSource;
@@ -2590,9 +2632,20 @@ const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
2590
2632
2591
2633
superclassSource = superclassSource->viaSuperclass (*this , conformance);
2592
2634
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
+ }
2596
2649
2597
2650
return superclassSource;
2598
2651
}
@@ -4599,9 +4652,12 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
4599
4652
4600
4653
// FIXME: diagnose if there's no conformance.
4601
4654
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
+ }
4605
4661
}
4606
4662
}
4607
4663
}
0 commit comments