[swift-evolution] [Proposal] Add an API to Unmanaged to get the instance it holds "@guaranteed"

John McCall rjmccall at apple.com
Mon Mar 14 13:53:13 CDT 2016

> On Mar 14, 2016, at 8:00 AM, Arnold Schwaighofer <aschwaighofer at apple.com> wrote:
> I would like to propose adding an additional method to the standard library’s ‘Unmanaged’ wrapper to mark values as having a guaranteed lifetime by another reference to it.
> Currently, there is no way to opt out of ARC even if we know the lifetime of a value is guaranteed by another reference to it. We can pass around values in the wrapper without incurring reference counting but as soon as we take the instance out of the wrapper we will incur reference counting.
> func doSomething(u: Unmanaged<Owned>) {
>     // Incurs refcount increment before the call and decrement after for self.
>     u.takeUnretainedValue().doSomeWork()
> The addition of this API will allow selectively disabling ARC for the scope of the lifetime of the value returned by this API call.

Calling this method makes a semantic guarantee that the returned reference is being kept alive somehow for a certain period of time.  So, the obvious questions here are:

1. What are the bounds of that period of time?
2. How can the user actually satisfy this guarantee?
3. What happens if they’re wrong?

#1 is totally unclear in your proposal.  Usually we do this sort of scoping thing with a callback, rather than a property, for exactly the reason that it lets us naturally bound the extent of the guarantee.  The library’s implementation of that function would then use some builtin functions to bound how long the guarantee lasts.  If we decide that that’s too awkward to actually use, we could burn this into the language as a custom result convention and invent some language rules for the guaranteed extents of such a result based on how the expression is used; that would permit more APIs to opt in to a +0 guaranteed result, but the language rules would probably be pretty ad hoc.  

#2 is also uncertain.  In ObjC ARC, we have a concept of an “object with precise lifetime semantics”.  (Here, “object” is used in the C/C++ sense of “variable”, not the reference-type-OO sense of “class instance”.)  Globals always have precise lifetime semantics, locals can opt in with an attribute, and members depend on their container.  So one possible answer is to say that the value must be precisely referenced somehow, perhaps by the system.  That does require doing some leg work in the proposal (to import the concept of precise lifetime), the language (to allow locals to be made precise), and and the compiler/optimizer (to honor precise guarantees).

It sounds like the only reasonable answer for #3 is “it’s undefined behavior”.  That argues for putting “unsafe” somewhere in the name, although perhaps that’s already covered by the proposal to rename Unmanaged to UnsafeReference.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160314/54f3f1dc/attachment.html>

More information about the swift-evolution mailing list