@@ -329,6 +329,26 @@ static void checkPartialApply(ASTContext &Context, DeclContext *DC,
329
329
}
330
330
}
331
331
332
+ // Enforce exclusivity restrictions on recursive uses of non-escaping closures.
333
+ // Exclusivity requires a Non-Escaping Recursion Restriction rule (SE-0176):
334
+ // A non-escaping closure A may not be recursively invoked during the
335
+ // execution of a non-escaping closure B which captures the same local
336
+ // variable or inout parameter unless:
337
+ // - A is defined within B or
338
+ // - A is a local function declaration which is referenced directly by B.
339
+ //
340
+ // This is conservatively approximated with a Non-Escaping Parameter Call
341
+ // Restriction rule (NPCR), as implemented below:
342
+ // A function may not call a non-escaping function parameter passing a
343
+ // non-escaping function parameter as an argument.
344
+ // For the purposes of this rule, a closure which captures a non-escaping
345
+ // function parameter is treated the same as the parameter.
346
+ //
347
+ // Note: The compiler does not enforce recursion via
348
+ // withoutActuallyEscaping. This undefined behavior is exposed to programmers.
349
+ //
350
+ // TODO: Verify that all uses of noescaping function arguments are SIL patterns
351
+ // that are recognized below to prove that this diagnostic is complete.
332
352
static void checkApply (ASTContext &Context, FullApplySite site) {
333
353
auto isNoEscapeParam = [&](SILValue value) -> const ParamDecl * {
334
354
// If the value is an escaping, do not enforce any restrictions.
0 commit comments