@@ -6442,10 +6442,9 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,
64426442 return DCC.fixupParserResult (FD);
64436443}
64446444
6445- // / Parse a function body for \p AFD and returns it without setting the body
6446- // / to \p AFD .
6447- ParserResult<BraceStmt>
6448- Parser::parseAbstractFunctionBodyImpl (AbstractFunctionDecl *AFD) {
6445+ // / Parse a function body for \p AFD, setting the body to \p AFD before
6446+ // / returning it.
6447+ BraceStmt *Parser::parseAbstractFunctionBodyImpl (AbstractFunctionDecl *AFD) {
64496448 assert (Tok.is (tok::l_brace));
64506449
64516450 // Enter the arguments for the function into a new function-body scope. We
@@ -6473,13 +6472,70 @@ Parser::parseAbstractFunctionBodyImpl(AbstractFunctionDecl *AFD) {
64736472 CodeCompletion->completeAccessorBeginning (CCE);
64746473 RBraceLoc = Tok.getLoc ();
64756474 consumeToken (tok::code_complete);
6476- return makeParserCodeCompletionResult (
6477- BraceStmt::create (Context, LBraceLoc, ASTNode (CCE), RBraceLoc,
6478- /* implicit*/ true ));
6475+ auto *BS = BraceStmt::create (Context, LBraceLoc, ASTNode (CCE), RBraceLoc,
6476+ /* implicit*/ true );
6477+ AFD->setBodyParsed (BS);
6478+ return BS;
64796479 }
64806480 }
64816481
6482- return parseBraceItemList (diag::invalid_diagnostic);
6482+ ParserResult<BraceStmt> Body = parseBraceItemList (diag::invalid_diagnostic);
6483+ if (Body.isNull ())
6484+ return nullptr ;
6485+
6486+ BraceStmt *BS = Body.get ();
6487+ AFD->setBodyParsed (BS);
6488+
6489+ // If the body consists of a single expression, turn it into a return
6490+ // statement.
6491+ //
6492+ // But don't do this transformation during code completion, as the source
6493+ // may be incomplete and the type mismatch in return statement will just
6494+ // confuse the type checker.
6495+ if (BS->getNumElements () != 1 || Body.hasCodeCompletion ())
6496+ return BS;
6497+
6498+ auto Element = BS->getFirstElement ();
6499+ if (auto *stmt = Element.dyn_cast <Stmt *>()) {
6500+ if (isa<FuncDecl>(AFD)) {
6501+ if (auto *returnStmt = dyn_cast<ReturnStmt>(stmt)) {
6502+ if (!returnStmt->hasResult ()) {
6503+ auto returnExpr = TupleExpr::createEmpty (Context,
6504+ SourceLoc (),
6505+ SourceLoc (),
6506+ /* implicit*/ true );
6507+ returnStmt->setResult (returnExpr);
6508+ AFD->setHasSingleExpressionBody ();
6509+ AFD->setSingleExpressionBody (returnExpr);
6510+ }
6511+ }
6512+ }
6513+ } else if (auto *E = Element.dyn_cast <Expr *>()) {
6514+ if (auto SE = dyn_cast<SequenceExpr>(E->getSemanticsProvidingExpr ())) {
6515+ if (SE->getNumElements () > 1 && isa<AssignExpr>(SE->getElement (1 ))) {
6516+ // This is an assignment. We don't want to implicitly return
6517+ // it.
6518+ return BS;
6519+ }
6520+ }
6521+ if (isa<FuncDecl>(AFD)) {
6522+ auto RS = new (Context) ReturnStmt (SourceLoc (), E);
6523+ BS->setFirstElement (RS);
6524+ AFD->setHasSingleExpressionBody ();
6525+ AFD->setSingleExpressionBody (E);
6526+ } else if (auto *F = dyn_cast<ConstructorDecl>(AFD)) {
6527+ if (F->isFailable () && isa<NilLiteralExpr>(E)) {
6528+ // If it's a nil literal, just insert return. This is the only
6529+ // legal thing to return.
6530+ auto RS = new (Context) ReturnStmt (E->getStartLoc (), E);
6531+ BS->setFirstElement (RS);
6532+ AFD->setHasSingleExpressionBody ();
6533+ AFD->setSingleExpressionBody (E);
6534+ }
6535+ }
6536+ }
6537+
6538+ return BS;
64836539}
64846540
64856541// / Parse function body into \p AFD or skip it for delayed parsing.
@@ -6504,60 +6560,7 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
65046560 }
65056561
65066562 Scope S (this , ScopeKind::FunctionBody);
6507-
6508- ParserResult<BraceStmt> Body = parseAbstractFunctionBodyImpl (AFD);
6509- if (!Body.isNull ()) {
6510- BraceStmt * BS = Body.get ();
6511- AFD->setBodyParsed (BS);
6512-
6513- // If the body consists of a single expression, turn it into a return
6514- // statement.
6515- //
6516- // But don't do this transformation during code completion, as the source
6517- // may be incomplete and the type mismatch in return statement will just
6518- // confuse the type checker.
6519- if (!Body.hasCodeCompletion () && BS->getNumElements () == 1 ) {
6520- auto Element = BS->getFirstElement ();
6521- if (auto *stmt = Element.dyn_cast <Stmt *>()) {
6522- if (isa<FuncDecl>(AFD)) {
6523- if (auto *returnStmt = dyn_cast<ReturnStmt>(stmt)) {
6524- if (!returnStmt->hasResult ()) {
6525- auto returnExpr = TupleExpr::createEmpty (Context,
6526- SourceLoc (),
6527- SourceLoc (),
6528- /* implicit*/ true );
6529- returnStmt->setResult (returnExpr);
6530- AFD->setHasSingleExpressionBody ();
6531- AFD->setSingleExpressionBody (returnExpr);
6532- }
6533- }
6534- }
6535- } else if (auto *E = Element.dyn_cast <Expr *>()) {
6536- if (auto SE = dyn_cast<SequenceExpr>(E->getSemanticsProvidingExpr ())) {
6537- if (SE->getNumElements () > 1 && isa<AssignExpr>(SE->getElement (1 ))) {
6538- // This is an assignment. We don't want to implicitly return
6539- // it.
6540- return ;
6541- }
6542- }
6543- if (isa<FuncDecl>(AFD)) {
6544- auto RS = new (Context) ReturnStmt (SourceLoc (), E);
6545- BS->setFirstElement (RS);
6546- AFD->setHasSingleExpressionBody ();
6547- AFD->setSingleExpressionBody (E);
6548- } else if (auto *F = dyn_cast<ConstructorDecl>(AFD)) {
6549- if (F->isFailable () && isa<NilLiteralExpr>(E)) {
6550- // If it's a nil literal, just insert return. This is the only
6551- // legal thing to return.
6552- auto RS = new (Context) ReturnStmt (E->getStartLoc (), E);
6553- BS->setFirstElement (RS);
6554- AFD->setHasSingleExpressionBody ();
6555- AFD->setSingleExpressionBody (E);
6556- }
6557- }
6558- }
6559- }
6560- }
6563+ (void )parseAbstractFunctionBodyImpl (AFD);
65616564}
65626565
65636566BraceStmt *Parser::parseAbstractFunctionBodyDelayed (AbstractFunctionDecl *AFD) {
@@ -6589,7 +6592,7 @@ BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
65896592 Scope TopLevelScope (this , ScopeKind::TopLevel);
65906593 Scope S (this , ScopeKind::FunctionBody);
65916594
6592- return parseAbstractFunctionBodyImpl (AFD). getPtrOrNull () ;
6595+ return parseAbstractFunctionBodyImpl (AFD);
65936596}
65946597
65956598// / Parse a 'enum' declaration, returning true (and doing no token
0 commit comments