<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div>Updated proposal: use a method that accepts a closure to delineate the required guaranteed lifetime for which the assertion by the programmer holds.<div class="">And, hopefully, no optimizer language speak.<br class=""><div class=""><br class=""><div class=""><br class=""></div><div class=""><h1 style="box-sizing: border-box; font-size: 2.25em; margin-right: 0px; margin-bottom: 16px; margin-left: 0px; line-height: 1.2; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255); margin-top: 0px !important;" class="">Add an API to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: inherit; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Unmanaged</code> to get the instance it holds <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: inherit; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@guaranteed</code></h1><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">Proposal: <a href="https://github.com/aschwaighofer/swift-evolution/blob/unmanaged_unsafe_guaranteed_proposal/proposals/0000-unsafe-guaranteed.md" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">SE-0000 Add an API to Unmanaged to get the instance it holds guaranteed</a></li><li style="box-sizing: border-box;" class="">Author(s): <a href="https://github.com/aschwaighofer" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">Arnold Schwaighofer</a></li><li style="box-sizing: border-box;" class="">Status: <strong style="box-sizing: border-box;" class="">Draft</strong></li><li style="box-sizing: border-box;" class="">Review manager: TBD</li></ul><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-introduction" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/blob/unmanaged_unsafe_guaranteed_proposal/proposals/0000-unsafe-guaranteed.md#introduction" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Introduction</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The standard library <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Unmanged<Instance></code> struct provides an instance wrapper that does not participate in ARC; it allows the user to make manual retain/release calls and get at the contained instance at balanced/unbalanced retain counts.</p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">This proposal suggests to add another method <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">withUnsafeGuaranteedValue</code> to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Unmanaged</code> that accepts a closure. Calling this method is akin to making an assertion about the guaranteed lifetime of the instance for the delinated scope of the method invocation. The closure is passed the unmanaged reference as a managed reference.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class=""> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doSomething</span>(u <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> Unmanged<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Owned<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>) {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// The programmer asserts that there exists another managed reference of the</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// unmanaged reference stored in 'u' and that the lifetime of the referenced</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// instance is guaranteed to extend beyond the 'withUnsafeGuaranteedValue'</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// invocation.</span>
u<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>withUnsafeGuaranteedValue {
$<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">0</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>doSomething()
}
}</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">This assertion will help the compiler remove ARC operations.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">struct</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Unmanaged</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Instance <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">AnyObject</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Get the value of the unmanaged referenced as a managed reference without</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// consuming an unbalanced retain of it and pass it to the closure. Asserts</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// that there is some other reference ('the owning reference') to the</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// unmanaged reference that guarantees the lifetime of the unmanaged reference</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// for the duration of the 'withUnsafeGuaranteedValue' call.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// NOTE: You are responsible for ensuring this by making the owning reference's</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// lifetime fixed for the duration of the 'withUnsafeGuaranteedValue' call.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Violation of this will incur undefined behavior.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// A lifetime of a reference 'the instance' is fixed over a point in the</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// programm if:</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// * There is another managed reference to the same instance 'the instance'</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// whose life time is fixed over the point in the program by means of</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// 'withExtendedLifetime' closing over this point.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// var owningReference = Instance()</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// ...</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// withExtendedLifetime(owningReference) {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// point($0)</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Or if:</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// * There is a class, or struct instance ('owner') whose lifetime is fixed at</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// the point and which has a stored property that references 'the instance'</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// for the duration of the fixed lifetime of the 'owner'.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// class Owned {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// class Owner {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// final var owned : Owned</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// func foo() {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// withExtendedLifetime(self) {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// doSomething(...)</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// } // Assuming: No stores to owned occur for the dynamic lifetime of</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// // the withExtendedLifetime invocation.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// func doSomething() {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// // both 'self' and 'owned''s lifetime is fixed over this point.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// point(self, owned)</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// The last rule applies transitively through a chains of stored references</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// and nested structs.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Examples:</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// var owningReference = Instance()</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// ...</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// withExtendedLifetime(owningReference) {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// let u = Unmanaged.passUnretained(owningReference)</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// for i in 0 ..< 100 {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// u.withUnsafeGuaranteedValue {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// $0.doSomething()</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// class Owner {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// final var owned : Owned</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// func foo() {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// withExtendedLifetime(self) {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// doSomething(Unmanaged.passUnretained(owned))</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">//</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// func doSomething(u : Unmanged<Owned>) {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// u.withUnsafeGuaranteedValue {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// $0.doSomething()</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// }</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">withUnsafeGuaranteedValue</span><Result>(
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">@noescape</span> closure: (Instance) throws <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> Result
) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">rethrows</span> {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> instance <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> _value
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> (guaranteedInstance, token) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> Builtin<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>unsafeGuaranteed(instance)
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">try</span> closure(guaranteedInstance)
Builtin<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>unsafeGuaranteedEnd(token)
}</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Prototype: <a href="https://github.com/aschwaighofer/swift/tree/unsafe_guaranteed_prototype" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">link to a prototype implementation</a></p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-motivation" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/blob/unmanaged_unsafe_guaranteed_proposal/proposals/0000-unsafe-guaranteed.md#motivation" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Motivation</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">A user can often make assertions that an instance is kept alive by another reference to it for the duration of some scope.</p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Consider the following example:</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> Owned {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doSomeWork</span>() {}
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> Owner {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> ref: Owned
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">init</span>() { ref <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> Owned() }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doWork</span>() {
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">withExtendedLifetime</span>(<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">self</span>) {
doSomething(ref)
}
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doSomething</span>(o: Owned) {
o<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>doSomeWork()
}
}</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">In this context the lifetime of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Owner</code> always exceeds <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">o: Ownee</code>. However, there is currently no way to tell the compiler about such an assertion. We can pass reference counted values in an <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Unmanged</code> container without incurring reference count changes.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> Owner {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doWork</span>() {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// No reference count for passing the parameter.</span>
doSomething(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Unmanaged</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>passUnretained(ref))
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doSomething</span>(u: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Unmanaged</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Owned<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>) {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// ...</span>
}
}</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">We can get at the contained instance by means of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">takeUnretainedValue()</code> which will return a balanced retained value: the value is returned at <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">+1</code> for release by the caller. However, when it comes to accessing the contained instance we incur reference counting.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class=""> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doSomething</span>(u: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Unmanaged</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Owned<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>) {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Incurs refcount increment before the call and decrement after for self.</span>
u<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">takeUnretainedValue</span>()<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>doSomeWork()
}</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">With the proposed API call the user could make the assertion that <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">u</code>'s contained instance's lifetime is guaranteed by another reference to it.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class=""> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">doSomething</span>(u: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Unmanaged</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Owned<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>) {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Incurs refcount increment before the call and decrement after for self</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// that can be removed by the compiler based on the assertion made.</span>
u<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>withUnsafeGuaranteedValue {
$<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">0</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>doSomeWork()
}
}</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The compiler can easily remove the reference counts marked by this method call with local reasoning.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-impact-on-existing-code" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/blob/unmanaged_unsafe_guaranteed_proposal/proposals/0000-unsafe-guaranteed.md#impact-on-existing-code" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Impact on existing code</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">This is a new API that does not replace an existing method. No existing code should be affected.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-alternatives-considered" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/blob/unmanaged_unsafe_guaranteed_proposal/proposals/0000-unsafe-guaranteed.md#alternatives-considered" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Alternatives considered</h2><div style="box-sizing: border-box; margin-top: 0px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class="">A somewhat related proposal would be to allow for class types to completely opt out of ARC forcing the programmer to perform manual reference counting. The scope of such a proposal would be much bigger making it questionable for Swift 3 inclusion. I believe that the two approaches are complementary and don't completely supplant each other. This proposal's approach allows for selectively opting out of ARC while providing a high notational burdon when wide spread over the application (wrapping and unwrapping of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Unmanaged</code>). Opting completely out of ARC is an all-in solution, which on the other hand does not have the high notational burden.</div><div style="box-sizing: border-box; margin-top: 0px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class=""><br class=""></div><div style="box-sizing: border-box; margin-top: 0px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class=""><br class=""></div><blockquote type="cite" class="">On Mar 15, 2016, at 4:06 PM, Dave Abrahams <<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>> wrote:<br class=""><br class=""><br class="">on Mon Mar 14 2016, John McCall <<a href="http://rjmccall-at-apple.com" class="">rjmccall-AT-apple.com</a>> wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">In this example this would be for the lifetime for the value in x which extends to the lifetime of y.<br class=""></blockquote><br class="">What if I return it or assign it to non-local memory?<br class=""><br class="">I feel like you’re trying to define this by optimizer behavior.<br class="">That’s not a workable language rule; programmers are not going to<br class="">reason about SSA values.<br class=""></blockquote><br class="">Thank you, John. That is the problem I usually have with evaluating<br class="">most optimizer proposals.<br class=""></blockquote><br class=""></div></div></div></body></html>