Fold ConstraintSolver::coerceToRValue() into TypeChecker::coerceToRValue()

ConstraintSolver::coerceToRValue() missed a bunch of cases where we
should be dealing with lvalues, e.g., tuples, "try" expressions, and
so on. Extend TypeChecker::coerceToRValue() to deal with the
expression type side-tables and ConstraintSolver::coerceToRValue() to
it.

Fixes rdar://problem/32700180, a crash-on-valid.
This commit is contained in:
Doug Gregor
2017-06-14 22:15:02 -07:00
parent 4d65801c05
commit 01b45a245c
4 changed files with 64 additions and 44 deletions

View File

@@ -7285,32 +7285,15 @@ namespace {
} // end anonymous namespace
Expr *ConstraintSystem::coerceToRValue(Expr *expr) {
// Can't load from an inout value.
if (auto *iot = getType(expr)->getAs<InOutType>()) {
// Emit a fixit if we can find the & expression that turned this into an
// inout.
auto &tc = getTypeChecker();
if (auto addrOf =
dyn_cast<InOutExpr>(expr->getSemanticsProvidingExpr())) {
tc.diagnose(expr->getLoc(), diag::load_of_explicit_lvalue,
iot->getObjectType())
.fixItRemove(SourceRange(addrOf->getLoc()));
return coerceToRValue(addrOf->getSubExpr());
} else {
tc.diagnose(expr->getLoc(), diag::load_of_explicit_lvalue,
iot->getObjectType());
return expr;
}
}
// If we already have an rvalue, we're done, otherwise emit a load.
if (auto lvalueTy = getType(expr)->getAs<LValueType>()) {
propagateLValueAccessKind(expr, AccessKind::Read);
return cacheType(new (getASTContext())
LoadExpr(expr, lvalueTy->getObjectType()));
}
return expr;
auto &tc = getTypeChecker();
return tc.coerceToRValue(expr,
[&](Expr *expr) {
return getType(expr);
},
[&](Expr *expr, Type type) {
expr->setType(type);
cacheType(expr);
});
}
/// Emit the fixes computed as part of the solution, returning true if we were