@@ -874,30 +874,27 @@ class SyntacticElementConstraintGenerator
874874 }
875875
876876 void visitReturnStmt (ReturnStmt *returnStmt) {
877- auto *closure =
878- dyn_cast_or_null<ClosureExpr>(context.getAbstractClosureExpr ());
879-
880877 // Single-expression closures are effectively a `return` statement,
881878 // so let's give them a special locator as to indicate that.
882879 // Return statements might not have a result if we have a closure whose
883880 // implicit returned value is coerced to Void.
884- if (closure && closure->hasSingleExpressionBody () &&
885- returnStmt->hasResult ()) {
881+ if (isInSingleExpressionClosure () && returnStmt->hasResult ()) {
886882 auto *expr = returnStmt->getResult ();
887883 assert (expr && " single expression closure without expression?" );
888884
889- expr = cs.generateConstraints (expr, closure ,
885+ expr = cs.generateConstraints (expr, context. getAsDeclContext () ,
890886 /* isInputExpression=*/ false );
891887 if (!expr) {
892888 hadError = true ;
893889 return ;
894890 }
895891
896- cs.addConstraint (
897- ConstraintKind::Conversion, cs.getType (expr), resultType,
898- cs.getConstraintLocator (
899- closure, LocatorPathElt::ClosureBody (
900- /* hasReturn=*/ !returnStmt->isImplicit ())));
892+ cs.addConstraint (ConstraintKind::Conversion, cs.getType (expr),
893+ getContextualResultType (),
894+ cs.getConstraintLocator (
895+ context.getAbstractClosureExpr (),
896+ LocatorPathElt::ClosureBody (
897+ /* hasReturn=*/ !returnStmt->isImplicit ())));
901898 return ;
902899 }
903900
@@ -923,14 +920,40 @@ class SyntacticElementConstraintGenerator
923920 return ;
924921 }
925922
926- cs.setContextualType (target.getAsExpr (), TypeLoc::withoutLoc (resultType),
923+ cs.setContextualType (target.getAsExpr (),
924+ TypeLoc::withoutLoc (getContextualResultType ()),
927925 CTP_ReturnStmt);
928926 cs.setSolutionApplicationTarget (returnStmt, target);
929927 }
930928
929+ bool isInSingleExpressionClosure () {
930+ if (!isExpr<ClosureExpr>(context.getAbstractClosureExpr ()))
931+ return false ;
932+
933+ // Result builder transformed bodies are never single-expression.
934+ if (cs.getAppliedResultBuilderTransform (context))
935+ return false ;
936+
937+ return context.hasSingleExpressionBody ();
938+ }
939+
940+ Type getContextualResultType () const {
941+ if (auto transform = cs.getAppliedResultBuilderTransform (context))
942+ return transform->bodyResultType ;
943+
944+ if (auto *closure =
945+ getAsExpr<ClosureExpr>(context.getAbstractClosureExpr ()))
946+ return cs.getClosureType (closure)->getResult ();
947+
948+ return context.getBodyResultType ();
949+ }
950+
931951 bool isSupportedMultiStatementClosure () const {
952+ if (cs.getAppliedResultBuilderTransform (context))
953+ return true ;
954+
932955 if (auto *closure =
933- dyn_cast_or_null <ClosureExpr>(context.getAbstractClosureExpr ())) {
956+ getAsExpr <ClosureExpr>(context.getAbstractClosureExpr ())) {
934957 return !closure->hasSingleExpressionBody () &&
935958 cs.participatesInInference (closure);
936959 }
0 commit comments