@@ -289,6 +289,22 @@ static void diagnoseCaptureLoc(ASTContext &Context, DeclContext *DC,
289
289
}
290
290
}
291
291
292
+ static bool isNonEscapingFunctionValue (SILValue value) {
293
+ auto type = value->getType ().getASTType ();
294
+
295
+ // Look through box types to handle mutable 'var' bindings.
296
+ if (auto boxType = dyn_cast<SILBoxType>(type)) {
297
+ for (auto field : boxType->getLayout ()->getFields ()) {
298
+ if (field.getLoweredType ()->isNoEscape ())
299
+ return true ;
300
+ }
301
+
302
+ return false ;
303
+ }
304
+
305
+ return type->isNoEscape ();
306
+ }
307
+
292
308
// Diagnose this partial_apply if it captures a non-escaping value and has
293
309
// an escaping use.
294
310
static void checkPartialApply (ASTContext &Context, DeclContext *DC,
@@ -314,9 +330,8 @@ static void checkPartialApply(ASTContext &Context, DeclContext *DC,
314
330
315
331
// Captures of noescape function types or tuples containing noescape
316
332
// function types cannot escape.
317
- if (value-> getType (). getASTType ()-> isNoEscape ()) {
333
+ if (isNonEscapingFunctionValue (value))
318
334
noEscapeCaptures.push_back (&oper);
319
- }
320
335
}
321
336
322
337
// A partial_apply without non-escaping captures is always valid.
@@ -416,7 +431,7 @@ static void checkPartialApply(ASTContext &Context, DeclContext *DC,
416
431
static void checkApply (ASTContext &Context, FullApplySite site) {
417
432
auto isNoEscapeParam = [&](SILValue value) -> const ParamDecl * {
418
433
// If the value is an escaping, do not enforce any restrictions.
419
- if (!value-> getType (). getASTType ()-> isNoEscape ( ))
434
+ if (!isNonEscapingFunctionValue (value ))
420
435
return nullptr ;
421
436
422
437
// If the value is not a function parameter, do not enforce any restrictions.
0 commit comments