[swift-users] Compiler refuses non-escaping closure calls in nested function

Zhao Xin owenzx at gmail.com
Mon Oct 10 06:15:00 CDT 2016


Thank you, Ole. Your reply teaches me a lot.

Zhaoxin

On Mon, Oct 10, 2016 at 6:52 PM, Ole Begemann via swift-users <
swift-users at swift.org> wrote:

> The line "let result = closure(n)" is refused by the compiler with the
>> error message "declaration over non closing parameter may allow it to
>> escape".
>>
>> First off, while I know what an escaping or a non-escaping closure is, I
>> find this error message utterly impossible to understand. To begin with,
>> the sentence "non closing parameter" is meaningless to me.
>>
>
> The error message I'm seeing in Xcode 8.0 is "Declaration closing over
> *non-escaping* parameter 'closure' may allow it to escape", so I don't know
> where you're seeing the "non closing parameter". And "non-escaping
> parameter" does make a lot more sense, I think.
>
> In any case, my main function is passed a non-escaping closure. I want
>> to call it from inside it, the compiler is ok with. I want also to call
>> it from a nested function, but the compiler disagrees.
>>
>> I believe the compiler should not complain here. Did I miss anything?
>>
>
> I think the error message is actually quite good, given that the compiler
> apparently is taking some shortcuts to prove that a parameter doesn't
> escape.
>
> By declaring a function that closes over the non-escaping parameter,
> you're creating a situation that *may* allow the non-escaping closure to
> escape, i.e. the compiler can't guarantee anymore that it won't escape. For
> example, you could do assign the `closureDoubled` function to a variable
> that's outside the scope of `mainFunction`:
>
>     // Variable outside the scope of mainFunction
>     var f: (Int) -> (Int) = { $0 }
>
>     func mainFunction(closure: (Int) -> Int) -> Int {
>
>         func closureDoubled(_ n: Int) -> Int {
>             let result = closure(n)
>             return 2*result
>         }
>
>         // closure would escape here
>         f = closureDoubled
>         ...
>     }
>
>     mainFunction { $0 }
>     f(5)
>
> If this were allowed, `closure` would be able to escape. I think this
> possibility explains the error message.
>
> Now the compiler *could* of course check for this and I think you're right
> in arguing that it *should* ideally perform more sophisticated checks, but
> since it currently seems to be taking some shortcuts in guaranteeing that a
> parameter doesn't escape, it has to disallow anything it can't verify as
> correct.
>
> Ole
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20161010/3c5a2bcd/attachment.html>


More information about the swift-users mailing list