Skip to content

Commit 6d67102

Browse files
committed
[TypeChecker/BuilderTransform] Make sure implicit load expression updates types in AST
Can't use `ConstraintSystem::addImplicitLoadExpr` because that would only cache types in constraint system and wouldn't propagate them to AST, since that happens in `ExprRewritter::finalize` during regular solution application. `TypeChecker::addImplicitLoadExpr` should be used directly in cases like that. Resolves: rdar://problem/58972627
1 parent c4bd50c commit 6d67102

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,8 @@ class BuilderClosureRewriter
694694

695695
// Load the right-hand side if needed.
696696
if (finalCapturedExpr->getType()->is<LValueType>()) {
697-
auto &cs = solution.getConstraintSystem();
698-
finalCapturedExpr = cs.addImplicitLoadExpr(finalCapturedExpr);
697+
finalCapturedExpr =
698+
TypeChecker::addImplicitLoadExpr(ctx, finalCapturedExpr);
699699
}
700700

701701
auto assign = new (ctx) AssignExpr(
@@ -840,8 +840,7 @@ class BuilderClosureRewriter
840840

841841
// Load the condition if needed.
842842
if (finalCondExpr->getType()->is<LValueType>()) {
843-
auto &cs = solution.getConstraintSystem();
844-
finalCondExpr = cs.addImplicitLoadExpr(finalCondExpr);
843+
finalCondExpr = TypeChecker::addImplicitLoadExpr(ctx, finalCondExpr);
845844
}
846845

847846
condElement.setBoolean(finalCondExpr);

lib/Sema/TypeChecker.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,10 +1094,13 @@ class TypeChecker final {
10941094
/// more complicated than simplify wrapping given root in newly created
10951095
/// `LoadExpr`, because `ForceValueExpr` and `ParenExpr` supposed to appear
10961096
/// only at certain positions in AST.
1097-
static Expr *
1098-
addImplicitLoadExpr(ASTContext &Context, Expr *expr,
1099-
std::function<Type(Expr *)> getType,
1100-
std::function<void(Expr *, Type)> setType);
1097+
static Expr *addImplicitLoadExpr(ASTContext &Context, Expr *expr,
1098+
std::function<Type(Expr *)> getType =
1099+
[](Expr *E) { return E->getType(); },
1100+
std::function<void(Expr *, Type)> setType =
1101+
[](Expr *E, Type type) {
1102+
E->setType(type);
1103+
});
11011104

11021105
/// Determine whether the given type contains the given protocol.
11031106
///
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %target-swift-frontend %s -target x86_64-apple-macosx10.15 -emit-sil -verify
2+
// REQUIRES: objc_interop
3+
// REQUIRES: OS=macosx
4+
5+
import SwiftUI
6+
import Combine
7+
8+
struct A: View {
9+
var body: some View {
10+
Spacer()
11+
}
12+
}
13+
14+
struct B: View {
15+
var body: some View {
16+
Spacer()
17+
}
18+
}
19+
20+
class Context: ObservableObject {
21+
@State var flag: Bool
22+
23+
init() {
24+
self.flag = false
25+
}
26+
}
27+
28+
struct S : View {
29+
@EnvironmentObject var context: Context
30+
31+
var body: some View {
32+
VStack {
33+
if (context.flag) { // Ok (shouldn't trip SIL Verifier)
34+
A()
35+
} else {
36+
B()
37+
}
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)