@@ -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
}
@@ -905,6 +910,8 @@ class SyntacticElementConstraintGenerator
905
910
}
906
911
907
912
void visitBraceStmt (BraceStmt *braceStmt) {
913
+ auto &ctx = cs.getASTContext ();
914
+
908
915
if (context.isSingleExpressionClosure (cs)) {
909
916
for (auto node : braceStmt->getElements ()) {
910
917
if (auto expr = node.dyn_cast <Expr *>()) {
@@ -922,7 +929,36 @@ class SyntacticElementConstraintGenerator
922
929
return ;
923
930
}
924
931
925
- auto &ctx = cs.getASTContext ();
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
+ }
926
962
927
963
if (isChildOf (StmtKind::Case)) {
928
964
auto *caseStmt = cast<CaseStmt>(
@@ -1122,39 +1158,6 @@ class SyntacticElementConstraintGenerator
1122
1158
};
1123
1159
}
1124
1160
1125
- bool ConstraintSystem::generateConstraints (ClosureExpr *closure) {
1126
- auto &ctx = closure->getASTContext ();
1127
-
1128
- if (participatesInInference (closure)) {
1129
- SyntacticElementConstraintGenerator generator (
1130
- *this , SyntacticElementContext::forClosure (closure),
1131
- getConstraintLocator (closure));
1132
-
1133
- generator.visit (closure->getBody ());
1134
-
1135
- if (closure->hasSingleExpressionBody ())
1136
- return generator.hadError ;
1137
- }
1138
-
1139
- // If this closure has an empty body and no explicit result type
1140
- // let's bind result type to `Void` since that's the only type empty body
1141
- // can produce. Otherwise, if (multi-statement) closure doesn't have
1142
- // an explicit result (no `return` statements) let's default it to `Void`.
1143
- if (!hasExplicitResult (closure)) {
1144
- auto constraintKind =
1145
- (closure->hasEmptyBody () && !closure->hasExplicitResultType ())
1146
- ? ConstraintKind::Bind
1147
- : ConstraintKind::Defaultable;
1148
-
1149
- addConstraint (
1150
- constraintKind, getClosureType (closure)->getResult (),
1151
- ctx.TheEmptyTupleType ,
1152
- getConstraintLocator (closure, ConstraintLocator::ClosureResult));
1153
- }
1154
-
1155
- return false ;
1156
- }
1157
-
1158
1161
bool ConstraintSystem::generateConstraints (AnyFunctionRef fn, BraceStmt *body) {
1159
1162
NullablePtr<ConstraintLocator> locator;
1160
1163
0 commit comments