Skip to content

Commit 969324d

Browse files
committed
[NFC] CSApply: Introduce generalized and convenience routines for building single curry thunks
1 parent f257252 commit 969324d

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

lib/Sema/CSApply.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)