[Diagnostics] Fix a crash when using withoutActuallyEscaping incorrectly

Teach `eraseOpenedExistentials` how to handle `OpaqueValueExpr`
associated with `MakeTemporarilyEscapableExpr`.

Resolves: rdar://problem/35773761
This commit is contained in:
Pavel Yaskevich
2018-03-23 14:38:42 -07:00
parent 6b899b625e
commit 134f4e5611
2 changed files with 19 additions and 5 deletions

View File

@@ -2111,13 +2111,17 @@ static void eraseOpenedExistentials(Expr *&expr, ConstraintSystem &CS) {
// Walk the base expression to ensure we erase any existentials within
// it.
base = base->walk(*this);
bool inserted = OpenExistentials.insert({archetypeVal, base}).second;
assert(inserted && "OpaqueValue appears multiple times?");
(void)inserted;
registerOpaqueValue(archetypeVal, base);
return { true, OOE->getSubExpr() };
}
if (auto *MTEE = dyn_cast<MakeTemporarilyEscapableExpr>(expr)) {
registerOpaqueValue(MTEE->getOpaqueValue(),
MTEE->getNonescapingClosureValue());
return {true, MTEE->getSubExpr()};
}
if (auto OVE = dyn_cast<OpaqueValueExpr>(expr)) {
auto value = OpenExistentials.find(OVE);
assert(value != OpenExistentials.end() &&
@@ -2166,6 +2170,12 @@ static void eraseOpenedExistentials(Expr *&expr, ConstraintSystem &CS) {
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
return { false, S };
}
void registerOpaqueValue(OpaqueValueExpr *opaque, Expr *base) {
bool inserted = OpenExistentials.insert({opaque, base}).second;
assert(inserted && "OpaqueValue appears multiple times?");
(void)inserted;
}
};
expr = expr->walk(ExistentialEraser(CS));