@@ -289,6 +289,22 @@ static void diagnoseCaptureLoc(ASTContext &Context, DeclContext *DC,
289289 }
290290}
291291
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+
292308// Diagnose this partial_apply if it captures a non-escaping value and has
293309// an escaping use.
294310static void checkPartialApply (ASTContext &Context, DeclContext *DC,
@@ -314,9 +330,8 @@ static void checkPartialApply(ASTContext &Context, DeclContext *DC,
314330
315331 // Captures of noescape function types or tuples containing noescape
316332 // function types cannot escape.
317- if (value-> getType (). getASTType ()-> isNoEscape ()) {
333+ if (isNonEscapingFunctionValue (value))
318334 noEscapeCaptures.push_back (&oper);
319- }
320335 }
321336
322337 // A partial_apply without non-escaping captures is always valid.
@@ -416,7 +431,7 @@ static void checkPartialApply(ASTContext &Context, DeclContext *DC,
416431static void checkApply (ASTContext &Context, FullApplySite site) {
417432 auto isNoEscapeParam = [&](SILValue value) -> const ParamDecl * {
418433 // If the value is an escaping, do not enforce any restrictions.
419- if (!value-> getType (). getASTType ()-> isNoEscape ( ))
434+ if (!isNonEscapingFunctionValue (value ))
420435 return nullptr ;
421436
422437 // If the value is not a function parameter, do not enforce any restrictions.
0 commit comments