@@ -383,6 +383,11 @@ struct SyntacticElementContext
383
383
}
384
384
}
385
385
386
+ NullablePtr<ClosureExpr> getAsClosureExpr () const {
387
+ return dyn_cast_or_null<ClosureExpr>(
388
+ this ->dyn_cast <AbstractClosureExpr *>());
389
+ }
390
+
386
391
NullablePtr<AbstractClosureExpr> getAsAbstractClosureExpr () const {
387
392
return this ->dyn_cast <AbstractClosureExpr *>();
388
393
}
@@ -907,36 +912,6 @@ class SyntacticElementConstraintGenerator
907
912
void visitBraceStmt (BraceStmt *braceStmt) {
908
913
auto &ctx = cs.getASTContext ();
909
914
910
- auto addResultDefault = [&](ClosureExpr *closure) {
911
- if (context.getBody () == braceStmt) {
912
- // If this closure has an empty body and no explicit result type
913
- // let's bind result type to `Void` since that's the only type empty
914
- // body can produce. Otherwise, if (multi-statement) closure doesn't
915
- // have an explicit result (no `return` statements) let's default it to
916
- // `Void`.
917
- if (!constraints::hasExplicitResult (closure)) {
918
- auto constraintKind =
919
- (closure->hasEmptyBody () && !closure->hasExplicitResultType ())
920
- ? ConstraintKind::Bind
921
- : ConstraintKind::Defaultable;
922
-
923
- cs.addConstraint (constraintKind,
924
- cs.getClosureType (closure)->getResult (),
925
- ctx.TheEmptyTupleType ,
926
- cs.getConstraintLocator (
927
- closure, ConstraintLocator::ClosureResult));
928
- }
929
- }
930
- };
931
-
932
- if (auto closure = cast<ClosureExpr>(
933
- context.getAsAbstractClosureExpr ().getPtrOrNull ())) {
934
- if (!cs.participatesInInference (closure)) {
935
- addResultDefault (closure);
936
- return ;
937
- }
938
- }
939
-
940
915
if (context.isSingleExpressionClosure (cs)) {
941
916
for (auto node : braceStmt->getElements ()) {
942
917
if (auto expr = node.dyn_cast <Expr *>()) {
@@ -951,13 +926,40 @@ class SyntacticElementConstraintGenerator
951
926
visitDecl (node.get <Decl *>());
952
927
}
953
928
}
954
- if (!hadError)
955
- addResultDefault (cast<ClosureExpr>(
956
- context.getAsAbstractClosureExpr ().getPtrOrNull ()));
957
-
958
929
return ;
959
930
}
960
931
932
+ // If this brace statement represents a body of an empty or
933
+ // multi-statement closure.
934
+ if (locator->directlyAt <ClosureExpr>()) {
935
+ auto *closure = context.getAsClosureExpr ().get ();
936
+ // If this closure has an empty body and no explicit result type
937
+ // let's bind result type to `Void` since that's the only type empty
938
+ // body can produce. Otherwise, if (multi-statement) closure doesn't
939
+ // have an explicit result (no `return` statements) let's default it to
940
+ // `Void`.
941
+ //
942
+ // Note that result builder bodies always have a `return` statement
943
+ // at the end, so they don't need to be defaulted.
944
+ if (!cs.getAppliedResultBuilderTransform ({closure}) &&
945
+ !hasExplicitResult (closure)) {
946
+ auto constraintKind =
947
+ (closure->hasEmptyBody () && !closure->hasExplicitResultType ())
948
+ ? ConstraintKind::Bind
949
+ : ConstraintKind::Defaultable;
950
+
951
+ cs.addConstraint (
952
+ constraintKind, cs.getClosureType (closure)->getResult (),
953
+ ctx.TheEmptyTupleType ,
954
+ cs.getConstraintLocator (closure, ConstraintLocator::ClosureResult));
955
+ }
956
+
957
+ // Let's not walk into the body if empty or multi-statement closure
958
+ // doesn't participate in inference.
959
+ if (!cs.participatesInInference (closure))
960
+ return ;
961
+ }
962
+
961
963
if (isChildOf (StmtKind::Case)) {
962
964
auto *caseStmt = cast<CaseStmt>(
963
965
locator->castLastElementTo <LocatorPathElt::SyntacticElement>()
@@ -988,10 +990,6 @@ class SyntacticElementConstraintGenerator
988
990
/* contextualInfo=*/ {}, isDiscarded));
989
991
}
990
992
991
- if (!hadError)
992
- addResultDefault (
993
- cast<ClosureExpr>(context.getAsAbstractClosureExpr ().getPtrOrNull ()));
994
-
995
993
createConjunction (cs, elements, locator);
996
994
}
997
995
0 commit comments