@@ -1071,6 +1071,61 @@ bool BindingSet::favoredOverConjunction(Constraint *conjunction) const {
10711071 if (forClosureResult () || forGenericParameter ())
10721072 return false ;
10731073 }
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+
10741129 return true ;
10751130}
10761131
0 commit comments