@@ -1228,6 +1228,10 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
1228
1228
llvm_unreachable (" Not a relational constraint" );
1229
1229
}
1230
1230
1231
+ // Input types can be contravariant (or equal).
1232
+ auto argumentLocator =
1233
+ locator.withPathElement (ConstraintLocator::FunctionArgument);
1234
+
1231
1235
TypeMatchOptions subflags = getDefaultDecompositionOptions (flags);
1232
1236
1233
1237
SmallVector<AnyFunctionType::Param, 8 > func1Params;
@@ -1254,8 +1258,23 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
1254
1258
auto implodeParams = [&](SmallVectorImpl<AnyFunctionType::Param> ¶ms) {
1255
1259
auto input = AnyFunctionType::composeInput (getASTContext (), params,
1256
1260
/* canonicalVararg=*/ false );
1261
+
1257
1262
params.clear ();
1258
- params.emplace_back (input);
1263
+ // If fixes are disabled let's do an easy thing and implode
1264
+ // tuple directly into parameters list.
1265
+ if (!shouldAttemptFixes ()) {
1266
+ params.emplace_back (input);
1267
+ return ;
1268
+ }
1269
+
1270
+ // Synthesize new argument and bind it to tuple formed from existing
1271
+ // arguments, this makes it easier to diagnose cases where we attempt
1272
+ // a single tuple element formed when no arguments were present.
1273
+ auto argLoc = argumentLocator.withPathElement (
1274
+ LocatorPathElt::getSynthesizedArgument (0 ));
1275
+ auto *typeVar = createTypeVariable (getConstraintLocator (argLoc));
1276
+ params.emplace_back (typeVar);
1277
+ assignFixedType (typeVar, input);
1259
1278
};
1260
1279
1261
1280
{
@@ -1323,10 +1342,6 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
1323
1342
}
1324
1343
}
1325
1344
1326
- // Input types can be contravariant (or equal).
1327
- auto argumentLocator = locator.withPathElement (
1328
- ConstraintLocator::FunctionArgument);
1329
-
1330
1345
int diff = func1Params.size () - func2Params.size ();
1331
1346
if (diff != 0 ) {
1332
1347
if (!shouldAttemptFixes ())
@@ -1796,6 +1811,46 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
1796
1811
1797
1812
auto &elt = path.back ();
1798
1813
switch (elt.getKind ()) {
1814
+ case ConstraintLocator::FunctionArgument: {
1815
+ auto *argLoc = cs.getConstraintLocator (
1816
+ locator.withPathElement (LocatorPathElt::getSynthesizedArgument (0 )));
1817
+
1818
+ // Let's drop the last element which points to a single argument
1819
+ // and see if this is a contextual mismatch.
1820
+ path.pop_back ();
1821
+ if (path.empty () ||
1822
+ !(path.back ().getKind () == ConstraintLocator::ApplyArgToParam ||
1823
+ path.back ().getKind () == ConstraintLocator::ContextualType))
1824
+ return ;
1825
+
1826
+ auto arg = llvm::find_if (cs.getTypeVariables (),
1827
+ [&argLoc](const TypeVariableType *typeVar) {
1828
+ return typeVar->getImpl ().getLocator () == argLoc;
1829
+ });
1830
+
1831
+ // What we have here is a form or tuple splat with no arguments
1832
+ // demonstrated by following example:
1833
+ //
1834
+ // func foo<T: P>(_: T, _: (T.Element) -> Int) {}
1835
+ // foo { 42 }
1836
+ //
1837
+ // In cases like this `T.Element` might be resolved to `Void`
1838
+ // which means that we have to try a single empty tuple argument
1839
+ // as a narrow exception to SE-0110, see `matchFunctionTypes`.
1840
+ //
1841
+ // But if `T.Element` didn't get resolved to `Void` we'd like
1842
+ // to diagnose this as a missing argument which can't be ignored.
1843
+ if (arg != cs.getTypeVariables ().end ()) {
1844
+ auto fnType = FunctionType::get ({FunctionType::Param (lhs)},
1845
+ cs.getASTContext ().TheEmptyTupleType );
1846
+ conversionsOrFixes.push_back (AddMissingArguments::create (
1847
+ cs, fnType, {FunctionType::Param (*arg)},
1848
+ cs.getConstraintLocator (anchor, path,
1849
+ /* summaryFlags=*/ 0 )));
1850
+ }
1851
+ break ;
1852
+ }
1853
+
1799
1854
case ConstraintLocator::TypeParameterRequirement:
1800
1855
case ConstraintLocator::ConditionalRequirement: {
1801
1856
if (auto *fix = fixRequirementFailure (cs, lhs, rhs, anchor, path))
@@ -5707,7 +5762,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
5707
5762
5708
5763
case FixKind::SkipSameTypeRequirement:
5709
5764
case FixKind::SkipSuperclassRequirement:
5710
- case FixKind::ContextualMismatch: {
5765
+ case FixKind::ContextualMismatch:
5766
+ case FixKind::AddMissingArguments: {
5711
5767
return recordFix (fix) ? SolutionKind::Error : SolutionKind::Solved;
5712
5768
}
5713
5769
@@ -5723,7 +5779,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
5723
5779
case FixKind::AllowTypeOrInstanceMember:
5724
5780
case FixKind::AllowInvalidPartialApplication:
5725
5781
case FixKind::AllowInvalidInitRef:
5726
- case FixKind::AddMissingArguments:
5727
5782
llvm_unreachable (" handled elsewhere" );
5728
5783
}
5729
5784
0 commit comments