@@ -370,22 +370,36 @@ static void determineBestChoicesInContext(
370
370
FunctionType::relabelParams (argsWithLabels, argumentList);
371
371
}
372
372
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 ());
376
390
377
391
llvm::TinyPtrVector<Type> resultTypes;
378
392
379
393
for (unsigned i = 0 , n = argFuncType->getNumParams (); i != n; ++i) {
380
394
const auto ¶m = argFuncType->getParams ()[i];
381
395
auto argType = cs.simplifyType (param.getPlainType ());
382
396
383
- SmallVector<std::pair<Type, bool > , 2 > types;
397
+ SmallVector<ArgumentCandidate , 2 > types;
384
398
if (auto *typeVar = argType->getAs <TypeVariableType>()) {
385
399
auto bindingSet = cs.getBindingsFor (typeVar);
386
400
387
401
for (const auto &binding : bindingSet.Bindings ) {
388
- types.push_back ({binding.BindingType , /* fromLiteral= */ false });
402
+ types.push_back ({binding.BindingType });
389
403
}
390
404
391
405
for (const auto &literal : bindingSet.Literals ) {
@@ -408,15 +422,16 @@ static void determineBestChoicesInContext(
408
422
if (auto *typeExpr = dyn_cast<TypeExpr>(call->getFn ())) {
409
423
auto instanceTy = cs.getType (typeExpr)->getMetatypeInstanceType ();
410
424
if (instanceTy->isDouble () || instanceTy->isCGFloat ())
411
- types.push_back ({instanceTy, /* fromLiteral=*/ false });
425
+ types.push_back ({instanceTy, /* fromLiteral=*/ false ,
426
+ /* fromInitializerCall=*/ true });
412
427
}
413
428
}
414
429
}
415
430
} else {
416
431
types.push_back ({argType, /* fromLiteral=*/ false });
417
432
}
418
433
419
- candidateArgumentTypes [i].append (types);
434
+ argumentCandidates [i].append (types);
420
435
}
421
436
422
437
auto resultType = cs.simplifyType(argFuncType->getResult ());
@@ -437,9 +452,9 @@ static void determineBestChoicesInContext(
437
452
argFuncType->getNumParams () > 0 &&
438
453
llvm::none_of(
439
454
indices (argFuncType->getParams ()), [&](const unsigned argIdx) {
440
- auto &candidates = candidateArgumentTypes [argIdx];
455
+ auto &candidates = argumentCandidates [argIdx];
441
456
return llvm::any_of (candidates, [&](const auto &candidate) {
442
- return !candidate.second ;
457
+ return !candidate.fromLiteral ;
443
458
});
444
459
});
445
460
@@ -846,7 +861,7 @@ static void determineBestChoicesInContext(
846
861
auto argIdx = argIndices.front ();
847
862
848
863
// Looks like there is nothing know about the argument.
849
- if (candidateArgumentTypes [argIdx].empty ())
864
+ if (argumentCandidates [argIdx].empty ())
850
865
continue ;
851
866
852
867
const auto paramFlags = param.getParameterFlags ();
@@ -873,32 +888,25 @@ static void determineBestChoicesInContext(
873
888
// at this parameter position and remove the overload choice
874
889
// from consideration.
875
890
double bestCandidateScore = 0 ;
876
- llvm::BitVector mismatches (candidateArgumentTypes [argIdx].size ());
891
+ llvm::BitVector mismatches (argumentCandidates [argIdx].size ());
877
892
878
893
for (unsigned candidateIdx :
879
- indices (candidateArgumentTypes [argIdx])) {
894
+ indices (argumentCandidates [argIdx])) {
880
895
// If one of the candidates matched exactly there is no reason
881
896
// to continue checking.
882
897
if (bestCandidateScore == 1 )
883
898
break ;
884
899
885
- Type candidateType;
886
- bool isLiteralDefault;
887
-
888
- std::tie (candidateType, isLiteralDefault) =
889
- candidateArgumentTypes[argIdx][candidateIdx];
900
+ auto candidate = argumentCandidates[argIdx][candidateIdx];
890
901
891
902
// `inout` parameter accepts only l-value argument.
892
- if (paramFlags.isInOut () && !candidateType ->is <LValueType>()) {
903
+ if (paramFlags.isInOut () && !candidate. type ->is <LValueType>()) {
893
904
mismatches.set (candidateIdx);
894
905
continue ;
895
906
}
896
907
897
- // The specifier only matters for `inout` check.
898
- candidateType = candidateType->getWithoutSpecifierType ();
899
-
900
908
MatchOptions options (MatchFlag::OnParam);
901
- if (isLiteralDefault )
909
+ if (candidate. fromLiteral )
902
910
options |= MatchFlag::Literal;
903
911
if (favorExactMatchesOnly)
904
912
options |= MatchFlag::ExactOnly;
@@ -913,8 +921,16 @@ static void determineBestChoicesInContext(
913
921
if (n == 1 && decl->isOperator ())
914
922
options |= MatchFlag::DisableCGFloatDoubleConversion;
915
923
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.
916
931
auto candidateScore = scoreCandidateMatch (
917
- genericSig, decl, candidateType, paramType, options);
932
+ genericSig, decl, candidate.type ->getWithoutSpecifierType (),
933
+ paramType, options);
918
934
919
935
if (!candidateScore)
920
936
continue ;
@@ -928,7 +944,7 @@ static void determineBestChoicesInContext(
928
944
// Only established arguments could be considered mismatches,
929
945
// literal default types should be regarded as holes if they
930
946
// didn't match.
931
- if (!isLiteralDefault && !candidateType ->hasTypeVariable ())
947
+ if (!candidate. fromLiteral && !candidate. type ->hasTypeVariable ())
932
948
mismatches.set (candidateIdx);
933
949
}
934
950
0 commit comments