Skip to content

Commit cb876cb

Browse files
committed
[CSSimplify] CGFloat-Double: Rank narrowing correctly when result is injected into an optional
If result of `CGFloat` -> `Double` conversion is injected into an optional it should be ranked based on depth just like when locator is fully simplified. For example: ```swift func test(v: CGFloat?) { _ = v ?? 2.0 / 3.0 } ``` In this expression division should be performed on `Double` and result narrowed down (based on the rule that narrowing conversion should always be delayed) but `Double` -> `CGFloat?` was given an incorrect score and instead of picking `?? (_: T?, _: T) -> T` overload, the solver would use `?? (_: T?, _: T?) -> T?`.
1 parent b7e7493 commit cb876cb

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14690,9 +14690,19 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1469014690
restriction == ConversionRestrictionKind::CGFloatToDouble ? 2 : 10;
1469114691

1469214692
if (restriction == ConversionRestrictionKind::DoubleToCGFloat) {
14693-
if (auto *anchor = locator.trySimplifyToExpr()) {
14694-
if (auto depth = getExprDepth(anchor))
14695-
impact = (*depth + 1) * impact;
14693+
SmallVector<LocatorPathElt> originalPath;
14694+
auto anchor = locator.getLocatorParts(originalPath);
14695+
14696+
SourceRange range;
14697+
ArrayRef<LocatorPathElt> path(originalPath);
14698+
simplifyLocator(anchor, path, range);
14699+
14700+
if (path.empty() || llvm::all_of(path, [](const LocatorPathElt &elt) {
14701+
return elt.is<LocatorPathElt::OptionalPayload>();
14702+
})) {
14703+
if (auto *expr = getAsExpr(anchor))
14704+
if (auto depth = getExprDepth(expr))
14705+
impact = (*depth + 1) * impact;
1469614706
}
1469714707
} else if (locator.directlyAt<AssignExpr>() ||
1469814708
locator.endsWith<LocatorPathElt::ContextualType>()) {

0 commit comments

Comments
 (0)