Skip to content

Commit fbeca3d

Browse files
committed
[CSBindings] Prefer Double over CGFloat bindings
Always prefer binding to `Double` over `CGFloat` if possible since there is an implicit conversion between them and attempting both could lead to ambiguities.
1 parent c77d086 commit fbeca3d

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,39 @@ void BindingSet::addBinding(PotentialBinding binding) {
510510
}
511511
}
512512

513+
// Since Double and CGFloat are effectively the same type due to an
514+
// implicit conversion between them, always prefer Double over CGFloat
515+
// when possible.
516+
//
517+
// Note: This optimization can't be performed for closure parameters
518+
// because their type could be converted only at the point of
519+
// use in the closure body.
520+
if (!TypeVar->getImpl().isClosureParameterType()) {
521+
auto type = binding.BindingType;
522+
523+
if (type->isCGFloatType() &&
524+
llvm::any_of(Bindings, [](const PotentialBinding &binding) {
525+
return binding.BindingType->isDoubleType();
526+
}))
527+
return;
528+
529+
if (type->isDoubleType()) {
530+
auto inferredCGFloat =
531+
llvm::find_if(Bindings, [](const PotentialBinding &binding) {
532+
return binding.BindingType->isCGFloatType();
533+
});
534+
535+
// TODO: If CGFloat has been already inferred, we can't simply remove it
536+
// because that would break supertype join logic - index stored in
537+
// `lastSupertypeIndex` would get invalidated. Instead let's replace type
538+
// of an existing binding with Double.
539+
if (inferredCGFloat != Bindings.end()) {
540+
inferredCGFloat->BindingType = type;
541+
return;
542+
}
543+
}
544+
}
545+
513546
// If this is a non-defaulted supertype binding,
514547
// check whether we can combine it with another
515548
// supertype binding by computing the 'join' of the types.

0 commit comments

Comments
 (0)