It's a limitation of the current implementation, documented in "Noncopyable variables captured by escaping closures" section of SE-0390. The following tests use consuming parameter, instead of non-copyable value, for simplicity. Test 1 is similar to the example in SE-0399. Test 2 emulates your usage.
func test1(x: consuming String) {
_ = consume x // error: missing reinitialization of inout parameter 'x' after consume while accessing memory
x = "abc"
let fn: () -> Void = { print(x) }
fn()
}
func test2(x: consuming String) {
let fn: () -> Void = { _ = consume x } // error: missing reinitialization of inout parameter 'x' after consume while accessing memory
fn()
}
PS: I think "inout parameter" in these error messages are incorrect.
PS2: As non-escaping closure doesn't have this issue, it appears that a variable referenced in defer code is considered captured by an escaping closure (that's my intuition too).