Skip to content

Commit d9fd4c7

Browse files
committed
[CS] Remove isInputExpression parameter
This wasn't consistently used, and consequently could result in some expressions getting their parents invalidated. Instead, replace it with a query to make sure we don't try and add an expression we've already computed the parent info for.
1 parent cc25000 commit d9fd4c7

File tree

5 files changed

+56
-13
lines changed

5 files changed

+56
-13
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4562,8 +4562,7 @@ class ConstraintSystem {
45624562
///
45634563
/// \returns a possibly-sanitized expression, or null if an error occurred.
45644564
[[nodiscard]]
4565-
Expr *generateConstraints(Expr *E, DeclContext *dc,
4566-
bool isInputExpression = true);
4565+
Expr *generateConstraints(Expr *E, DeclContext *dc);
45674566

45684567
/// Generate constraints for binding the given pattern to the
45694568
/// value of the given expression.

lib/Sema/CSGen.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4959,10 +4959,8 @@ bool ConstraintSystem::generateConstraints(
49594959
}
49604960
}
49614961

4962-
Expr *ConstraintSystem::generateConstraints(
4963-
Expr *expr, DeclContext *dc, bool isInputExpression) {
4964-
if (isInputExpression)
4965-
InputExprs.insert(expr);
4962+
Expr *ConstraintSystem::generateConstraints(Expr *expr, DeclContext *dc) {
4963+
InputExprs.insert(expr);
49664964
return generateConstraintsFor(*this, expr, dc);
49674965
}
49684966

lib/Sema/CSSyntacticElement.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,8 +1115,8 @@ class SyntacticElementConstraintGenerator
11151115

11161116
for (auto node : braceStmt->getElements()) {
11171117
if (auto expr = node.dyn_cast<Expr *>()) {
1118-
auto generatedExpr = cs.generateConstraints(
1119-
expr, context.getAsDeclContext(), /*isInputExpression=*/false);
1118+
auto generatedExpr =
1119+
cs.generateConstraints(expr, context.getAsDeclContext());
11201120
if (!generatedExpr) {
11211121
hadError = true;
11221122
}
@@ -1250,8 +1250,7 @@ class SyntacticElementConstraintGenerator
12501250
auto *expr = returnStmt->getResult();
12511251
assert(expr && "single expression closure without expression?");
12521252

1253-
expr = cs.generateConstraints(expr, context.getAsDeclContext(),
1254-
/*isInputExpression=*/false);
1253+
expr = cs.generateConstraints(expr, context.getAsDeclContext());
12551254
if (!expr) {
12561255
hadError = true;
12571256
return;

lib/Sema/ConstraintSystem.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,12 @@ void ConstraintSystem::addPackEnvironment(PackElementExpr *packElement,
822822
static void extendDepthMap(
823823
Expr *expr,
824824
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &depthMap) {
825+
// If we already have an entry in the map, we don't need to update it. This
826+
// avoids invalidating previous entries when solving a smaller component of a
827+
// larger AST node, e.g during conjunction solving.
828+
if (depthMap.contains(expr))
829+
return;
830+
825831
class RecordingTraversal : public ASTWalker {
826832
SmallVector<ClosureExpr *, 4> Closures;
827833

unittests/Sema/ConstraintGenerationTests.cpp

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ TEST_F(SemaTest, TestImplicitForceCastConstraintGeneration) {
3838
auto *castExpr = ForcedCheckedCastExpr::createImplicit(Context, literal,
3939
Context.TheAnyType);
4040

41-
auto *expr = cs.generateConstraints(castExpr, DC, /*isInputExpression=*/true);
41+
auto *expr = cs.generateConstraints(castExpr, DC);
4242

4343
ASSERT_NE(expr, nullptr);
4444

@@ -66,7 +66,7 @@ TEST_F(SemaTest, TestImplicitCoercionConstraintGeneration) {
6666
auto *castExpr = CoerceExpr::createImplicit(Context, literal,
6767
getStdlibType("Double"));
6868

69-
auto *expr = cs.generateConstraints(castExpr, DC, /*isInputExpression=*/true);
69+
auto *expr = cs.generateConstraints(castExpr, DC);
7070

7171
ASSERT_NE(expr, nullptr);
7272

@@ -95,7 +95,7 @@ TEST_F(SemaTest, TestImplicitConditionalCastConstraintGeneration) {
9595
auto *castExpr = ConditionalCheckedCastExpr::createImplicit(
9696
Context, literal, getStdlibType("Double"));
9797

98-
auto *expr = cs.generateConstraints(castExpr, DC, /*isInputExpression=*/true);
98+
auto *expr = cs.generateConstraints(castExpr, DC);
9999

100100
ASSERT_NE(expr, nullptr);
101101

@@ -179,3 +179,44 @@ TEST_F(SemaTest, TestCaptureListIsNotOpenedEarly) {
179179
ASSERT_TRUE(cs.hasType(capture.getVar()));
180180
}
181181
}
182+
183+
TEST_F(SemaTest, TestMultiStmtClosureBodyParentAndDepth) {
184+
// {
185+
// ()
186+
// return ()
187+
// }
188+
DeclAttributes attrs;
189+
auto *closure = new (Context) ClosureExpr(attrs,
190+
/*braceRange=*/SourceRange(),
191+
/*capturedSelfDecl=*/nullptr,
192+
ParameterList::createEmpty(Context),
193+
/*asyncLoc=*/SourceLoc(),
194+
/*throwsLoc=*/SourceLoc(),
195+
/*thrownType*/ nullptr,
196+
/*arrowLoc=*/SourceLoc(),
197+
/*inLoc=*/SourceLoc(),
198+
/*explicitResultType=*/nullptr, DC);
199+
closure->setImplicit();
200+
201+
auto *RS = ReturnStmt::createImplicit(
202+
Context, TupleExpr::createImplicit(Context, {}, {}));
203+
204+
closure->setBody(BraceStmt::createImplicit(Context, {
205+
TupleExpr::createImplicit(Context, {}, {}), RS
206+
}));
207+
208+
SyntacticElementTarget target(closure, DC, ContextualTypeInfo(),
209+
/*isDiscarded*/ true);
210+
211+
ConstraintSystem cs(DC, ConstraintSystemOptions());
212+
cs.solve(target);
213+
214+
ASSERT_EQ(cs.getParentExpr(closure), nullptr);
215+
ASSERT_EQ(cs.getExprDepth(closure), 0);
216+
217+
// We visit the ReturnStmt twice when computing the parent map, ensure we
218+
// don't invalidate its parent on the second walk during the conjunction.
219+
auto *result = RS->getResult();
220+
ASSERT_EQ(cs.getParentExpr(result), closure);
221+
ASSERT_EQ(cs.getExprDepth(result), 1);
222+
}

0 commit comments

Comments
 (0)