@@ -139,6 +139,7 @@ class PartialApplySimplificationPass : public SILModuleTransform {
139
139
static bool isSimplePartialApply (SILModule &M,
140
140
CanSILFunctionType calleeTy,
141
141
TypeExpansionContext context,
142
+ ParameterConvention calleeConvention,
142
143
unsigned numPartiallyAppliedArgs,
143
144
bool isOnStack) {
144
145
if (calleeTy->isPolymorphic ()) {
@@ -157,6 +158,7 @@ static bool isSimplePartialApply(SILModule &M,
157
158
158
159
auto contextParam = calleeTy->getSelfParameter ();
159
160
161
+ auto argTy = contextParam.getArgumentType (M, calleeTy, context);
160
162
if (isOnStack) {
161
163
switch (contextParam.getConvention ()) {
162
164
case ParameterConvention::Indirect_Inout:
@@ -167,13 +169,11 @@ static bool isSimplePartialApply(SILModule &M,
167
169
return true ;
168
170
169
171
case ParameterConvention::Direct_Guaranteed:
170
- case ParameterConvention::Direct_Unowned: {
171
- auto argTy = contextParam.getArgumentType (M, calleeTy, context);
172
+ case ParameterConvention::Direct_Unowned:
172
173
return SILType::getPrimitiveObjectType (argTy)
173
174
.isPointerSizeAndAligned (M, context.getResilienceExpansion ());
174
175
// TODO: If we're running as an IRGen pass, use IRGen's version of
175
176
// `isPointerSizeAndAligned` as a more accurate check.
176
- }
177
177
178
178
// +1 arguments need a thunk to stage a copy for the callee to consume.
179
179
case ParameterConvention::Direct_Owned:
@@ -185,12 +185,16 @@ static bool isSimplePartialApply(SILModule &M,
185
185
return false ;
186
186
}
187
187
188
- // TODO: Handle native-refcounted classes, single-refcounted aggregates,
189
- // and bit-packable trivial types using knowledge from IRGen if this becomes
190
- // an IRGenPrepare pass
191
- if (!isa<SILBoxType>(contextParam.getInterfaceType ())) {
188
+ // The context parameter's convention must match the callee convention of
189
+ // the resulting closure.
190
+ if (contextParam.getConvention () != calleeConvention) {
192
191
return false ;
193
192
}
193
+
194
+ // The context type must consist of only a swift-refcounted object
195
+ // reference.
196
+ return SILType::getPrimitiveObjectType (argTy)
197
+ .isSingleSwiftRefcounted (M, context.getResilienceExpansion ());
194
198
}
195
199
196
200
return true ;
@@ -200,6 +204,7 @@ static bool isSimplePartialApply(PartialApplyInst *i) {
200
204
return isSimplePartialApply (i->getModule (),
201
205
i->getCallee ()->getType ().castTo <SILFunctionType>(),
202
206
i->getFunction ()->getTypeExpansionContext (),
207
+ i->getFunctionType ()->getCalleeConvention (),
203
208
i->getNumArguments (),
204
209
i->isOnStack ());
205
210
}
@@ -323,6 +328,7 @@ void PartialApplySimplificationPass::processKnownCallee(SILFunction *callee,
323
328
if (isSimplePartialApply (callee->getModule (),
324
329
calleeTyAsMethod,
325
330
examplePA->getFunction ()->getTypeExpansionContext (),
331
+ examplePA->getFunctionType ()->getCalleeConvention (),
326
332
examplePA->getNumArguments (),
327
333
examplePA->isOnStack ())) {
328
334
return rewriteKnownCalleeConventionOnly (callee, pa, examplePA,
0 commit comments