@@ -381,9 +381,13 @@ namespace {
381
381
if (paramTy->isEqual (argTy))
382
382
return true ;
383
383
384
- // Double and CGFloat types could be used interchangeably
385
- if ((argTy->isCGFloatType () || argTy->isDoubleType ()) &&
386
- (paramTy->isDoubleType () || paramTy->isCGFloatType ()))
384
+ // Don't favor narrowing conversions.
385
+ if (argTy->isDoubleType () && paramTy->isCGFloatType ())
386
+ return false ;
387
+
388
+ // CGFloat could be passed to a Double parameter and that's
389
+ // is either equivalent of widening conversion.
390
+ if (argTy->isCGFloatType () && paramTy->isDoubleType ())
387
391
return true ;
388
392
389
393
llvm::SmallSetVector<ProtocolDecl *, 2 > literalProtos;
@@ -549,9 +553,9 @@ namespace {
549
553
if (contextualTy->isEqual (resultTy))
550
554
return true ;
551
555
552
- // Double and CGFloat could be used interchangeably.
553
- return (resultTy-> isDoubleType () || resultTy-> isCGFloatType ()) &&
554
- (contextualTy-> isDoubleType () || contextualTy->isCGFloatType () );
556
+ // Double and CGFloat could be used interchangeably, so let's
557
+ // favor widening conversion going from CGFloat to Double.
558
+ return resultTy-> isCGFloatType () && contextualTy->isDoubleType ( );
555
559
}
556
560
557
561
// / Favor unary operator constraints where we have exact matches
@@ -566,8 +570,19 @@ namespace {
566
570
567
571
Type paramTy = FunctionType::composeInput (CS.getASTContext (),
568
572
fnTy->getParams (), false );
569
- return isFavoredParamAndArg (
570
- CS, paramTy, CS.getType (expr->getArg ())->getWithoutParens ()) &&
573
+
574
+ auto argTy = CS.getType (expr->getArg ())
575
+ ->getWithoutParens ()
576
+ ->getWithoutSpecifierType ();
577
+
578
+ // There is no CGFloat overloads on some of the unary operators, so
579
+ // in order to preserve current behavior let's not favor overloads
580
+ // which would result in conversion from CGFloat to Double otherwise
581
+ // it would lead to ambiguities.
582
+ if (argTy->isCGFloatType () && paramTy->isDoubleType ())
583
+ return false ;
584
+
585
+ return isFavoredParamAndArg (CS, paramTy, argTy) &&
571
586
hasContextuallyFavorableResultType (fnTy,
572
587
CS.getContextualType (expr));
573
588
};
@@ -724,6 +739,16 @@ namespace {
724
739
725
740
auto contextualTy = CS.getContextualType (expr);
726
741
742
+ // Avoid favoring overloads that would require narrowing conversion
743
+ // to match the arguments.
744
+ {
745
+ if (firstArgTy->isDoubleType () && firstParamTy->isCGFloatType ())
746
+ return false ;
747
+
748
+ if (secondArgTy->isDoubleType () && secondParamTy->isCGFloatType ())
749
+ return false ;
750
+ }
751
+
727
752
return (isFavoredParamAndArg (CS, firstParamTy, firstArgTy, secondArgTy) ||
728
753
isFavoredParamAndArg (CS, secondParamTy, secondArgTy,
729
754
firstArgTy)) &&
0 commit comments