@@ -1793,7 +1793,13 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
1793
1793
auto *argPack = PackType::get(cs.getASTContext(), argTypes);
1794
1794
auto *argPackExpansion = PackExpansionType::get(argPack, argPack);
1795
1795
1796
- cs.addConstraint(subKind, argPackExpansion, paramTy, loc);
1796
+ auto firstArgIdx =
1797
+ argTypes.empty() ? paramIdx : parameterBindings[paramIdx].front();
1798
+
1799
+ cs.addConstraint(
1800
+ subKind, argPackExpansion, paramTy,
1801
+ locator.withPathElement(LocatorPathElt::ApplyArgToParam(
1802
+ firstArgIdx, paramIdx, param.getParameterFlags())));
1797
1803
continue;
1798
1804
}
1799
1805
}
@@ -5661,6 +5667,18 @@ bool ConstraintSystem::repairFailures(
5661
5667
if (hasFixFor(loc, FixKind::RemoveExtraneousArguments))
5662
5668
return true;
5663
5669
5670
+ // If parameter is a pack, let's see if we have already recorded
5671
+ // either synthesized or extraneous argument fixes.
5672
+ if (rhs->is<PackType>()) {
5673
+ ArrayRef tmpPath(path);
5674
+
5675
+ // Path would end with `ApplyArgument`.
5676
+ auto *argsLoc = getConstraintLocator(anchor, tmpPath.drop_back());
5677
+ if (hasFixFor(argsLoc, FixKind::RemoveExtraneousArguments) ||
5678
+ hasFixFor(argsLoc, FixKind::AddMissingArguments))
5679
+ return true;
5680
+ }
5681
+
5664
5682
// If the argument couldn't be found, this could be a default value
5665
5683
// type mismatch.
5666
5684
if (!simplifyLocatorToAnchor(loc)) {
@@ -7275,9 +7293,16 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
7275
7293
case TypeKind::Pack: {
7276
7294
auto tmpPackLoc = locator.withPathElement(LocatorPathElt::PackType(type1));
7277
7295
auto packLoc = tmpPackLoc.withPathElement(LocatorPathElt::PackType(type2));
7278
- return matchPackTypes(cast<PackType>(desugar1),
7279
- cast<PackType>(desugar2),
7280
- kind, subflags, packLoc);
7296
+
7297
+ auto result =
7298
+ matchPackTypes(cast<PackType>(desugar1), cast<PackType>(desugar2),
7299
+ kind, subflags, packLoc);
7300
+
7301
+ // Let `repairFailures` attempt to "fix" this.
7302
+ if (shouldAttemptFixes() && result.isFailure())
7303
+ break;
7304
+
7305
+ return result;
7281
7306
}
7282
7307
case TypeKind::PackExpansion: {
7283
7308
auto expansion1 = cast<PackExpansionType>(desugar1);
@@ -13278,16 +13303,87 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifySameShapeConstraint(
13278
13303
return SolutionKind::Solved;
13279
13304
13280
13305
if (shouldAttemptFixes()) {
13306
+ // If there are placeholders involved shape mismatches are most
13307
+ // likely just a symptom of some other issue i.e. type mismatch.
13281
13308
if (type1->hasPlaceholder() || type2->hasPlaceholder())
13282
13309
return SolutionKind::Solved;
13283
13310
13311
+ auto recordShapeFix = [&](ConstraintFix *fix,
13312
+ unsigned impact) -> SolutionKind {
13313
+ return recordFix(fix, impact) ? SolutionKind::Error
13314
+ : SolutionKind::Solved;
13315
+ };
13316
+
13317
+ // Let's check whether we can produce a tailored fix for argument/parameter
13318
+ // mismatches.
13319
+ if (locator.endsWith<LocatorPathElt::PackShape>()) {
13320
+ SmallVector<LocatorPathElt> path;
13321
+ auto anchor = locator.getLocatorParts(path);
13322
+
13323
+ // Drop `PackShape`
13324
+ path.pop_back();
13325
+
13326
+ // Tailed diagnostics for argument/parameter mismatches - there
13327
+ // are either missing or extra arguments.
13328
+ if (path.size() > 0 &&
13329
+ path[path.size() - 1].is<LocatorPathElt::ApplyArgToParam>()) {
13330
+ auto &ctx = getASTContext();
13331
+
13332
+ auto *loc = getConstraintLocator(anchor, path);
13333
+ auto argLoc =
13334
+ loc->castLastElementTo<LocatorPathElt::ApplyArgToParam>();
13335
+
13336
+ auto numArgs = shape1->castTo<PackType>()->getNumElements();
13337
+ auto numParams = shape2->castTo<PackType>()->getNumElements();
13338
+
13339
+ // Drops `ApplyArgToParam` and left with `ApplyArgument`.
13340
+ path.pop_back();
13341
+
13342
+ auto *argListLoc = getConstraintLocator(anchor, path);
13343
+
13344
+ // Missing arguments.
13345
+ if (numParams > numArgs) {
13346
+ SmallVector<SynthesizedArg> synthesizedArgs;
13347
+ for (unsigned i = 0, n = numParams - numArgs; i != n; ++i) {
13348
+ auto eltTy = shape2->castTo<PackType>()->getElementType(i);
13349
+ synthesizedArgs.push_back(SynthesizedArg{
13350
+ argLoc.getParamIdx(), AnyFunctionType::Param(eltTy)});
13351
+ }
13352
+
13353
+ return recordShapeFix(
13354
+ AddMissingArguments::create(*this, synthesizedArgs, argListLoc),
13355
+ /*impact=*/2 * synthesizedArgs.size());
13356
+ } else {
13357
+ auto argIdx = argLoc.getArgIdx() + numParams;
13358
+ SmallVector<std::pair<unsigned, AnyFunctionType::Param>, 4>
13359
+ extraneousArgs;
13360
+
13361
+ for (unsigned i = 0, n = numArgs - numParams; i != n; ++i) {
13362
+ extraneousArgs.push_back(
13363
+ {argIdx + i, AnyFunctionType::Param(ctx.TheEmptyTupleType)});
13364
+ }
13365
+
13366
+ auto overload = findSelectedOverloadFor(getCalleeLocator(argListLoc));
13367
+ if (!overload)
13368
+ return SolutionKind::Error;
13369
+
13370
+ return recordShapeFix(
13371
+ RemoveExtraneousArguments::create(
13372
+ *this, overload->openedType->castTo<FunctionType>(),
13373
+ extraneousArgs, argListLoc),
13374
+ /*impact=*/2 * extraneousArgs.size());
13375
+ }
13376
+ }
13377
+ }
13378
+
13284
13379
unsigned impact = 1;
13285
13380
if (locator.endsWith<LocatorPathElt::AnyRequirement>())
13286
13381
impact = assessRequirementFailureImpact(*this, shape1, locator);
13287
13382
13288
- auto *fix = SkipSameShapeRequirement::create(*this, type1, type2,
13289
- getConstraintLocator(locator));
13290
- return recordFix(fix, impact) ? SolutionKind::Error : SolutionKind::Solved;
13383
+ return recordShapeFix(
13384
+ SkipSameShapeRequirement::create(*this, type1, type2,
13385
+ getConstraintLocator(locator)),
13386
+ impact);
13291
13387
}
13292
13388
13293
13389
return SolutionKind::Error;
0 commit comments