@@ -2607,10 +2607,9 @@ static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
2607
2607
Type type2,
2608
2608
ConstraintLocatorBuilder locator) {
2609
2609
SmallVector<LocatorPathElt, 4> path;
2610
- if (auto anchor = locator.getLocatorParts(path)) {
2611
- return fixRequirementFailure(cs, type1, type2, anchor, path);
2612
- }
2613
- return nullptr;
2610
+
2611
+ auto anchor = locator.getLocatorParts(path);
2612
+ return fixRequirementFailure(cs, type1, type2, anchor, path);
2614
2613
}
2615
2614
2616
2615
static unsigned
@@ -3576,8 +3575,16 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
3576
3575
if (mismatches.empty())
3577
3576
return result;
3578
3577
3579
- if (auto last = locator.last()) {
3580
- if (last->is<LocatorPathElt::AnyRequirement>()) {
3578
+ auto *loc = getConstraintLocator(locator);
3579
+
3580
+ auto path = loc->getPath();
3581
+ if (!path.empty()) {
3582
+ // If we have something like ... -> type req # -> pack element #, we're
3583
+ // solving a requirement of the form T : P where T is a type parameter pack
3584
+ if (path.back().is<LocatorPathElt::PackElement>())
3585
+ path = path.drop_back();
3586
+
3587
+ if (path.back().is<LocatorPathElt::AnyRequirement>()) {
3581
3588
if (auto *fix = fixRequirementFailure(*this, type1, type2, locator)) {
3582
3589
if (recordFix(fix))
3583
3590
return getTypeMatchFailure(locator);
@@ -3602,7 +3609,7 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
3602
3609
}
3603
3610
3604
3611
auto *fix = GenericArgumentsMismatch::create(
3605
- *this, type1, type2, mismatches, getConstraintLocator(locator) );
3612
+ *this, type1, type2, mismatches, loc );
3606
3613
3607
3614
if (!recordFix(fix, impact))
3608
3615
return getTypeMatchSuccess();
@@ -4144,6 +4151,11 @@ static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
4144
4151
if (type1->isTypeVariableOrMember() || type2->isTypeVariableOrMember())
4145
4152
return nullptr;
4146
4153
4154
+ // If we have something like ... -> type req # -> pack element #, we're
4155
+ // solving a requirement of the form T : P where T is a type parameter pack
4156
+ if (path.back().is<LocatorPathElt::PackElement>())
4157
+ path = path.drop_back();
4158
+
4147
4159
auto req = path.back().castTo<LocatorPathElt::AnyRequirement>();
4148
4160
if (req.isConditionalRequirement()) {
4149
4161
// path is - ... -> open generic -> type req # -> cond req #,
@@ -6051,11 +6063,17 @@ bool ConstraintSystem::repairFailures(
6051
6063
// record the requirement failure fix.
6052
6064
path.pop_back();
6053
6065
6054
- if (path.empty() || !path.back().is<LocatorPathElt::AnyRequirement>())
6055
- break;
6066
+ // If we have something like ... -> type req # -> pack element #, we're
6067
+ // solving a requirement of the form T : P where T is a type parameter pack
6068
+ if (!path.empty() && path.back().is<LocatorPathElt::PackElement>())
6069
+ path.pop_back();
6056
6070
6057
- return repairFailures(lhs, rhs, matchKind, conversionsOrFixes,
6058
- getConstraintLocator(anchor, path));
6071
+ if (!path.empty() && path.back().is<LocatorPathElt::AnyRequirement>()) {
6072
+ return repairFailures(lhs, rhs, matchKind, conversionsOrFixes,
6073
+ getConstraintLocator(anchor, path));
6074
+ }
6075
+
6076
+ break;
6059
6077
}
6060
6078
6061
6079
case ConstraintLocator::ResultBuilderBodyResult: {
@@ -7636,6 +7654,11 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
7636
7654
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
7637
7655
}
7638
7656
7657
+ // If we have something like ... -> type req # -> pack element #, we're
7658
+ // solving a requirement of the form T : P where T is a type parameter pack
7659
+ if (path.back().is<LocatorPathElt::PackElement>())
7660
+ path.pop_back();
7661
+
7639
7662
if (auto req = path.back().getAs<LocatorPathElt::AnyRequirement>()) {
7640
7663
// If this is a requirement associated with `Self` which is bound
7641
7664
// to `Any`, let's consider this "too incorrect" to continue.
@@ -13875,10 +13898,20 @@ void ConstraintSystem::addConstraint(Requirement req,
13875
13898
case RequirementKind::Conformance:
13876
13899
kind = ConstraintKind::ConformsTo;
13877
13900
break;
13878
- case RequirementKind::Superclass:
13901
+ case RequirementKind::Superclass: {
13902
+ // FIXME: Should always use ConstraintKind::SubclassOf, but that breaks
13903
+ // a couple of diagnostics
13904
+ if (auto *typeVar = req.getFirstType()->getAs<TypeVariableType>()) {
13905
+ if (typeVar->getImpl().canBindToPack()) {
13906
+ kind = ConstraintKind::SubclassOf;
13907
+ break;
13908
+ }
13909
+ }
13910
+
13879
13911
conformsToAnyObject = true;
13880
13912
kind = ConstraintKind::Subtype;
13881
13913
break;
13914
+ }
13882
13915
case RequirementKind::SameType:
13883
13916
kind = ConstraintKind::Bind;
13884
13917
break;
0 commit comments