@@ -1071,6 +1071,61 @@ bool BindingSet::favoredOverConjunction(Constraint *conjunction) const {
1071
1071
if (forClosureResult () || forGenericParameter ())
1072
1072
return false ;
1073
1073
}
1074
+
1075
+ auto *locator = conjunction->getLocator ();
1076
+ if (locator->directlyAt <ClosureExpr>()) {
1077
+ auto *closure = castToExpr<ClosureExpr>(locator->getAnchor ());
1078
+
1079
+ if (auto transform = CS.getAppliedResultBuilderTransform (closure)) {
1080
+ // Conjunctions that represent closures with result builder transformed
1081
+ // bodies could be attempted right after their resolution if they meet
1082
+ // all of the following criteria:
1083
+ //
1084
+ // - Builder type doesn't have any unresolved generic parameters;
1085
+ // - Closure doesn't have any parameters;
1086
+ // - The contextual result type is either concrete or opaque type.
1087
+ auto contextualType = transform->contextualType ;
1088
+ if (!(contextualType && contextualType->is <FunctionType>()))
1089
+ return true ;
1090
+
1091
+ auto *contextualFnType =
1092
+ CS.simplifyType (contextualType)->castTo <FunctionType>();
1093
+ {
1094
+ auto resultType = contextualFnType->getResult ();
1095
+ if (resultType->hasTypeVariable ()) {
1096
+ auto *typeVar = resultType->getAs <TypeVariableType>();
1097
+ // If contextual result type is represented by an opaque type,
1098
+ // it's a strong indication that body is self-contained, otherwise
1099
+ // closure might rely on external types flowing into the body for
1100
+ // disambiguation of `build{Partial}Block` or `buildFinalResult`
1101
+ // calls.
1102
+ if (!(typeVar && typeVar->getImpl ().isOpaqueType ()))
1103
+ return true ;
1104
+ }
1105
+ }
1106
+
1107
+ // If some of the closure parameters are unresolved, the conjunction
1108
+ // has to be delayed to give them a chance to be inferred.
1109
+ if (llvm::any_of (contextualFnType->getParams (), [](const auto ¶m) {
1110
+ return param.getPlainType ()->hasTypeVariable ();
1111
+ }))
1112
+ return true ;
1113
+
1114
+ // Check whether conjunction has any unresolved type variables
1115
+ // besides the variable that represents the closure.
1116
+ //
1117
+ // Conjunction could refer to declarations from outer context
1118
+ // (i.e. a variable declared in the outer closure) or generic
1119
+ // parameters of the builder type), if any of such references
1120
+ // are not yet inferred the conjunction has to be delayed.
1121
+ auto *closureType = CS.getType (closure)->castTo <TypeVariableType>();
1122
+ return llvm::any_of (
1123
+ conjunction->getTypeVariables (), [&](TypeVariableType *typeVar) {
1124
+ return !(typeVar == closureType || CS.getFixedType (typeVar));
1125
+ });
1126
+ }
1127
+ }
1128
+
1074
1129
return true ;
1075
1130
}
1076
1131
0 commit comments