Skip to content

Commit 879bd65

Browse files
committed
[CSApply] Rewrite types of a constructed tuple
When construction call is rewritten into a tuple conversion, rewriter has to make sure that AST types are reset otherwise it would end up with types set by `packIntoImplicitTupleOrParen` which could contain l-values. Resolves: rdar://90366182
1 parent 56e024d commit 879bd65

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/Sema/CSApply.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7744,7 +7744,15 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
77447744
auto *packed = apply->getArgs()->packIntoImplicitTupleOrParen(
77457745
ctx, [&](Expr *E) { return cs.getType(E); });
77467746
cs.cacheType(packed);
7747-
return coerceToType(packed, tupleTy, cs.getConstraintLocator(packed));
7747+
auto *result = coerceToType(packed, tupleTy, cs.getConstraintLocator(packed));
7748+
// Resetting the types of tuple is necessary because
7749+
// `packIntoImplicitTupleOrParen` sets types in AST
7750+
// where `coerceToType` only updates constraint system
7751+
// cache. This creates a mismatch that would not be
7752+
// corrected by `setExprTypes` if this tuple is used
7753+
// as an argument that is wrapped in an autoclosure.
7754+
solution.setExprTypes(result);
7755+
return result;
77487756
}
77497757

77507758
// We're constructing a value of nominal type. Look for the constructor or
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
class Data {
4+
}
5+
6+
class Test {
7+
var lastIndex: Int = 0
8+
9+
func test(_ arr: [[Data]]) {
10+
typealias I = (index: Int, data: [Int])
11+
12+
struct Pair: Hashable {
13+
var lhs: Int
14+
var rhs: Int
15+
}
16+
17+
let data = [Pair: I]()
18+
for index in 0..<arr.count {
19+
for (idx, _) in arr[index].enumerated() {
20+
_ = data[Pair(lhs: index, rhs: idx)] ?? I(index: lastIndex, data: [Int]()) // Ok
21+
}
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)