@@ -3748,15 +3748,23 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
37483748 // Match up the generic arguments, exactly.
37493749
37503750 if (shouldAttemptFixes()) {
3751+ auto *baseLoc =
3752+ getConstraintLocator(locator, {LocatorPathElt::GenericType(bound1),
3753+ LocatorPathElt::GenericType(bound2)});
3754+
3755+ auto argMatchingFlags =
3756+ subflags | TMF_ApplyingFix | TMF_MatchingGenericArguments;
3757+
37513758 // Optionals have a lot of special diagnostics and only one
37523759 // generic argument so if we' re dealing with one, don't produce generic
37533760 // arguments mismatch fixes.
37543761 if (bound1->getDecl()->isOptionalDecl())
3755- return matchDeepTypeArguments(*this, subflags, args1, args2, locator);
3762+ return matchDeepTypeArguments(*this, argMatchingFlags, args1, args2,
3763+ baseLoc);
37563764
37573765 SmallVector<unsigned, 4> mismatches;
37583766 auto result = matchDeepTypeArguments(
3759- *this, subflags | TMF_ApplyingFix , args1, args2, locator ,
3767+ *this, argMatchingFlags , args1, args2, baseLoc ,
37603768 [&mismatches](unsigned position) { mismatches.push_back(position); });
37613769
37623770 if (mismatches.empty())
@@ -4843,7 +4851,7 @@ static bool repairOutOfOrderArgumentsInBinaryFunction(
48434851/// \return true if at least some of the failures has been repaired
48444852/// successfully, which allows type matcher to continue.
48454853bool ConstraintSystem::repairFailures(
4846- Type lhs, Type rhs, ConstraintKind matchKind,
4854+ Type lhs, Type rhs, ConstraintKind matchKind, TypeMatchOptions flags,
48474855 SmallVectorImpl<RestrictionOrFix> &conversionsOrFixes,
48484856 ConstraintLocatorBuilder locator) {
48494857 SmallVector<LocatorPathElt, 4> path;
@@ -5344,7 +5352,7 @@ bool ConstraintSystem::repairFailures(
53445352 // let's re-attempt to repair without l-value conversion in the
53455353 // locator to fix underlying type mismatch.
53465354 if (path.back().is<LocatorPathElt::FunctionResult>()) {
5347- return repairFailures(lhs, rhs, matchKind, conversionsOrFixes,
5355+ return repairFailures(lhs, rhs, matchKind, flags, conversionsOrFixes,
53485356 getConstraintLocator(anchor, path));
53495357 }
53505358
@@ -6133,7 +6141,7 @@ bool ConstraintSystem::repairFailures(
61336141 if (!path.empty() && path.back().is<LocatorPathElt::PackType>())
61346142 path.pop_back();
61356143
6136- return repairFailures(lhs, rhs, matchKind, conversionsOrFixes,
6144+ return repairFailures(lhs, rhs, matchKind, flags, conversionsOrFixes,
61376145 getConstraintLocator(anchor, path));
61386146 }
61396147
@@ -6369,19 +6377,70 @@ bool ConstraintSystem::repairFailures(
63696377 // failure e.g. `String bind T.Element`, so let's drop the generic argument
63706378 // path element and recurse in repairFailures to check and potentially
63716379 // record the requirement failure fix.
6372- path.pop_back();
6380+ auto genericArgElt =
6381+ path.pop_back_val().castTo<LocatorPathElt::GenericArgument>();
63736382
63746383 // If we have something like ... -> type req # -> pack element #, we're
63756384 // solving a requirement of the form T : P where T is a type parameter pack
63766385 if (!path.empty() && path.back().is<LocatorPathElt::PackElement>())
63776386 path.pop_back();
63786387
63796388 if (!path.empty() && path.back().is<LocatorPathElt::AnyRequirement>()) {
6380- return repairFailures(lhs, rhs, matchKind, conversionsOrFixes,
6389+ return repairFailures(lhs, rhs, matchKind, flags, conversionsOrFixes,
63816390 getConstraintLocator(anchor, path));
63826391 }
63836392
6384- break;
6393+ // When the solver sets `TMF_MatchingGenericArguments` it means
6394+ // that it's matching generic argument pairs to identify any mismatches
6395+ // as part of larger matching of two generic types. Letting this
6396+ // fail results in a single fix that aggregates all mismatch locations.
6397+ //
6398+ // Types are not always resolved enough to enable that which means
6399+ // that the comparison should be delayed, which brings us here - a
6400+ // standalone constraint that represents such a match, in such cases
6401+ // we create a fix per mismatch location and coalesce them during
6402+ // diagnostics.
6403+ if (flags.contains(TMF_MatchingGenericArguments))
6404+ break;
6405+
6406+ Type fromType;
6407+ Type toType;
6408+
6409+ if (path.size() >= 2) {
6410+ if (path[path.size() - 2].is<LocatorPathElt::GenericType>()) {
6411+ fromType = path[path.size() - 2]
6412+ .castTo<LocatorPathElt::GenericType>()
6413+ .getType();
6414+ }
6415+
6416+ if (path[path.size() - 1].is<LocatorPathElt::GenericType>()) {
6417+ toType = path[path.size() - 1]
6418+ .castTo<LocatorPathElt::GenericType>()
6419+ .getType();
6420+ }
6421+ }
6422+
6423+ if (!fromType || !toType)
6424+ break;
6425+
6426+ // Drop both `GenericType` elements.
6427+ path.pop_back();
6428+ path.pop_back();
6429+
6430+ ConstraintFix *fix = nullptr;
6431+ if (!path.empty() && path.back().is<LocatorPathElt::AnyRequirement>()) {
6432+ fix = fixRequirementFailure(*this, fromType, toType, anchor, path);
6433+ } else {
6434+ fix = GenericArgumentsMismatch::create(
6435+ *this, fromType, toType, {genericArgElt.getIndex()},
6436+ getConstraintLocator(anchor, path));
6437+ }
6438+
6439+ if (!fix)
6440+ break;
6441+
6442+ conversionsOrFixes.push_back(fix);
6443+ return true;
63856444 }
63866445
63876446 case ConstraintLocator::ResultBuilderBodyResult: {
@@ -7478,7 +7537,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
74787537 // Attempt fixes iff it's allowed, both types are concrete and
74797538 // we are not in the middle of attempting one already.
74807539 if (shouldAttemptFixes() && !flags.contains(TMF_ApplyingFix)) {
7481- if (repairFailures(type1, type2, kind, conversionsOrFixes, locator)) {
7540+ if (repairFailures(type1, type2, kind, flags, conversionsOrFixes,
7541+ locator)) {
74827542 if (conversionsOrFixes.empty())
74837543 return getTypeMatchSuccess();
74847544 }
@@ -14038,7 +14098,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1403814098 case FixKind::MustBeCopyable:
1403914099 case FixKind::AllowInvalidPackElement:
1404014100 case FixKind::MacroMissingPound:
14041- case FixKind::AllowGlobalActorMismatch: {
14101+ case FixKind::AllowGlobalActorMismatch:
14102+ case FixKind::GenericArgumentsMismatch: {
1404214103 return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
1404314104 }
1404414105 case FixKind::IgnoreInvalidASTNode: {
@@ -14258,7 +14319,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1425814319 case FixKind::TreatKeyPathSubscriptIndexAsHashable:
1425914320 case FixKind::AllowInvalidRefInKeyPath:
1426014321 case FixKind::DefaultGenericArgument:
14261- case FixKind::GenericArgumentsMismatch:
1426214322 case FixKind::AllowMutatingMemberOnRValueBase:
1426314323 case FixKind::AllowTupleSplatForSingleParameter:
1426414324 case FixKind::AllowNonClassTypeToConvertToAnyObject:
0 commit comments