@@ -207,27 +207,11 @@ SILGenFunction::emitSiblingMethodRef(SILLocation loc,
207
207
methodTy, subs);
208
208
}
209
209
210
- ManagedValue SILGenFunction::emitFunctionRef (SILLocation loc,
211
- SILDeclRef constant,
212
- SILConstantInfo constantInfo) {
213
- // If the function has captures, apply them.
214
- if (auto fn = constant.getAnyFunctionRef ()) {
215
- if (fn->getCaptureInfo ().hasLocalCaptures () ||
216
- fn->getCaptureInfo ().hasGenericParamCaptures ()) {
217
- return emitClosureValue (loc, constant, *fn);
218
- }
219
- }
220
-
221
- // Otherwise, use a global FunctionRefInst.
222
- SILValue c = emitGlobalFunctionRef (loc, constant, constantInfo);
223
- return ManagedValue::forUnmanaged (c);
224
- }
225
-
226
210
void SILGenFunction::emitCaptures (SILLocation loc,
227
- AnyFunctionRef TheClosure ,
211
+ AnyFunctionRef closure ,
228
212
CaptureEmission purpose,
229
213
SmallVectorImpl<ManagedValue> &capturedArgs) {
230
- auto captureInfo = SGM.Types .getLoweredLocalCaptures (TheClosure );
214
+ auto captureInfo = SGM.Types .getLoweredLocalCaptures (closure );
231
215
// For boxed captures, we need to mark the contained variables as having
232
216
// escaped for DI diagnostics.
233
217
SmallVector<SILValue, 2 > escapesToMark;
@@ -349,31 +333,38 @@ void SILGenFunction::emitCaptures(SILLocation loc,
349
333
350
334
ManagedValue
351
335
SILGenFunction::emitClosureValue (SILLocation loc, SILDeclRef constant,
352
- AnyFunctionRef TheClosure) {
336
+ CanType expectedType,
337
+ ArrayRef<Substitution> subs) {
338
+ auto closure = *constant.getAnyFunctionRef ();
339
+ auto captureInfo = closure.getCaptureInfo ();
340
+
353
341
assert (((constant.uncurryLevel == 1 &&
354
- TheClosure. getCaptureInfo () .hasLocalCaptures ()) ||
342
+ captureInfo .hasLocalCaptures ()) ||
355
343
(constant.uncurryLevel == 0 &&
356
- !TheClosure. getCaptureInfo () .hasLocalCaptures ())) &&
344
+ !captureInfo .hasLocalCaptures ())) &&
357
345
" curried local functions not yet supported" );
358
346
359
347
auto constantInfo = getConstantInfo (constant);
360
348
SILValue functionRef = emitGlobalFunctionRef (loc, constant, constantInfo);
361
349
SILType functionTy = functionRef->getType ();
362
350
363
- auto expectedType =
364
- cast<FunctionType>(TheClosure.getType ()->getCanonicalType ());
365
-
366
- // Forward substitutions from the outer scope.
367
-
351
+ // Apply substitutions.
368
352
auto pft = constantInfo.SILFnType ;
369
353
370
- auto forwardSubs = constantInfo.getForwardingSubstitutions (getASTContext ());
371
-
372
354
bool wasSpecialized = false ;
373
- if (pft->isPolymorphic () && !forwardSubs.empty ()) {
355
+ if (pft->isPolymorphic ()) {
356
+ // If the lowered function type is generic but Sema did not hand us any
357
+ // substitutions, the function is a local function that appears in a
358
+ // generic context but does not have a generic parameter list of its own;
359
+ // just use our forwarding substitutions.
360
+ if (subs.empty ()) {
361
+ assert (closure.getAsDeclContext ()->isLocalContext () &&
362
+ " cannot reference generic global function without substitutions" );
363
+ subs = getForwardingSubstitutions ();
364
+ }
374
365
auto specialized = pft->substGenericArgs (F.getModule (),
375
366
F.getModule ().getSwiftModule (),
376
- forwardSubs );
367
+ subs );
377
368
functionTy = SILType::getPrimitiveObjectType (specialized);
378
369
wasSpecialized = true ;
379
370
}
@@ -382,19 +373,19 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
382
373
// globals, but we still need to mark them as escaping so that DI can flag
383
374
// uninitialized uses.
384
375
if (this == SGM.TopLevelSGF ) {
385
- SGM.emitMarkFunctionEscapeForTopLevelCodeGlobals (loc,
386
- TheClosure. getCaptureInfo () );
376
+ SGM.emitMarkFunctionEscapeForTopLevelCodeGlobals (
377
+ loc, captureInfo );
387
378
}
388
379
389
- if (!TheClosure. getCaptureInfo () .hasLocalCaptures () && !wasSpecialized) {
380
+ if (!captureInfo .hasLocalCaptures () && !wasSpecialized) {
390
381
auto result = ManagedValue::forUnmanaged (functionRef);
391
382
return emitOrigToSubstValue (loc, result,
392
383
AbstractionPattern (expectedType),
393
384
expectedType);
394
385
}
395
386
396
387
SmallVector<ManagedValue, 4 > capturedArgs;
397
- emitCaptures (loc, TheClosure , CaptureEmission::PartialApplication,
388
+ emitCaptures (loc, closure , CaptureEmission::PartialApplication,
398
389
capturedArgs);
399
390
400
391
// The partial application takes ownership of the context parameters.
@@ -405,15 +396,42 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
405
396
SILType closureTy =
406
397
SILGenBuilder::getPartialApplyResultType (functionRef->getType (),
407
398
capturedArgs.size (), SGM.M ,
408
- forwardSubs );
399
+ subs );
409
400
auto toClosure =
410
401
B.createPartialApply (loc, functionRef, functionTy,
411
- forwardSubs , forwardedArgs, closureTy);
402
+ subs , forwardedArgs, closureTy);
412
403
auto result = emitManagedRValueWithCleanup (toClosure);
413
404
414
- return emitOrigToSubstValue (loc, result,
415
- AbstractionPattern (expectedType),
416
- expectedType);
405
+ // Get the lowered AST types:
406
+ // - the original type
407
+ auto origLoweredFormalType =
408
+ AbstractionPattern (constantInfo.LoweredInterfaceType );
409
+ if (captureInfo.hasLocalCaptures ()) {
410
+ // Get the unlowered formal type of the constant, stripping off
411
+ // the first level of function application, which applies captures.
412
+ origLoweredFormalType =
413
+ AbstractionPattern (constantInfo.FormalInterfaceType )
414
+ .getFunctionResultType ();
415
+
416
+ // Lower it, being careful to use the right generic signature.
417
+ origLoweredFormalType =
418
+ AbstractionPattern (
419
+ origLoweredFormalType.getGenericSignature (),
420
+ SGM.Types .getLoweredASTFunctionType (
421
+ cast<FunctionType>(origLoweredFormalType.getType ()),
422
+ 0 , constant));
423
+ }
424
+
425
+ // - the substituted type
426
+ auto substFormalType = cast<FunctionType>(expectedType);
427
+ auto substLoweredFormalType =
428
+ SGM.Types .getLoweredASTFunctionType (substFormalType, 0 , constant);
429
+
430
+ // Generalize if necessary.
431
+ result = emitOrigToSubstValue (loc, result, origLoweredFormalType,
432
+ substLoweredFormalType);
433
+
434
+ return result;
417
435
}
418
436
419
437
void SILGenFunction::emitFunction (FuncDecl *fd) {
0 commit comments