@@ -3565,6 +3565,7 @@ bool ImplicitInitOnNonConstMetatypeFailure::diagnoseAsError() {
3565
3565
}
3566
3566
3567
3567
bool MissingArgumentsFailure::diagnoseAsError () {
3568
+ auto &cs = getConstraintSystem ();
3568
3569
auto *locator = getLocator ();
3569
3570
auto path = locator->getPath ();
3570
3571
@@ -3574,6 +3575,11 @@ bool MissingArgumentsFailure::diagnoseAsError() {
3574
3575
path.back ().getKind () == ConstraintLocator::ApplyArgument))
3575
3576
return false ;
3576
3577
3578
+ // If this is a misplaced `missng argument` situation, it would be
3579
+ // diagnosed by invalid conversion fix.
3580
+ if (isMisplacedMissingArgument (cs, locator))
3581
+ return false ;
3582
+
3577
3583
auto *anchor = getAnchor ();
3578
3584
if (auto *captureList = dyn_cast<CaptureListExpr>(anchor))
3579
3585
anchor = captureList->getClosureBody ();
@@ -3901,6 +3907,68 @@ bool MissingArgumentsFailure::isPropertyWrapperInitialization() const {
3901
3907
return NTD && NTD->getAttrs ().hasAttribute <PropertyWrapperAttr>();
3902
3908
}
3903
3909
3910
+ bool MissingArgumentsFailure::isMisplacedMissingArgument (
3911
+ ConstraintSystem &cs, ConstraintLocator *locator) {
3912
+ auto *calleeLocator = cs.getCalleeLocator (locator);
3913
+ auto overloadChoice = cs.findSelectedOverloadFor (calleeLocator);
3914
+ if (!overloadChoice)
3915
+ return false ;
3916
+
3917
+ auto *fnType =
3918
+ cs.simplifyType (overloadChoice->ImpliedType )->getAs <FunctionType>();
3919
+ if (!(fnType && fnType->getNumParams () == 2 ))
3920
+ return false ;
3921
+
3922
+ auto *anchor = locator->getAnchor ();
3923
+
3924
+ auto hasFixFor = [&](FixKind kind, ConstraintLocator *locator) -> bool {
3925
+ auto fix = llvm::find_if (cs.getFixes (), [&](const ConstraintFix *fix) {
3926
+ return fix->getLocator () == locator;
3927
+ });
3928
+
3929
+ if (fix == cs.getFixes ().end ())
3930
+ return false ;
3931
+
3932
+ return (*fix)->getKind () == kind;
3933
+ };
3934
+
3935
+ auto *callLocator =
3936
+ cs.getConstraintLocator (anchor, ConstraintLocator::ApplyArgument);
3937
+
3938
+ auto argFlags = fnType->getParams ()[0 ].getParameterFlags ();
3939
+ auto *argLoc = cs.getConstraintLocator (
3940
+ callLocator, LocatorPathElt::ApplyArgToParam (0 , 0 , argFlags));
3941
+
3942
+ if (!(hasFixFor (FixKind::AllowArgumentTypeMismatch, argLoc) &&
3943
+ hasFixFor (FixKind::AddMissingArguments, callLocator)))
3944
+ return false ;
3945
+
3946
+ Expr *argExpr = nullptr ;
3947
+ if (auto *call = dyn_cast<CallExpr>(anchor)) {
3948
+ argExpr = call->getArg ();
3949
+ } else if (auto *subscript = dyn_cast<SubscriptExpr>(anchor)) {
3950
+ argExpr = subscript->getIndex ();
3951
+ } else {
3952
+ return false ;
3953
+ }
3954
+
3955
+ Expr *argument = nullptr ;
3956
+ if (auto *PE = dyn_cast<ParenExpr>(argExpr)) {
3957
+ argument = PE->getSubExpr ();
3958
+ } else {
3959
+ auto *tuple = cast<TupleExpr>(argExpr);
3960
+ if (tuple->getNumElements () != 1 )
3961
+ return false ;
3962
+ argument = tuple->getElement (0 );
3963
+ }
3964
+
3965
+ auto argType = cs.simplifyType (cs.getType (argument));
3966
+ auto paramType = fnType->getParams ()[1 ].getPlainType ();
3967
+
3968
+ auto &TC = cs.getTypeChecker ();
3969
+ return TC.isConvertibleTo (argType, paramType, cs.DC );
3970
+ }
3971
+
3904
3972
bool ClosureParamDestructuringFailure::diagnoseAsError () {
3905
3973
auto *closure = cast<ClosureExpr>(getAnchor ());
3906
3974
auto params = closure->getParameters ();
@@ -4845,6 +4913,9 @@ void InOutConversionFailure::fixItChangeArgumentType() const {
4845
4913
}
4846
4914
4847
4915
bool ArgumentMismatchFailure::diagnoseAsError () {
4916
+ if (diagnoseMisplacedMissingArgument ())
4917
+ return true ;
4918
+
4848
4919
if (diagnoseConversionToBool ())
4849
4920
return true ;
4850
4921
@@ -5074,6 +5145,33 @@ bool ArgumentMismatchFailure::diagnoseArchetypeMismatch() const {
5074
5145
return true ;
5075
5146
}
5076
5147
5148
+ bool ArgumentMismatchFailure::diagnoseMisplacedMissingArgument () const {
5149
+ auto &cs = getConstraintSystem ();
5150
+ auto *locator = getLocator ();
5151
+
5152
+ if (!MissingArgumentsFailure::isMisplacedMissingArgument (cs, locator))
5153
+ return false ;
5154
+
5155
+ auto info = *getFunctionArgApplyInfo (locator);
5156
+
5157
+ auto *argType = cs.createTypeVariable (
5158
+ cs.getConstraintLocator (locator, LocatorPathElt::SynthesizedArgument (1 )),
5159
+ /* flags=*/ 0 );
5160
+
5161
+ // Assign new type variable to a type of a parameter.
5162
+ auto *fnType = info.getFnType ();
5163
+ const auto ¶m = fnType->getParams ()[0 ];
5164
+ cs.assignFixedType (argType, param.getOldType ());
5165
+
5166
+ auto *anchor = getRawAnchor ();
5167
+
5168
+ MissingArgumentsFailure failure (
5169
+ getParentExpr (), cs, {param.withType (argType)},
5170
+ cs.getConstraintLocator (anchor, ConstraintLocator::ApplyArgument));
5171
+
5172
+ return failure.diagnoseSingleMissingArgument ();
5173
+ }
5174
+
5077
5175
void ExpandArrayIntoVarargsFailure::tryDropArrayBracketsFixIt (
5078
5176
Expr *anchor) const {
5079
5177
// If this is an array literal, offer to remove the brackets and pass the
0 commit comments