Escaping-ness of `Unsafe*Pointer`s

I was recently wondering, for no particular reason, if it is ever correct Swift to return any instance of the unsafe pointer types from any function?

Because, if so, or even if it is simply very rare to have an unsafe pointer one can validly return, I think we can have pointers take a page from functions, and make them require @escaping to be able to return one which was passed as a parameter.

An awful lot of interop with C requires pointers, and there's no reason why you can't build wrappers around those C functions. At the same time, C functions aren't annotated with an escaping/non-escaping distinction, so nearly any use of a C function that takes pointers as parameters would involve a withoutActuallyEscaping. Finally, it's easy to restrict what you can do with a function value because the only thing you might want to do today is call it or pass it somewhere else, but with a pointer you have all of the API on the pointer types themselves. So while this could definitely help with some things, I don't think it'll be a net win.

That said, tracking valid pointer lifetimes and producing compiler diagnostics and/or sanitizer-style errors when the rules are clearly broken would be great.

1 Like

Sure, SwiftNIO allows it in some cases. For example, in this function. The key thing that SwiftNIO does to enable this use-case is to provide an explicit object to manage the lifetime of the pointer you're about to escape, as you can see in this function.

The rule, as @jrose suggests, is ultimately that the lifetime of the pointer needs to be managed. If the pointer supports being held in a specific way, either due to a property of the underlying type or due to a property of the function, then there's no issue.

This is ultimately very difficult to police for all the reasons @jrose has outlined, most notably that C functions may always escape a pointer. In fact, the vast majority of my subtle correctness bugs around pointer lifecycle management have been to do with missing the fact that a C function may have escaped a pointer. I'm good at spotting that I don't do it in my Swift code, but every C function that accepts a pointer ultimately needs to be audited for safety.