mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #23251 from nate-chandler/nate/omit-return
Allow return to be omitted from single expression functions.
This commit is contained in:
@@ -5671,8 +5671,60 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
|
||||
Context.Stats->getFrontendCounters().NumFunctionsParsed++;
|
||||
|
||||
ParserResult<BraceStmt> Body = parseBraceItemList(diag::invalid_diagnostic);
|
||||
if (!Body.isNull())
|
||||
AFD->setBody(Body.get());
|
||||
if (!Body.isNull()) {
|
||||
BraceStmt * BS = Body.get();
|
||||
AFD->setBody(BS);
|
||||
|
||||
// If the body consists of a single expression, turn it into a return
|
||||
// statement.
|
||||
//
|
||||
// But don't do this transformation during code completion, as the source
|
||||
// may be incomplete and the type mismatch in return statement will just
|
||||
// confuse the type checker.
|
||||
if (!Body.hasCodeCompletion() && BS->getNumElements() == 1) {
|
||||
auto Element = BS->getElement(0);
|
||||
if (auto *stmt = Element.dyn_cast<Stmt *>()) {
|
||||
auto kind = AFD->getKind();
|
||||
if (kind == DeclKind::Var || kind == DeclKind::Subscript ||
|
||||
kind == DeclKind::Func ) {
|
||||
if (auto *returnStmt = dyn_cast<ReturnStmt>(stmt)) {
|
||||
if (!returnStmt->hasResult()) {
|
||||
auto returnExpr = TupleExpr::createEmpty(Context,
|
||||
SourceLoc(),
|
||||
SourceLoc(),
|
||||
/*implicit*/true);
|
||||
returnStmt->setResult(returnExpr);
|
||||
AFD->setHasSingleExpressionBody();
|
||||
AFD->setSingleExpressionBody(returnExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (auto *E = Element.dyn_cast<Expr *>()) {
|
||||
if (auto SE = dyn_cast<SequenceExpr>(E->getSemanticsProvidingExpr())) {
|
||||
if (SE->getNumElements() > 1 && isa<AssignExpr>(SE->getElement(1))) {
|
||||
// This is an assignment. We don't want to implicitly return
|
||||
// it.
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (auto F = dyn_cast<FuncDecl>(AFD)) {
|
||||
auto RS = new (Context) ReturnStmt(SourceLoc(), E);
|
||||
BS->setElement(0, RS);
|
||||
AFD->setHasSingleExpressionBody();
|
||||
AFD->setSingleExpressionBody(E);
|
||||
} else if (auto *F = dyn_cast<ConstructorDecl>(AFD)) {
|
||||
if (F->getFailability() != OTK_None && isa<NilLiteralExpr>(E)) {
|
||||
// If it's a nil literal, just insert return. This is the only
|
||||
// legal thing to return.
|
||||
auto RS = new (Context) ReturnStmt(E->getStartLoc(), E);
|
||||
BS->setElement(0, RS);
|
||||
AFD->setHasSingleExpressionBody();
|
||||
AFD->setSingleExpressionBody(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
|
||||
|
||||
Reference in New Issue
Block a user