@@ -370,22 +370,36 @@ static void determineBestChoicesInContext(
370370 FunctionType::relabelParams (argsWithLabels, argumentList);
371371 }
372372
373- SmallVector<SmallVector<std::pair<Type, /* fromLiteral=*/ bool >, 2 >, 2 >
374- candidateArgumentTypes;
375- candidateArgumentTypes.resize (argFuncType->getNumParams ());
373+ struct ArgumentCandidate {
374+ Type type;
375+ // The candidate type is derived from a literal expression.
376+ bool fromLiteral : 1 ;
377+ // The candidate type is derived from a call to an
378+ // initializer i.e. `Double(...)`.
379+ bool fromInitializerCall : 1 ;
380+
381+ ArgumentCandidate (Type type, bool fromLiteral = false ,
382+ bool fromInitializerCall = false )
383+ : type(type), fromLiteral(fromLiteral),
384+ fromInitializerCall (fromInitializerCall) {}
385+ };
386+
387+ SmallVector<SmallVector<ArgumentCandidate, 2 >, 2 >
388+ argumentCandidates;
389+ argumentCandidates.resize(argFuncType->getNumParams ());
376390
377391 llvm::TinyPtrVector<Type> resultTypes;
378392
379393 for (unsigned i = 0 , n = argFuncType->getNumParams (); i != n; ++i) {
380394 const auto ¶m = argFuncType->getParams ()[i];
381395 auto argType = cs.simplifyType (param.getPlainType ());
382396
383- SmallVector<std::pair<Type, bool > , 2 > types;
397+ SmallVector<ArgumentCandidate , 2 > types;
384398 if (auto *typeVar = argType->getAs <TypeVariableType>()) {
385399 auto bindingSet = cs.getBindingsFor (typeVar);
386400
387401 for (const auto &binding : bindingSet.Bindings ) {
388- types.push_back ({binding.BindingType , /* fromLiteral= */ false });
402+ types.push_back ({binding.BindingType });
389403 }
390404
391405 for (const auto &literal : bindingSet.Literals ) {
@@ -408,15 +422,16 @@ static void determineBestChoicesInContext(
408422 if (auto *typeExpr = dyn_cast<TypeExpr>(call->getFn ())) {
409423 auto instanceTy = cs.getType (typeExpr)->getMetatypeInstanceType ();
410424 if (instanceTy->isDouble () || instanceTy->isCGFloat ())
411- types.push_back ({instanceTy, /* fromLiteral=*/ false });
425+ types.push_back ({instanceTy, /* fromLiteral=*/ false ,
426+ /* fromInitializerCall=*/ true });
412427 }
413428 }
414429 }
415430 } else {
416431 types.push_back ({argType, /* fromLiteral=*/ false });
417432 }
418433
419- candidateArgumentTypes [i].append (types);
434+ argumentCandidates [i].append (types);
420435 }
421436
422437 auto resultType = cs.simplifyType(argFuncType->getResult ());
@@ -437,9 +452,9 @@ static void determineBestChoicesInContext(
437452 argFuncType->getNumParams () > 0 &&
438453 llvm::none_of(
439454 indices (argFuncType->getParams ()), [&](const unsigned argIdx) {
440- auto &candidates = candidateArgumentTypes [argIdx];
455+ auto &candidates = argumentCandidates [argIdx];
441456 return llvm::any_of (candidates, [&](const auto &candidate) {
442- return !candidate.second ;
457+ return !candidate.fromLiteral ;
443458 });
444459 });
445460
@@ -846,7 +861,7 @@ static void determineBestChoicesInContext(
846861 auto argIdx = argIndices.front ();
847862
848863 // Looks like there is nothing know about the argument.
849- if (candidateArgumentTypes [argIdx].empty ())
864+ if (argumentCandidates [argIdx].empty ())
850865 continue ;
851866
852867 const auto paramFlags = param.getParameterFlags ();
@@ -873,32 +888,25 @@ static void determineBestChoicesInContext(
873888 // at this parameter position and remove the overload choice
874889 // from consideration.
875890 double bestCandidateScore = 0 ;
876- llvm::BitVector mismatches (candidateArgumentTypes [argIdx].size ());
891+ llvm::BitVector mismatches (argumentCandidates [argIdx].size ());
877892
878893 for (unsigned candidateIdx :
879- indices (candidateArgumentTypes [argIdx])) {
894+ indices (argumentCandidates [argIdx])) {
880895 // If one of the candidates matched exactly there is no reason
881896 // to continue checking.
882897 if (bestCandidateScore == 1 )
883898 break ;
884899
885- Type candidateType;
886- bool isLiteralDefault;
887-
888- std::tie (candidateType, isLiteralDefault) =
889- candidateArgumentTypes[argIdx][candidateIdx];
900+ auto candidate = argumentCandidates[argIdx][candidateIdx];
890901
891902 // `inout` parameter accepts only l-value argument.
892- if (paramFlags.isInOut () && !candidateType ->is <LValueType>()) {
903+ if (paramFlags.isInOut () && !candidate. type ->is <LValueType>()) {
893904 mismatches.set (candidateIdx);
894905 continue ;
895906 }
896907
897- // The specifier only matters for `inout` check.
898- candidateType = candidateType->getWithoutSpecifierType ();
899-
900908 MatchOptions options (MatchFlag::OnParam);
901- if (isLiteralDefault )
909+ if (candidate. fromLiteral )
902910 options |= MatchFlag::Literal;
903911 if (favorExactMatchesOnly)
904912 options |= MatchFlag::ExactOnly;
@@ -913,8 +921,16 @@ static void determineBestChoicesInContext(
913921 if (n == 1 && decl->isOperator ())
914922 options |= MatchFlag::DisableCGFloatDoubleConversion;
915923
924+ // Disable implicit CGFloat -> Double widening conversion if
925+ // argument is an explicit call to `CGFloat` initializer.
926+ if (candidate.type ->isCGFloat () &&
927+ candidate.fromInitializerCall )
928+ options |= MatchFlag::DisableCGFloatDoubleConversion;
929+
930+ // The specifier for a candidate only matters for `inout` check.
916931 auto candidateScore = scoreCandidateMatch (
917- genericSig, decl, candidateType, paramType, options);
932+ genericSig, decl, candidate.type ->getWithoutSpecifierType (),
933+ paramType, options);
918934
919935 if (!candidateScore)
920936 continue ;
@@ -928,7 +944,7 @@ static void determineBestChoicesInContext(
928944 // Only established arguments could be considered mismatches,
929945 // literal default types should be regarded as holes if they
930946 // didn't match.
931- if (!isLiteralDefault && !candidateType ->hasTypeVariable ())
947+ if (!candidate. fromLiteral && !candidate. type ->hasTypeVariable ())
932948 mismatches.set (candidateIdx);
933949 }
934950
0 commit comments