Skip to content

Commit 96ff76c

Browse files
committed
[CS] Use the type map in eraseOpenedExistentials.
1 parent 4d28791 commit 96ff76c

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3193,12 +3193,15 @@ namespace {
31933193
/// This is done in the case of a typecheck failure, after we re-typecheck
31943194
/// partially-typechecked subexpressions in a context-free manner.
31953195
///
3196-
static void eraseOpenedExistentials(Expr *&expr) {
3196+
static void eraseOpenedExistentials(Expr *&expr, ConstraintSystem &CS) {
31973197

31983198
class ExistentialEraser : public ASTWalker {
3199+
ConstraintSystem &CS;
31993200
llvm::SmallDenseMap<OpaqueValueExpr *, Expr *, 4> OpenExistentials;
32003201

32013202
public:
3203+
ExistentialEraser(ConstraintSystem &CS) : CS(CS) {}
3204+
32023205
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
32033206
if (auto OOE = dyn_cast<OpenExistentialExpr>(expr)) {
32043207
auto archetypeVal = OOE->getOpaqueValue();
@@ -3236,8 +3239,11 @@ static void eraseOpenedExistentials(Expr *&expr) {
32363239
}
32373240

32383241
Expr *walkToExprPost(Expr *expr) override {
3239-
Type type = expr->getType();
3240-
if (!type || !type->hasOpenedExistential())
3242+
if (!CS.hasType(expr))
3243+
return expr;
3244+
3245+
Type type = CS.getType(expr);
3246+
if (!type->hasOpenedExistential())
32413247
return expr;
32423248

32433249
type = type.transform([&](Type type) -> Type {
@@ -3247,7 +3253,7 @@ static void eraseOpenedExistentials(Expr *&expr) {
32473253

32483254
return type;
32493255
});
3250-
expr->setType(type);
3256+
CS.setType(expr, type);
32513257

32523258
return expr;
32533259
}
@@ -3259,7 +3265,7 @@ static void eraseOpenedExistentials(Expr *&expr) {
32593265
}
32603266
};
32613267

3262-
expr = expr->walk(ExistentialEraser());
3268+
expr = expr->walk(ExistentialEraser(CS));
32633269
}
32643270

32653271
/// Unless we've already done this, retypecheck the specified subexpression on
@@ -3355,19 +3361,21 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
33553361
// anything that the type-checker doesn't expect to see. This can happen
33563362
// because of repeated type-checking; the removal below, while independently
33573363
// important, isn't itself sufficient because of AST mutation.
3358-
eraseOpenedExistentials(subExpr);
3364+
eraseOpenedExistentials(subExpr, CS);
33593365

33603366
auto resultTy = CS.TC.typeCheckExpression(
33613367
subExpr, CS.DC, TypeLoc::withoutLoc(convertType), convertTypePurpose,
33623368
TCEOptions, listener, &CS);
33633369

3370+
CS.cacheExprTypes(subExpr);
3371+
33643372
// This is a terrible hack to get around the fact that typeCheckExpression()
33653373
// might change subExpr to point to a new OpenExistentialExpr. In that case,
33663374
// since the caller passed subExpr by value here, they would be left
33673375
// holding on to an expression containing open existential types but
33683376
// no OpenExistentialExpr, which breaks invariants enforced by the
33693377
// ASTChecker.
3370-
eraseOpenedExistentials(subExpr);
3378+
eraseOpenedExistentials(subExpr, CS);
33713379

33723380
// If recursive type checking failed, then an error was emitted. Return
33733381
// null to indicate this to the caller.
@@ -3378,10 +3386,11 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
33783386
// just pretend as though nothing happened.
33793387
if (resultTy->is<ErrorType>()) {
33803388
subExpr = preCheckedExpr;
3389+
if (subExpr->getType())
3390+
CS.cacheType(subExpr);
33813391
SavedTypeData.restore();
33823392
}
33833393

3384-
CS.cacheExprTypes(subExpr);
33853394
CS.TC.addExprForDiagnosis(preCheckedExpr, std::make_pair(subExpr, &CS));
33863395

33873396
return subExpr;

0 commit comments

Comments
 (0)