@@ -590,7 +590,14 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
590
590
if (paramInfo.hasDefaultArgument (paramIdx))
591
591
continue ;
592
592
593
- listener.missingArgument (paramIdx);
593
+ if (potentiallyOutOfOrder)
594
+ return true ;
595
+
596
+ if (auto newArgIdx = listener.missingArgument (paramIdx)) {
597
+ parameterBindings[paramIdx].push_back (*newArgIdx);
598
+ continue ;
599
+ }
600
+
594
601
return true ;
595
602
}
596
603
}
@@ -790,20 +797,58 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
790
797
791
798
class ArgumentFailureTracker : public MatchCallArgumentListener {
792
799
ConstraintSystem &CS;
793
- ArrayRef <AnyFunctionType::Param> Arguments;
800
+ SmallVectorImpl <AnyFunctionType::Param> & Arguments;
794
801
ArrayRef<AnyFunctionType::Param> Parameters;
795
802
SmallVectorImpl<ParamBinding> &Bindings;
796
803
ConstraintLocatorBuilder Locator;
797
804
805
+ unsigned NumSynthesizedArgs = 0 ;
806
+
798
807
public:
799
808
ArgumentFailureTracker (ConstraintSystem &cs,
800
- ArrayRef <AnyFunctionType::Param> args,
809
+ SmallVectorImpl <AnyFunctionType::Param> & args,
801
810
ArrayRef<AnyFunctionType::Param> params,
802
811
SmallVectorImpl<ParamBinding> &bindings,
803
812
ConstraintLocatorBuilder locator)
804
813
: CS(cs), Arguments(args), Parameters(params), Bindings(bindings),
805
814
Locator (locator) {}
806
815
816
+ ~ArgumentFailureTracker () override {
817
+ if (NumSynthesizedArgs > 0 ) {
818
+ ArrayRef<AnyFunctionType::Param> argRef (Arguments);
819
+
820
+ auto *fix =
821
+ AddMissingArguments::create (CS, argRef.take_back (NumSynthesizedArgs),
822
+ CS.getConstraintLocator (Locator));
823
+
824
+ // Not having an argument is the same impact as having a type mismatch.
825
+ (void )CS.recordFix (fix, /* impact=*/ NumSynthesizedArgs * 2 );
826
+ }
827
+ }
828
+
829
+ Optional<unsigned > missingArgument (unsigned paramIdx) override {
830
+ if (!CS.shouldAttemptFixes ())
831
+ return None;
832
+
833
+ const auto ¶m = Parameters[paramIdx];
834
+
835
+ unsigned newArgIdx = Arguments.size ();
836
+ auto argLoc =
837
+ Locator
838
+ .withPathElement (
839
+ LocatorPathElt::ApplyArgToParam (newArgIdx, paramIdx))
840
+ .withPathElement (LocatorPathElt::SynthesizedArgument (newArgIdx));
841
+
842
+ auto *argType = CS.createTypeVariable (
843
+ CS.getConstraintLocator (argLoc),
844
+ TVO_CanBindToInOut | TVO_CanBindToLValue | TVO_CanBindToNoEscape);
845
+
846
+ Arguments.push_back (param.withType (argType));
847
+ ++NumSynthesizedArgs;
848
+
849
+ return newArgIdx;
850
+ }
851
+
807
852
bool missingLabel (unsigned paramIndex) override {
808
853
return !CS.shouldAttemptFixes ();
809
854
}
@@ -883,19 +928,19 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
883
928
884
929
// Match up the call arguments to the parameters.
885
930
SmallVector<ParamBinding, 4 > parameterBindings;
886
- ArgumentFailureTracker listener (cs, argsWithLabels, params, parameterBindings,
887
- locator);
888
- if (constraints::matchCallArguments (argsWithLabels, params,
889
- paramInfo,
890
- hasTrailingClosure,
891
- cs.shouldAttemptFixes (), listener,
892
- parameterBindings)) {
893
- if (!cs.shouldAttemptFixes ())
894
- return cs.getTypeMatchFailure (locator);
931
+ {
932
+ ArgumentFailureTracker listener (cs, argsWithLabels, params,
933
+ parameterBindings, locator);
934
+ if (constraints::matchCallArguments (
935
+ argsWithLabels, params, paramInfo, hasTrailingClosure,
936
+ cs.shouldAttemptFixes (), listener, parameterBindings)) {
937
+ if (!cs.shouldAttemptFixes ())
938
+ return cs.getTypeMatchFailure (locator);
895
939
896
- if (AllowTupleSplatForSingleParameter::attempt (cs, argsWithLabels, params,
897
- parameterBindings, locator))
898
- return cs.getTypeMatchFailure (locator);
940
+ if (AllowTupleSplatForSingleParameter::attempt (
941
+ cs, argsWithLabels, params, parameterBindings, locator))
942
+ return cs.getTypeMatchFailure (locator);
943
+ }
899
944
}
900
945
901
946
// If this application is part of an operator, then we allow an implicit
@@ -904,6 +949,15 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
904
949
auto *anchor = locator.getAnchor ();
905
950
assert (anchor && " locator without anchor expression?" );
906
951
952
+ auto isSynthesizedArgument = [](const AnyFunctionType::Param &arg) -> bool {
953
+ if (auto *typeVar = arg.getPlainType ()->getAs <TypeVariableType>()) {
954
+ auto *locator = typeVar->getImpl ().getLocator ();
955
+ return locator->isLastElement (ConstraintLocator::SynthesizedArgument);
956
+ }
957
+
958
+ return false ;
959
+ };
960
+
907
961
for (unsigned paramIdx = 0 , numParams = parameterBindings.size ();
908
962
paramIdx != numParams; ++paramIdx){
909
963
// Skip unfulfilled parameters. There's nothing to do for them.
@@ -918,10 +972,11 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
918
972
for (auto argIdx : parameterBindings[paramIdx]) {
919
973
auto loc = locator.withPathElement (LocatorPathElt::ApplyArgToParam (
920
974
argIdx, paramIdx, param.getParameterFlags ()));
921
- auto argTy = argsWithLabels[argIdx].getOldType ();
975
+ const auto &argument = argsWithLabels[argIdx];
976
+ auto argTy = argument.getOldType ();
922
977
923
978
bool matchingAutoClosureResult = param.isAutoClosure ();
924
- if (param.isAutoClosure ()) {
979
+ if (param.isAutoClosure () && ! isSynthesizedArgument (argument) ) {
925
980
auto &ctx = cs.getASTContext ();
926
981
auto *fnType = paramTy->castTo <FunctionType>();
927
982
auto *argExpr = getArgumentExpr (locator.getAnchor (), argIdx);
@@ -960,7 +1015,11 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
960
1015
// If argument comes for declaration it should loose
961
1016
// `@autoclosure` flag, because in context it's used
962
1017
// as a function type represented by autoclosure.
963
- assert (!argsWithLabels[argIdx].isAutoClosure ());
1018
+ //
1019
+ // Special case here are synthesized arguments because
1020
+ // they mirror parameter flags to ease diagnosis.
1021
+ assert (!argsWithLabels[argIdx].isAutoClosure () ||
1022
+ isSynthesizedArgument (argument));
964
1023
965
1024
cs.addConstraint (
966
1025
subKind, argTy, paramTy,
0 commit comments