@@ -1602,7 +1602,7 @@ ConstraintSystem::matchTypesBindTypeVar(
1602
1602
1603
1603
static ConstraintFix *fixRequirementFailure (ConstraintSystem &cs, Type type1,
1604
1604
Type type2, Expr *anchor,
1605
- LocatorPathElt &req ) {
1605
+ ArrayRef< LocatorPathElt> path ) {
1606
1606
// Can't fix not yet properly resolved types.
1607
1607
if (type1->hasTypeVariable () || type2->hasTypeVariable ())
1608
1608
return nullptr ;
@@ -1612,9 +1612,21 @@ static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
1612
1612
if (type1->hasDependentMember () || type2->hasDependentMember ())
1613
1613
return nullptr ;
1614
1614
1615
- // Build simplified locator which only contains anchor and requirement info.
1616
- ConstraintLocatorBuilder requirement (cs.getConstraintLocator (anchor));
1617
- auto *reqLoc = cs.getConstraintLocator (requirement.withPathElement (req));
1615
+ auto req = path.back ();
1616
+
1617
+ ConstraintLocator *reqLoc = nullptr ;
1618
+ if (req.getKind () == ConstraintLocator::ConditionalRequirement) {
1619
+ // If underlaying conformance requirement has been fixed as
1620
+ // we there is no reason to fix up conditional requirements.
1621
+ if (cs.hasFixFor (cs.getConstraintLocator (anchor, req)))
1622
+ return nullptr ;
1623
+
1624
+ // For conditional requirements we need a full path.
1625
+ reqLoc = cs.getConstraintLocator (anchor, path, /* summaryFlags=*/ 0 );
1626
+ } else {
1627
+ // Build simplified locator which only contains anchor and requirement info.
1628
+ reqLoc = cs.getConstraintLocator (anchor, req);
1629
+ }
1618
1630
1619
1631
auto reqKind = static_cast <RequirementKind>(req.getValue2 ());
1620
1632
switch (reqKind) {
@@ -1644,8 +1656,9 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
1644
1656
1645
1657
auto &elt = path.back ();
1646
1658
switch (elt.getKind ()) {
1647
- case ConstraintLocator::TypeParameterRequirement: {
1648
- if (auto *fix = fixRequirementFailure (cs, lhs, rhs, anchor, elt))
1659
+ case ConstraintLocator::TypeParameterRequirement:
1660
+ case ConstraintLocator::ConditionalRequirement: {
1661
+ if (auto *fix = fixRequirementFailure (cs, lhs, rhs, anchor, path))
1649
1662
conversionsOrFixes.push_back (fix);
1650
1663
break ;
1651
1664
}
@@ -2764,15 +2777,25 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
2764
2777
SmallVector<LocatorPathElt, 4 > path;
2765
2778
auto *anchor = locator.getLocatorParts (path);
2766
2779
2767
- if (!path.empty () && path.back ().getKind () ==
2768
- ConstraintLocator::PathElementKind::TypeParameterRequirement) {
2769
- auto typeRequirement = path.back ();
2770
- // Let's strip all of the unnecessary information from locator,
2771
- // diagnostics only care about anchor - to lookup type,
2772
- // and what was the requirement# which is not satisfied.
2773
- ConstraintLocatorBuilder requirement (getConstraintLocator (anchor));
2774
- auto *reqLoc =
2775
- getConstraintLocator (requirement.withPathElement (typeRequirement));
2780
+ if (!path.empty () &&
2781
+ (path.back ().getKind () == ConstraintLocator::TypeParameterRequirement ||
2782
+ path.back ().getKind () == ConstraintLocator::ConditionalRequirement)) {
2783
+ ConstraintLocator *reqLoc = nullptr ;
2784
+ if (path.back ().getKind () == ConstraintLocator::ConditionalRequirement) {
2785
+ // Underlying conformance requirement is itself fixed,
2786
+ // this wouldn't lead to right solution.
2787
+ if (hasFixFor (getConstraintLocator (anchor, path.back ())))
2788
+ return SolutionKind::Error;
2789
+
2790
+ // For conditional requirements we need complete path, which includes
2791
+ // type requirement position, to be able to fetch conformance later.
2792
+ reqLoc = getConstraintLocator (locator);
2793
+ } else {
2794
+ // Let's strip all of the unnecessary information from locator,
2795
+ // diagnostics only care about anchor - to lookup type,
2796
+ // and what was the requirement# which is not satisfied.
2797
+ reqLoc = getConstraintLocator (anchor, path.back ());
2798
+ }
2776
2799
2777
2800
auto *fix = MissingConformance::create (*this , type, protocol, reqLoc);
2778
2801
if (!recordFix (fix))
@@ -5417,12 +5440,7 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix) {
5417
5440
// Always useful, unless duplicate of exactly the same fix and location.
5418
5441
// This situation might happen when the same fix kind is applicable to
5419
5442
// different overload choices.
5420
- auto *loc = fix->getLocator ();
5421
- auto existingFix = llvm::find_if (Fixes, [&](const ConstraintFix *e) {
5422
- // If we already have a fix like this recorded, let's not do it again,
5423
- return e->getKind () == fix->getKind () && e->getLocator () == loc;
5424
- });
5425
- if (existingFix == Fixes.end ())
5443
+ if (!hasFixFor (fix->getLocator ()))
5426
5444
Fixes.push_back (fix);
5427
5445
} else {
5428
5446
// Only useful to record if no pre-existing fix in the subexpr tree.
0 commit comments