@@ -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
}
@@ -5673,6 +5679,18 @@ bool ConstraintSystem::repairFailures(
5673
5679
if (hasFixFor(loc, FixKind::RemoveExtraneousArguments))
5674
5680
return true;
5675
5681
5682
+ // If parameter is a pack, let's see if we have already recorded
5683
+ // either synthesized or extraneous argument fixes.
5684
+ if (rhs->is<PackType>()) {
5685
+ ArrayRef tmpPath(path);
5686
+
5687
+ // Path would end with `ApplyArgument`.
5688
+ auto *argsLoc = getConstraintLocator(anchor, tmpPath.drop_back());
5689
+ if (hasFixFor(argsLoc, FixKind::RemoveExtraneousArguments) ||
5690
+ hasFixFor(argsLoc, FixKind::AddMissingArguments))
5691
+ return true;
5692
+ }
5693
+
5676
5694
// If the argument couldn't be found, this could be a default value
5677
5695
// type mismatch.
5678
5696
if (!simplifyLocatorToAnchor(loc)) {
@@ -7271,9 +7289,16 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
7271
7289
case TypeKind::Pack: {
7272
7290
auto tmpPackLoc = locator.withPathElement(LocatorPathElt::PackType(type1));
7273
7291
auto packLoc = tmpPackLoc.withPathElement(LocatorPathElt::PackType(type2));
7274
- return matchPackTypes(cast<PackType>(desugar1),
7275
- cast<PackType>(desugar2),
7276
- kind, subflags, packLoc);
7292
+
7293
+ auto result =
7294
+ matchPackTypes(cast<PackType>(desugar1), cast<PackType>(desugar2),
7295
+ kind, subflags, packLoc);
7296
+
7297
+ // Let `repairFailures` attempt to "fix" this.
7298
+ if (shouldAttemptFixes() && result.isFailure())
7299
+ break;
7300
+
7301
+ return result;
7277
7302
}
7278
7303
case TypeKind::PackExpansion: {
7279
7304
auto expansion1 = cast<PackExpansionType>(desugar1);
@@ -13273,16 +13298,87 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifySameShapeConstraint(
13273
13298
return SolutionKind::Solved;
13274
13299
13275
13300
if (shouldAttemptFixes()) {
13301
+ // If there are placeholders involved shape mismatches are most
13302
+ // likely just a symptom of some other issue i.e. type mismatch.
13276
13303
if (type1->hasPlaceholder() || type2->hasPlaceholder())
13277
13304
return SolutionKind::Solved;
13278
13305
13306
+ auto recordShapeFix = [&](ConstraintFix *fix,
13307
+ unsigned impact) -> SolutionKind {
13308
+ return recordFix(fix, impact) ? SolutionKind::Error
13309
+ : SolutionKind::Solved;
13310
+ };
13311
+
13312
+ // Let's check whether we can produce a tailored fix for argument/parameter
13313
+ // mismatches.
13314
+ if (locator.endsWith<LocatorPathElt::PackShape>()) {
13315
+ SmallVector<LocatorPathElt> path;
13316
+ auto anchor = locator.getLocatorParts(path);
13317
+
13318
+ // Drop `PackShape`
13319
+ path.pop_back();
13320
+
13321
+ // Tailed diagnostics for argument/parameter mismatches - there
13322
+ // are either missing or extra arguments.
13323
+ if (path.size() > 0 &&
13324
+ path[path.size() - 1].is<LocatorPathElt::ApplyArgToParam>()) {
13325
+ auto &ctx = getASTContext();
13326
+
13327
+ auto *loc = getConstraintLocator(anchor, path);
13328
+ auto argLoc =
13329
+ loc->castLastElementTo<LocatorPathElt::ApplyArgToParam>();
13330
+
13331
+ auto numArgs = shape1->castTo<PackType>()->getNumElements();
13332
+ auto numParams = shape2->castTo<PackType>()->getNumElements();
13333
+
13334
+ // Drops `ApplyArgToParam` and left with `ApplyArgument`.
13335
+ path.pop_back();
13336
+
13337
+ auto *argListLoc = getConstraintLocator(anchor, path);
13338
+
13339
+ // Missing arguments.
13340
+ if (numParams > numArgs) {
13341
+ SmallVector<SynthesizedArg> synthesizedArgs;
13342
+ for (unsigned i = 0, n = numParams - numArgs; i != n; ++i) {
13343
+ auto eltTy = shape2->castTo<PackType>()->getElementType(i);
13344
+ synthesizedArgs.push_back(SynthesizedArg{
13345
+ argLoc.getParamIdx(), AnyFunctionType::Param(eltTy)});
13346
+ }
13347
+
13348
+ return recordShapeFix(
13349
+ AddMissingArguments::create(*this, synthesizedArgs, argListLoc),
13350
+ /*impact=*/2 * synthesizedArgs.size());
13351
+ } else {
13352
+ auto argIdx = argLoc.getArgIdx() + numParams;
13353
+ SmallVector<std::pair<unsigned, AnyFunctionType::Param>, 4>
13354
+ extraneousArgs;
13355
+
13356
+ for (unsigned i = 0, n = numArgs - numParams; i != n; ++i) {
13357
+ extraneousArgs.push_back(
13358
+ {argIdx + i, AnyFunctionType::Param(ctx.TheEmptyTupleType)});
13359
+ }
13360
+
13361
+ auto overload = findSelectedOverloadFor(getCalleeLocator(argListLoc));
13362
+ if (!overload)
13363
+ return SolutionKind::Error;
13364
+
13365
+ return recordShapeFix(
13366
+ RemoveExtraneousArguments::create(
13367
+ *this, overload->openedType->castTo<FunctionType>(),
13368
+ extraneousArgs, argListLoc),
13369
+ /*impact=*/2 * extraneousArgs.size());
13370
+ }
13371
+ }
13372
+ }
13373
+
13279
13374
unsigned impact = 1;
13280
13375
if (locator.endsWith<LocatorPathElt::AnyRequirement>())
13281
13376
impact = assessRequirementFailureImpact(*this, shape1, locator);
13282
13377
13283
- auto *fix = SkipSameShapeRequirement::create(*this, type1, type2,
13284
- getConstraintLocator(locator));
13285
- return recordFix(fix, impact) ? SolutionKind::Error : SolutionKind::Solved;
13378
+ return recordShapeFix(
13379
+ SkipSameShapeRequirement::create(*this, type1, type2,
13380
+ getConstraintLocator(locator)),
13381
+ impact);
13286
13382
}
13287
13383
13288
13384
return SolutionKind::Error;
0 commit comments