Skip to content

Commit 5bcf8a9

Browse files
authored
Merge pull request #10058 from rudkx/clear-opaque-expr-on-open-existential
[Constraint solver] Fix an issue with rewriting OpenExistentialExpr.
2 parents 63bc717 + fb5ac6d commit 5bcf8a9

File tree

3 files changed

+33
-11
lines changed

3 files changed

+33
-11
lines changed

lib/AST/ASTVerifier.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,11 @@ class Verifier : public ASTWalker {
697697
if (!shouldVerify(cast<Expr>(expr)))
698698
return false;
699699

700+
// In rare instances we clear the opaque value because we no
701+
// longer have a subexpression that references it.
702+
if (!expr->getOpaqueValue())
703+
return true;
704+
700705
assert(!OpaqueValues.count(expr->getOpaqueValue()));
701706
OpaqueValues[expr->getOpaqueValue()] = 0;
702707
assert(OpenedExistentialArchetypes.count(expr->getOpenedArchetype())==0);
@@ -705,6 +710,11 @@ class Verifier : public ASTWalker {
705710
}
706711

707712
void cleanup(OpenExistentialExpr *expr) {
713+
// In rare instances we clear the opaque value because we no
714+
// longer have a subexpression that references it.
715+
if (!expr->getOpaqueValue())
716+
return;
717+
708718
assert(OpaqueValues.count(expr->getOpaqueValue()));
709719
OpaqueValues.erase(expr->getOpaqueValue());
710720
assert(OpenedExistentialArchetypes.count(expr->getOpenedArchetype())==1);

lib/AST/Expr.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,19 +316,25 @@ void Expr::propagateLValueAccessKind(AccessKind accessKind,
316316

317317
void visitOpenExistentialExpr(OpenExistentialExpr *E,
318318
AccessKind accessKind) {
319-
bool opaqueValueHadAK = E->getOpaqueValue()->hasLValueAccessKind();
320-
AccessKind oldOpaqueValueAK =
321-
(opaqueValueHadAK ? E->getOpaqueValue()->getLValueAccessKind()
322-
: AccessKind::Read);
319+
AccessKind oldOpaqueValueAK;
320+
bool opaqueValueHadAK;
321+
if (E->getOpaqueValue()) {
322+
opaqueValueHadAK = E->getOpaqueValue()->hasLValueAccessKind();
323+
oldOpaqueValueAK =
324+
(opaqueValueHadAK ? E->getOpaqueValue()->getLValueAccessKind()
325+
: AccessKind::Read);
326+
}
323327

324328
visit(E->getSubExpr(), accessKind);
325329

326-
// Propagate the new access kind from the OVE to the original existential
327-
// if we just set or changed it on the OVE.
328-
if (E->getOpaqueValue()->hasLValueAccessKind()) {
329-
auto newOpaqueValueAK = E->getOpaqueValue()->getLValueAccessKind();
330-
if (!opaqueValueHadAK || newOpaqueValueAK != oldOpaqueValueAK)
331-
visit(E->getExistentialValue(), newOpaqueValueAK);
330+
if (E->getOpaqueValue()) {
331+
// Propagate the new access kind from the OVE to the original
332+
// existential if we just set or changed it on the OVE.
333+
if (E->getOpaqueValue()->hasLValueAccessKind()) {
334+
auto newOpaqueValueAK = E->getOpaqueValue()->getLValueAccessKind();
335+
if (!opaqueValueHadAK || newOpaqueValueAK != oldOpaqueValueAK)
336+
visit(E->getExistentialValue(), newOpaqueValueAK);
337+
}
332338
}
333339
}
334340

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,12 @@ namespace {
760760
if (result == nullptr) {
761761
result = new (tc.Context) ErrorExpr(range);
762762
cs.setType(result, erasedTy);
763+
// The opaque value is no longer reachable in an AST walk as
764+
// a result of the result above being replaced with an
765+
// ErrorExpr, but there is code expecting to have a type set
766+
// on it. Since we no longer have a reachable reference,
767+
// we'll null this out.
768+
record.OpaqueValue = nullptr;
763769
}
764770
}
765771

@@ -768,7 +774,7 @@ namespace {
768774
// means this is our only chance to propagate the l-value access kind
769775
// down to the original existential value. Otherwise, propagateLVAK
770776
// will handle this.
771-
if (record.OpaqueValue->hasLValueAccessKind())
777+
if (record.OpaqueValue && record.OpaqueValue->hasLValueAccessKind())
772778
cs.propagateLValueAccessKind(record.ExistentialValue,
773779
record.OpaqueValue->getLValueAccessKind());
774780

0 commit comments

Comments
 (0)