my best current guess:
func executeOk(block: () -> Void) {
{ block() }()
}
this one compiles because the wrapping closure is also inferred to be non-escaping. this is visible in the AST dump output (see this, and note how there is no escaping tag on the corresponding closure_expr).
func execute1(block: () -> Void) {
let closure = { block() }
}
since the closure is stored in this case, the closure's function type is escaping (variables like this currently are always escaping AFAIK – see discussion here). but this compiles because the diagnostics check for an 'interesting' use of the escaped value, and there aren't any here.
func executeNOK(block: () -> Void) {
let closure = { block() } // compiler issue: Escaping closure captures non-escaping parameter 'block'
closure()
}
this one is similar to execute1 but fails to compile because there is a use of the escaping closure that captures the non-escaping parameter. that's treated as a violation of the escaping rules even though in your example it's clearly not actually escaping.
IIUC, the diagnostic you hit in the final case is implemented in DiagnoseInvalidEscapingCaptures.cpp if you're interested in the particulars. @Slava_Pestov will hopefully correct any errors in this assessment.