Make the "typechecked function body" request more central and resilient

The "typechecked function body" request was defined to type-check a
function body that is known to be present, and not skipped, and would
assert these conditions, requiring its users to check whether a body
was expected. Often, this means that callers would use `getBody()`
instead, which retrieves the underlying value in whatever form it
happens to be, and assume it has been mutated appropriately.

Make the "typechecked function body" request, triggered by
`getTypecheckedBody()`, more resilient and central. A `NULL` result is
now acceptable, signifying that there is no body. Clients will need to
tolerate NULL results.

* When there is no body but should be one, produce an appropriate
error.
* When there shouldn't be a body but is, produce an appropriate error
* Handle skipping of function bodies here, rather than elsewhere.

Over time, we should move clients off of `getBody` and `hasBody`
entirely, and toward `getTypecheckedBody` or some yet-to-be-introduced
forms like `getBodyAsWritten` for the pre-typechecked body.
This commit is contained in:
Doug Gregor
2023-11-26 09:09:29 -08:00
parent 6fa556b35d
commit 236418dbf8
11 changed files with 116 additions and 79 deletions

View File

@@ -412,11 +412,13 @@ extractTypePropertyInfo(VarDecl *propertyDecl) {
}
if (auto accessorDecl = propertyDecl->getAccessor(AccessorKind::Get)) {
auto node = accessorDecl->getTypecheckedBody()->getFirstElement();
if (auto *stmt = node.dyn_cast<Stmt *>()) {
if (stmt->getKind() == StmtKind::Return) {
return {propertyDecl,
extractCompileTimeValue(cast<ReturnStmt>(stmt)->getResult())};
if (auto body = accessorDecl->getTypecheckedBody()) {
auto node = body->getFirstElement();
if (auto *stmt = node.dyn_cast<Stmt *>()) {
if (stmt->getKind() == StmtKind::Return) {
return {propertyDecl,
extractCompileTimeValue(cast<ReturnStmt>(stmt)->getResult())};
}
}
}
}