Skip to content

Commit 7cc6892

Browse files
committed
[CSApply] Adjust locator while coercion source of assignment to destination type
Constraint generator records conversion between source and destination types as anchored on an assignment, which means that coercion has to do the same in case restrictions (like Double<->CGFloat conversion) depend on locators to retrieve information for the solution.
1 parent 074035b commit 7cc6892

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

lib/Sema/CSApply.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4310,9 +4310,12 @@ namespace {
43104310
Expr *visitAssignExpr(AssignExpr *expr) {
43114311
// Convert the source to the simplified destination type.
43124312
auto destTy = simplifyType(cs.getType(expr->getDest()));
4313-
auto locator =
4314-
ConstraintLocatorBuilder(cs.getConstraintLocator(expr->getSrc()));
4315-
Expr *src = coerceToType(expr->getSrc(), destTy->getRValueType(), locator);
4313+
// Conversion is recorded as anchored on an assignment itself by
4314+
// constraint generator and that has to be preserved here in case
4315+
// anything depends on the locator (i.e. Double<->CGFloat implicit
4316+
// conversion).
4317+
Expr *src = coerceToType(expr->getSrc(), destTy->getRValueType(),
4318+
cs.getConstraintLocator(expr));
43164319
if (!src)
43174320
return nullptr;
43184321

@@ -6757,6 +6760,11 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
67576760
auto *argExpr = locator.trySimplifyToExpr();
67586761
assert(argExpr);
67596762

6763+
// Source requires implicit conversion to match destination
6764+
// type but the conversion itself is recorded on assignment.
6765+
if (auto *assignment = dyn_cast<AssignExpr>(argExpr))
6766+
argExpr = assignment->getSrc();
6767+
67606768
// Load the value for conversion.
67616769
argExpr = cs.coerceToRValue(argExpr);
67626770

test/Constraints/implicit_double_cgfloat_conversion.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,16 @@ func test_collection_literals_as_call_arguments() {
247247
cont.prop = .test_dict_nested(["": ["": point.x]]) // Ok
248248
}
249249
}
250+
251+
func assignments_with_and_without_optionals() {
252+
class C {
253+
var prop: CGFloat = 0
254+
}
255+
256+
func test(c: C?, v: Double) {
257+
c?.prop = v / 2.0 // Ok
258+
259+
let copy = c!
260+
copy.prop = Optional(v) ?? 0 // Ok
261+
}
262+
}

0 commit comments

Comments
 (0)