@@ -1228,6 +1228,10 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
12281228 llvm_unreachable (" Not a relational constraint" );
12291229 }
12301230
1231+ // Input types can be contravariant (or equal).
1232+ auto argumentLocator =
1233+ locator.withPathElement (ConstraintLocator::FunctionArgument);
1234+
12311235 TypeMatchOptions subflags = getDefaultDecompositionOptions (flags);
12321236
12331237 SmallVector<AnyFunctionType::Param, 8 > func1Params;
@@ -1254,8 +1258,23 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
12541258 auto implodeParams = [&](SmallVectorImpl<AnyFunctionType::Param> ¶ms) {
12551259 auto input = AnyFunctionType::composeInput (getASTContext (), params,
12561260 /* canonicalVararg=*/ false );
1261+
12571262 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);
12591278 };
12601279
12611280 {
@@ -1323,10 +1342,6 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
13231342 }
13241343 }
13251344
1326- // Input types can be contravariant (or equal).
1327- auto argumentLocator = locator.withPathElement (
1328- ConstraintLocator::FunctionArgument);
1329-
13301345 int diff = func1Params.size () - func2Params.size ();
13311346 if (diff != 0 ) {
13321347 if (!shouldAttemptFixes ())
@@ -1796,6 +1811,46 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
17961811
17971812 auto &elt = path.back ();
17981813 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+
17991854 case ConstraintLocator::TypeParameterRequirement:
18001855 case ConstraintLocator::ConditionalRequirement: {
18011856 if (auto *fix = fixRequirementFailure (cs, lhs, rhs, anchor, path))
@@ -5707,7 +5762,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
57075762
57085763 case FixKind::SkipSameTypeRequirement:
57095764 case FixKind::SkipSuperclassRequirement:
5710- case FixKind::ContextualMismatch: {
5765+ case FixKind::ContextualMismatch:
5766+ case FixKind::AddMissingArguments: {
57115767 return recordFix (fix) ? SolutionKind::Error : SolutionKind::Solved;
57125768 }
57135769
@@ -5723,7 +5779,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
57235779 case FixKind::AllowTypeOrInstanceMember:
57245780 case FixKind::AllowInvalidPartialApplication:
57255781 case FixKind::AllowInvalidInitRef:
5726- case FixKind::AddMissingArguments:
57275782 llvm_unreachable (" handled elsewhere" );
57285783 }
57295784
0 commit comments