@@ -1242,6 +1242,14 @@ class SyntacticElementConstraintGenerator
12421242 }
12431243
12441244 void visitReturnStmt (ReturnStmt *returnStmt) {
1245+ // Record an implied result if we have one.
1246+ if (returnStmt->isImplied ()) {
1247+ auto kind = context.getAsClosureExpr () ? ImpliedResultKind::ForClosure
1248+ : ImpliedResultKind::Regular;
1249+ auto *result = returnStmt->getResult ();
1250+ cs.recordImpliedResult (result, kind);
1251+ }
1252+
12451253 Expr *resultExpr;
12461254 if (returnStmt->hasResult ()) {
12471255 resultExpr = returnStmt->getResult ();
@@ -1316,11 +1324,9 @@ class SyntacticElementConstraintGenerator
13161324 // on the closure itself. Otherwise we use the default contextual type
13171325 // locator, which will be created for us.
13181326 ConstraintLocator *loc = nullptr ;
1319- if (context.isSingleExpressionClosure (cs) && returnStmt->hasResult ()) {
1320- loc = cs.getConstraintLocator (
1321- closure, {LocatorPathElt::ClosureBody (
1322- /* hasImpliedReturn=*/ returnStmt->isImplied ())});
1323- }
1327+ if (context.isSingleExpressionClosure (cs) && returnStmt->hasResult ())
1328+ loc = cs.getConstraintLocator (closure, {LocatorPathElt::ClosureBody ()});
1329+
13241330 return {cs.getClosureType (closure)->getResult (), CTP_ClosureResult, loc};
13251331 }
13261332
@@ -1461,18 +1467,30 @@ bool ConstraintSystem::generateConstraints(SingleValueStmtExpr *E) {
14611467 Type resultTy = createTypeVariable (loc, /* options*/ 0 );
14621468 setType (E, resultTy);
14631469
1470+ // Propagate the implied result kind from the if/switch expression itself
1471+ // into the branches.
1472+ auto impliedResultKind =
1473+ isImpliedResult (E).value_or (ImpliedResultKind::Regular);
1474+
14641475 // Assign contextual types for each of the result exprs.
1465- SmallVector<Expr *, 4 > scratch;
1466- auto branches = E->getResultExprs (scratch);
1476+ SmallVector<ThenStmt *, 4 > scratch;
1477+ auto branches = E->getThenStmts (scratch);
14671478 for (auto idx : indices (branches)) {
1468- auto *branch = branches[idx];
1479+ auto *thenStmt = branches[idx];
1480+ auto *result = thenStmt->getResult ();
1481+
1482+ // If we have an implicit 'then' statement, record it as an implied result.
1483+ // TODO: Should we track 'implied' as a separate bit on ThenStmt? Currently
1484+ // it's the same as being implicit, but may not always be.
1485+ if (thenStmt->isImplicit ())
1486+ recordImpliedResult (result, impliedResultKind);
14691487
14701488 auto ctpElt = LocatorPathElt::ContextualType (CTP_SingleValueStmtBranch);
14711489 auto *loc = getConstraintLocator (
14721490 E, {LocatorPathElt::SingleValueStmtResult (idx), ctpElt});
14731491
14741492 ContextualTypeInfo info (resultTy, CTP_SingleValueStmtBranch, loc);
1475- setContextualInfo (branch , info);
1493+ setContextualInfo (result , info);
14761494 }
14771495
14781496 TypeJoinExpr *join = nullptr ;
@@ -1488,9 +1506,9 @@ bool ConstraintSystem::generateConstraints(SingleValueStmtExpr *E) {
14881506 ctx, resultTy, E, AllocationArena::ConstraintSolver);
14891507 }
14901508
1491- // If this is the single expression body of a closure, we need to account
1492- // for the fact that the result type may be bound to Void. This is necessary
1493- // to correctly handle the following case:
1509+ // If this is an implied return in a closure, we need to account for the fact
1510+ // that the result type may be bound to Void. This is necessary to correctly
1511+ // handle the following case:
14941512 //
14951513 // func foo<T>(_ fn: () -> T) {}
14961514 // foo {
@@ -1514,12 +1532,11 @@ bool ConstraintSystem::generateConstraints(SingleValueStmtExpr *E) {
15141532 // need to do this with 'return if'. We also don't need to do it for function
15151533 // decls, as we proactively avoid transforming the if/switch into an
15161534 // expression if the result is known to be Void.
1517- if (auto *CE = dyn_cast<ClosureExpr>(E->getDeclContext ())) {
1518- if (CE->hasSingleExpressionBody () && !hasExplicitResult (CE) &&
1519- CE->getSingleExpressionBody ()->getSemanticsProvidingExpr () == E) {
1520- assert (!getAppliedResultBuilderTransform (CE) &&
1521- " Should have applied the builder with statement semantics" );
1522-
1535+ if (impliedResultKind == ImpliedResultKind::ForClosure) {
1536+ auto *CE = cast<ClosureExpr>(E->getDeclContext ());
1537+ assert (!getAppliedResultBuilderTransform (CE) &&
1538+ " Should have applied the builder with statement semantics" );
1539+ if (getParentExpr (E) == CE) {
15231540 // We may not have a closure type if we're solving a sub-expression
15241541 // independently for e.g code completion.
15251542 // TODO: This won't be necessary once we stop doing the fallback
0 commit comments