Skip to content

Commit 0567900

Browse files
committed
[CSGen] Favor overload choices that support Double/CGFloat conversions (argument or result)
1 parent 000625f commit 0567900

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

lib/Sema/CSGen.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,11 @@ namespace {
381381
if (paramTy->isEqual(argTy))
382382
return true;
383383

384+
// Double and CGFloat types could be used interchangeably
385+
if ((argTy->isCGFloatType() || argTy->isDoubleType()) &&
386+
(paramTy->isDoubleType() || paramTy->isCGFloatType()))
387+
return true;
388+
384389
llvm::SmallSetVector<ProtocolDecl *, 2> literalProtos;
385390
if (auto argTypeVar = argTy->getAs<TypeVariableType>()) {
386391
auto constraints = CS.getConstraintGraph().gatherConstraints(
@@ -532,7 +537,23 @@ namespace {
532537

533538
return { nOperands, nNoDefault };
534539
}
535-
540+
541+
bool hasContextuallyFavorableResultType(AnyFunctionType *choice,
542+
Type contextualTy) {
543+
// No restrictions of what result could be.
544+
if (!contextualTy)
545+
return true;
546+
547+
auto resultTy = choice->getResult();
548+
// Result type of the call matches expected contextual type.
549+
if (contextualTy->isEqual(resultTy))
550+
return true;
551+
552+
// Double and CGFloat could be used interchangeably.
553+
return (resultTy->isDoubleType() || resultTy->isCGFloatType()) &&
554+
(contextualTy->isDoubleType() || contextualTy->isCGFloatType());
555+
}
556+
536557
/// Favor unary operator constraints where we have exact matches
537558
/// for the operand and contextual type.
538559
void favorMatchingUnaryOperators(ApplyExpr *expr,
@@ -545,15 +566,12 @@ namespace {
545566

546567
Type paramTy = FunctionType::composeInput(CS.getASTContext(),
547568
fnTy->getParams(), false);
548-
auto resultTy = fnTy->getResult();
549-
auto contextualTy = CS.getContextualType(expr);
550-
551569
return isFavoredParamAndArg(
552-
CS, paramTy,
553-
CS.getType(expr->getArg())->getWithoutParens()) &&
554-
(!contextualTy || contextualTy->isEqual(resultTy));
570+
CS, paramTy, CS.getType(expr->getArg())->getWithoutParens()) &&
571+
hasContextuallyFavorableResultType(fnTy,
572+
CS.getContextualType(expr));
555573
};
556-
574+
557575
favorCallOverloads(expr, CS, isFavoredDecl);
558576
}
559577

@@ -704,15 +722,14 @@ namespace {
704722
auto firstParamTy = params[0].getOldType();
705723
auto secondParamTy = params[1].getOldType();
706724

707-
auto resultTy = fnTy->getResult();
708725
auto contextualTy = CS.getContextualType(expr);
709726

710727
return (isFavoredParamAndArg(CS, firstParamTy, firstArgTy, secondArgTy) ||
711728
isFavoredParamAndArg(CS, secondParamTy, secondArgTy,
712729
firstArgTy)) &&
713730
firstParamTy->isEqual(secondParamTy) &&
714731
!isPotentialForcingOpportunity(firstArgTy, secondArgTy) &&
715-
(!contextualTy || contextualTy->isEqual(resultTy));
732+
hasContextuallyFavorableResultType(fnTy, contextualTy);
716733
};
717734

718735
favorCallOverloads(expr, CS, isFavoredDecl);

0 commit comments

Comments
 (0)