@@ -1121,9 +1121,8 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
11211121 continue ;
11221122
11231123 // FIXME: Right now, a "matching" overload is one with a parameter whose
1124- // type is identical to the argument type, or substitutable via
1125- // rudimentary handling of functions with a single archetype in one or
1126- // more parameters.
1124+ // type is identical to the argument type, or substitutable via handling
1125+ // of functions with a single archetype in one or more parameters.
11271126 // We can still do something more sophisticated with this.
11281127 // FIXME: Use TC.isConvertibleTo?
11291128
@@ -1151,13 +1150,9 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
11511150 if (nonSubstitutableArgs == 0 )
11521151 continue ;
11531152 ++nonSubstitutableArgs;
1154- // Fallthrough, this is nonsubstitutable, so mismatches as well.
1153+ mismatchesAreNearMisses = false ;
11551154 } else {
1156- if (nonSubstitutableArgs == 0 ) {
1157- paramType = matchingArgType;
1158- // Fallthrough as mismatched arg, comparing nearness to archetype
1159- // bound type.
1160- } else if (nonSubstitutableArgs == 1 ) {
1155+ if (nonSubstitutableArgs == 1 ) {
11611156 // If we have only one nonSubstitutableArg so far, then this different
11621157 // type might be the one that we should be substituting for instead.
11631158 // Note that failureInfo is already set correctly for that case.
@@ -1167,23 +1162,37 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
11671162 continue ;
11681163 }
11691164 }
1165+
1166+ // This substitution doesn't match a previous substitution. Set up the nearMiss
1167+ // and failureInfo.paramType with the expected substitution inserted.
1168+ // (Note that this transform assumes only a single archetype.)
1169+ mismatchesAreNearMisses &= argumentMismatchIsNearMiss (substitution, matchingArgType);
1170+ paramType = paramType.transform (([&](Type type) -> Type {
1171+ if (type->is <SubstitutableType>())
1172+ return matchingArgType;
1173+ return type;
1174+ }));
11701175 }
11711176 } else {
11721177 matchingArgType = substitution;
11731178 singleArchetype = archetype;
11741179
1175- if (CS->TC .isSubstitutableFor (substitution, archetype, CS->DC )) {
1180+ if (CS->TC .isSubstitutableFor (substitution, archetype, CS->DC ))
11761181 continue ;
1177- }
1182+
1183+ if (auto argOptType = argType->getOptionalObjectType ())
1184+ mismatchesAreNearMisses &= CS->TC .isSubstitutableFor (argOptType, archetype, CS->DC );
1185+ else
1186+ mismatchesAreNearMisses = false ;
11781187 ++nonSubstitutableArgs;
11791188 }
1189+ } else {
1190+ // Keep track of whether this argument was a near miss or not.
1191+ mismatchesAreNearMisses &= argumentMismatchIsNearMiss (argType, paramType);
11801192 }
11811193
11821194 ++mismatchingArgs;
1183-
1184- // Keep track of whether this argument was a near miss or not.
1185- mismatchesAreNearMisses &= argumentMismatchIsNearMiss (argType, paramType);
1186-
1195+
11871196 failureInfo.argumentNumber = argNo;
11881197 failureInfo.parameterType = paramType;
11891198 if (paramType->hasTypeParameter ())
@@ -1196,7 +1205,8 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
11961205
11971206 // Check to see if the first argument expects an inout argument, but is not
11981207 // an lvalue.
1199- if (candArgs[0 ].Ty ->is <InOutType>() && !actualArgs[0 ].Ty ->isLValueType ())
1208+ Type firstArg = actualArgs[0 ].Ty ;
1209+ if (candArgs[0 ].Ty ->is <InOutType>() && !(firstArg->isLValueType () || firstArg->is <InOutType>()))
12001210 return { CC_NonLValueInOut, {}};
12011211
12021212 // If we have exactly one argument mismatching, classify it specially, so that
@@ -1588,14 +1598,28 @@ bool CalleeCandidateInfo::diagnoseGenericParameterErrors(Expr *badArgExpr) {
15881598
15891599 for (unsigned i = 0 , c = archetypes.size (); i < c; i++) {
15901600 auto archetype = archetypes[i];
1591- auto argType = substitutions[i];
1601+ auto substitution = substitutions[i];
15921602
15931603 // FIXME: Add specific error for not subclass, if the archetype has a superclass?
1604+
1605+ // Check for optional near miss.
1606+ if (auto argOptType = substitution->getOptionalObjectType ()) {
1607+ if (CS->TC .isSubstitutableFor (argOptType, archetype, CS->DC )) {
1608+ CS->TC .diagnose (badArgExpr->getLoc (), diag::missing_unwrap_optional, argType);
1609+ foundFailure = true ;
1610+ continue ;
1611+ }
1612+ }
15941613
15951614 for (auto proto : archetype->getConformsTo ()) {
1596- if (!CS->TC .conformsToProtocol (argType, proto, CS->DC , ConformanceCheckOptions (TR_InExpression))) {
1597- CS->TC .diagnose (badArgExpr->getLoc (), diag::cannot_convert_argument_value_protocol,
1598- argType, proto->getDeclaredType ());
1615+ if (!CS->TC .conformsToProtocol (substitution, proto, CS->DC , ConformanceCheckOptions (TR_InExpression))) {
1616+ if (substitution->isEqual (argType)) {
1617+ CS->TC .diagnose (badArgExpr->getLoc (), diag::cannot_convert_argument_value_protocol,
1618+ substitution, proto->getDeclaredType ());
1619+ } else {
1620+ CS->TC .diagnose (badArgExpr->getLoc (), diag::cannot_convert_partial_argument_value_protocol,
1621+ argType, substitution, proto->getDeclaredType ());
1622+ }
15991623 foundFailure = true ;
16001624 }
16011625 }
@@ -1647,7 +1671,11 @@ enum TCCFlags {
16471671 // / Re-type-check the given subexpression even if the expression has already
16481672 // / been checked already. The client is asserting that infinite recursion is
16491673 // / not possible because it has relaxed a constraint on the system.
1650- TCC_ForceRecheck = 0x02
1674+ TCC_ForceRecheck = 0x02 ,
1675+
1676+ // / tell typeCheckExpression that it is ok to produce an ambiguous result,
1677+ // / it can just fill in holes with UnresolvedType and we'll deal with it.
1678+ TCC_AllowUnresolvedTypeVariables = 0x04
16511679};
16521680
16531681typedef OptionSet<TCCFlags> TCCOptions;
@@ -1716,7 +1744,8 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
17161744
17171745 // / Special magic to handle inout exprs and tuples in argument lists.
17181746 Expr *typeCheckArgumentChildIndependently (Expr *argExpr, Type argType,
1719- const CalleeCandidateInfo &candidates);
1747+ const CalleeCandidateInfo &candidates,
1748+ TCCOptions options = TCCOptions());
17201749
17211750 // / Diagnose common failures due to applications of an argument list to an
17221751 // / ApplyExpr or SubscriptExpr.
@@ -2781,7 +2810,7 @@ typeCheckChildIndependently(Expr *subExpr, Type convertType,
27812810 // If there is no contextual type available, tell typeCheckExpression that it
27822811 // is ok to produce an ambiguous result, it can just fill in holes with
27832812 // UnresolvedType and we'll deal with it.
2784- if (!convertType)
2813+ if (!convertType || options. contains (TCC_AllowUnresolvedTypeVariables) )
27852814 TCEOptions |= TypeCheckExprFlags::AllowUnresolvedTypeVariables;
27862815
27872816 bool hadError = CS->TC .typeCheckExpression (subExpr, CS->DC , convertType,
@@ -3169,7 +3198,8 @@ void ConstraintSystem::diagnoseAssignmentFailure(Expr *dest, Type destTy,
31693198// / Special magic to handle inout exprs and tuples in argument lists.
31703199Expr *FailureDiagnosis::
31713200typeCheckArgumentChildIndependently (Expr *argExpr, Type argType,
3172- const CalleeCandidateInfo &candidates) {
3201+ const CalleeCandidateInfo &candidates,
3202+ TCCOptions options) {
31733203 // Grab one of the candidates (if present) and get its input list to help
31743204 // identify operators that have implicit inout arguments.
31753205 Type exampleInputType;
@@ -3203,7 +3233,6 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType,
32033233 if (!TE) {
32043234 // If the argument isn't a tuple, it is some scalar value for a
32053235 // single-argument call.
3206- TCCOptions options;
32073236 if (exampleInputType && exampleInputType->is <InOutType>())
32083237 options |= TCC_AllowLValue;
32093238
@@ -3276,7 +3305,6 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType,
32763305 unsigned inArgNo = sources[i];
32773306 auto actualType = argTypeTT->getElementType (i);
32783307
3279- TCCOptions options;
32803308 if (actualType->is <InOutType>())
32813309 options |= TCC_AllowLValue;
32823310
@@ -3341,7 +3369,6 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType,
33413369 exampleInputTuple = exampleInputType->getAs <TupleType>();
33423370
33433371 for (unsigned i = 0 , e = TE->getNumElements (); i != e; i++) {
3344- TCCOptions options;
33453372 if (exampleInputTuple && i < exampleInputTuple->getNumElements () &&
33463373 exampleInputTuple->getElementType (i)->is <InOutType>())
33473374 options |= TCC_AllowLValue;
@@ -3761,18 +3788,17 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
37613788 badArgExpr = argExpr;
37623789 }
37633790
3791+ // It could be that the argument doesn't conform to an archetype.
3792+ if (CCI.diagnoseGenericParameterErrors (badArgExpr))
3793+ return true ;
3794+
37643795 // Re-type-check the argument with the expected type of the candidate set.
37653796 // This should produce a specific and tailored diagnostic saying that the
37663797 // type mismatches with expectations.
37673798 Type paramType = CCI.failedArgument .parameterType ;
37683799 if (!typeCheckChildIndependently (badArgExpr, paramType,
37693800 CTP_CallArgument, options))
37703801 return true ;
3771-
3772- // If that fails, it could be that the argument doesn't conform to an
3773- // archetype.
3774- if (CCI.diagnoseGenericParameterErrors (badArgExpr))
3775- return true ;
37763802 }
37773803
37783804 return false ;
@@ -4059,8 +4085,9 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
40594085 // Get the expression result of type checking the arguments to the call
40604086 // independently, so we have some idea of what we're working with.
40614087 //
4062- auto argExpr = typeCheckArgumentChildIndependently (callExpr->getArg (),
4063- argType, calleeInfo);
4088+ auto argExpr = typeCheckArgumentChildIndependently (callExpr->getArg (), argType,
4089+ calleeInfo,
4090+ TCC_AllowUnresolvedTypeVariables);
40644091 if (!argExpr)
40654092 return true ; // already diagnosed.
40664093
@@ -4069,6 +4096,14 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
40694096 if (diagnoseParameterErrors (calleeInfo, callExpr->getFn (), argExpr))
40704097 return true ;
40714098
4099+ // Force recheck of the arg expression because we allowed unresolved types
4100+ // before, and that turned out not to help, and now we want any diagnoses
4101+ // from disallowing them.
4102+ argExpr = typeCheckArgumentChildIndependently (callExpr->getArg (), argType,
4103+ calleeInfo, TCC_ForceRecheck);
4104+ if (!argExpr)
4105+ return true ; // already diagnosed.
4106+
40724107 // Diagnose some simple and common errors.
40734108 if (calleeInfo.diagnoseSimpleErrors (callExpr->getLoc ()))
40744109 return true ;
0 commit comments