@@ -1092,12 +1092,14 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10921092 auto &eval = getASTContext ().evaluator ;
10931093 auto *S =
10941094 evaluateOrDefault (eval, PreCheckReturnStmtRequest{RS, DC}, nullptr );
1095+ if (!S)
1096+ return nullptr ;
10951097
10961098 // We do a cast here as it may have been turned into a FailStmt. We should
10971099 // return that without doing anything else.
1098- RS = dyn_cast_or_null <ReturnStmt>(S);
1100+ RS = dyn_cast <ReturnStmt>(S);
10991101 if (!RS)
1100- return S ;
1102+ return visit (S) ;
11011103
11021104 auto TheFunc = AnyFunctionRef::fromDeclContext (DC);
11031105 assert (TheFunc && " Should have bailed from pre-check if this is None" );
@@ -1778,16 +1780,26 @@ Stmt *PreCheckReturnStmtRequest::evaluate(Evaluator &evaluator, ReturnStmt *RS,
17781780 auto &ctx = DC->getASTContext ();
17791781 auto fn = AnyFunctionRef::fromDeclContext (DC);
17801782
1783+ auto errorResult = [&]() -> Stmt * {
1784+ if (RS->hasResult ()) {
1785+ auto *AE = new (ctx)
1786+ AssignExpr (new (ctx) DiscardAssignmentExpr (SourceLoc (), true ),
1787+ SourceLoc (), RS->getResult (), true );
1788+ return BraceStmt::createImplicit (ctx, {AE});
1789+ }
1790+ return nullptr ;
1791+ };
1792+
17811793 // Not valid outside of a function.
17821794 if (!fn) {
17831795 ctx.Diags .diagnose (RS->getReturnLoc (), diag::return_invalid_outside_func);
1784- return nullptr ;
1796+ return errorResult () ;
17851797 }
17861798
17871799 // If the return is in a defer, then it isn't valid either.
17881800 if (isDefer (DC)) {
17891801 ctx.Diags .diagnose (RS->getReturnLoc (), diag::jump_out_of_defer, " return" );
1790- return nullptr ;
1802+ return errorResult () ;
17911803 }
17921804
17931805 // The rest of the checks only concern return statements with results.
0 commit comments