@@ -1116,6 +1116,80 @@ namespace {
11161116 return callExpr;
11171117 }
11181118
1119+ // / Build a "{ args in base.fn(args) }" single-expression curry thunk.
1120+ // /
1121+ // / \param baseExpr The base expression to be captured, if warranted.
1122+ // / \param fnExpr The expression to be called by consecutively applying
1123+ // / the optional \p baseExpr and thunk parameters.
1124+ // / \param declOrClosure The underlying function-like declaration or
1125+ // / closure we're going to call.
1126+ // / \param thunkTy The type of the thunk.
1127+ // / \param locator The locator pinned on the function reference carried
1128+ // / by \p fnExpr. If the function has associated applied property wrappers,
1129+ // / the locator is used to pull them in.
1130+ AutoClosureExpr *buildSingleCurryThunk (Expr *baseExpr, Expr *fnExpr,
1131+ DeclContext *declOrClosure,
1132+ FunctionType *thunkTy,
1133+ ConstraintLocatorBuilder locator) {
1134+ auto &ctx = cs.getASTContext ();
1135+
1136+ const OptionSet<ParameterList::CloneFlags> options =
1137+ (ParameterList::Implicit | ParameterList::NamedArguments);
1138+ auto *const thunkParamList =
1139+ getParameterList (declOrClosure)->clone (ctx, options);
1140+
1141+ for (const auto idx : indices (*thunkParamList)) {
1142+ auto *param = thunkParamList->get (idx);
1143+ auto arg = thunkTy->getParams ()[idx];
1144+
1145+ param->setInterfaceType (arg.getParameterType ()->mapTypeOutOfContext ());
1146+ param->setSpecifier (ParamDecl::getParameterSpecifierForValueOwnership (
1147+ arg.getValueOwnership ()));
1148+ }
1149+
1150+ auto *const thunk =
1151+ new (ctx) AutoClosureExpr (/* set body later*/ nullptr , thunkTy,
1152+ AutoClosureExpr::InvalidDiscriminator, dc);
1153+ thunk->setParameterList (thunkParamList);
1154+ thunk->setThunkKind (AutoClosureExpr::Kind::SingleCurryThunk);
1155+ cs.cacheType (thunk);
1156+
1157+ Expr *thunkBody = buildSingleCurryThunkBodyCall (
1158+ baseExpr, fnExpr, declOrClosure, thunkParamList, locator);
1159+
1160+ // Coerce to the result type of the thunk.
1161+ thunkBody = coerceToType (thunkBody, thunkTy->getResult (), locator);
1162+
1163+ if (thunkTy->getExtInfo ().isThrowing ()) {
1164+ thunkBody = new (ctx)
1165+ TryExpr (thunkBody->getStartLoc (), thunkBody, cs.getType (thunkBody),
1166+ /* implicit=*/ true );
1167+ cs.cacheType (thunkBody);
1168+ }
1169+
1170+ thunk->setBody (thunkBody);
1171+
1172+ return thunk;
1173+ }
1174+
1175+ // / Build a "{ args in fn(args) }" single-expression curry thunk.
1176+ // /
1177+ // / \param fnExpr The expression to be called by applying the thunk
1178+ // / parameters.
1179+ // / \param declOrClosure The underlying function-like declaration or
1180+ // / closure we're going to call.
1181+ // / \param locator The locator pinned on the function reference carried
1182+ // / by \p fnExpr. If the function has associated applied property wrappers,
1183+ // / the locator is used to pull them in.
1184+ AutoClosureExpr *buildSingleCurryThunk (Expr *fnExpr,
1185+ DeclContext *declOrClosure,
1186+ ConstraintLocatorBuilder locator) {
1187+ auto *const thunkTy = cs.getType (fnExpr)->castTo <FunctionType>();
1188+
1189+ return buildSingleCurryThunk (/* baseExpr=*/ nullptr , fnExpr, declOrClosure,
1190+ thunkTy, locator);
1191+ }
1192+
11191193 AutoClosureExpr *buildPropertyWrapperFnThunk (
11201194 Expr *fnRef, FunctionType *fnType, AnyFunctionRef fnDecl, ConcreteDeclRef ref,
11211195 ArrayRef<AppliedPropertyWrapper> appliedPropertyWrappers) {
0 commit comments