<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hello, swift-evolution.</div><div class=""><br class=""></div><div class="">Memory ownership is a topic that keeps poking its head up here. &nbsp;Core team</div><div class="">members have mentioned several times that it's something we're interested in</div><div class="">working on. &nbsp;Questions sometimes get referred back to it, saying stuff like</div><div class="">"we're working on tools to let you control ARC a little better". &nbsp;It's even on the</div><div class="">short list of high-priority features for Swift 4:</div><div class=""><br class=""></div><div class="">&nbsp;&nbsp;<a href="https://github.com/apple/swift-evolution" class="">https://github.com/apple/swift-evolution</a></div><div class=""><br class=""></div><div class="">&nbsp;&nbsp;Memory ownership model: an (opt-in) Cyclone/Rust-inspired memory</div><div class="">&nbsp; ownership model is highly desired by systems programmers and for other</div><div class="">&nbsp; high-performance applications that want predictable and deterministic</div><div class="">&nbsp; performance. This feature will fundamentally shape the ABI, from low-level</div><div class="">&nbsp; language concerns such as "inout" and low-level "addressors" to its impact</div><div class="">&nbsp; on the standard library. While a full memory ownership model is likely&nbsp;too</div><div class="">&nbsp; large for Swift 4 stage 1, we need a comprehensive design to understand</div><div class="">&nbsp; how it will change the ABI.</div><div class=""><br class=""></div><div class="">But that's all pretty vague. &nbsp;What is ownership? &nbsp;What does it mean for</div><div class="">programmers? &nbsp;Is somebody ever going to actually write that comprehensive</div><div class="">design that was supposed to come out during Stage 1?</div><div class=""><br class=""></div><div class="">Well, here you go.</div><div class=""><br class=""></div><div class="">I want to emphasize that this document is two things. &nbsp;It is a *manifesto*,</div><div class="">because it describes the whole problem and presents a holistic solution to it.</div><div class="">And it is a *meta-proposal*, because that holistic solution imagines and a number</div><div class="">of changes, each of which is worthy of a proposal; it is, essentially, a proposal</div><div class="">that we write a bunch of smaller proposals for each of these changes. &nbsp;But it's</div><div class="">not actually a concrete proposal for those smaller changes: it's often lacking in</div><div class="">that level of detail, and it leaves a number of questions open. &nbsp;This document, itself,</div><div class="">will not undergo the formal evolution process. &nbsp;And it may be that some of these</div><div class="">changes aren't really necessary, or that they need major reconsideration before</div><div class="">they're appropriate for proposal. &nbsp;But our hope — my hope — is that this</div><div class="">document is sufficient for you to understand the holistic approach we're suggesting,</div><div class="">or at least puts you in a position where you're comfortable asking questions</div><div class="">and trying to figure it out.</div><div class=""><br class=""></div><div class="">So, like I said, this isn't a formal proposal. &nbsp;What, then, are we hoping to achieve?</div><div class="">Well, we want people to talk about it. &nbsp;We'd like to achieve a consensus about</div><div class="">whether this basic approach makes sense for the language and achieves its goals.</div><div class="">And, assuming that the consensus is "yes" and that we should go forward with it,</div><div class="">we'd like this document — and this thread — to serve as an introduction to the</div><div class="">topic that we can refer back to when we're proposing and discussing all of those</div><div class="">changes in the weeks to come.</div><div class=""><br class=""></div><div class="">With that said, let's get started.</div><div class=""><br class=""></div><div class="">John.</div><div class=""><br class=""></div><div class="">------------------------------------------------------------------</div><div class=""><br class=""></div><div class=""># Ownership</div><div class=""><br class=""></div><div class="">## Introduction</div><div class=""><br class=""></div><div class="">Adding "ownership" to Swift is a major feature with many benefits</div><div class="">for programmers. &nbsp;This document is both a "manifesto" and a</div><div class="">"meta-proposal" for ownership: it lays out the basic goals of</div><div class="">the work, describes a general approach for achieving those goals,</div><div class="">and proposes a number of specific changes and features, each of</div><div class="">which will need to be separately discussed in a smaller and more</div><div class="">targeted proposal. &nbsp;This document is intended to provide a framework</div><div class="">for understanding the contributions of each of those changes.</div><div class=""><br class=""></div><div class="">### Problem statement</div><div class=""><br class=""></div><div class="">The widespread use of copy-on-write value types in Swift has generally</div><div class="">been a success. &nbsp;It does, however, come with some drawbacks:</div><div class=""><br class=""></div><div class="">* Reference counting and uniqueness testing do impose some overhead.</div><div class=""><br class=""></div><div class="">* Reference counting provides deterministic performance in most cases,</div><div class="">&nbsp; but that performance can still be complex to analyze and predict.</div><div class=""><br class=""></div><div class="">* The ability to copy a value at any time and thus "escape" it forces</div><div class="">&nbsp; the underlying buffers to generally be heap-allocated. &nbsp;Stack allocation</div><div class="">&nbsp; is far more efficient but does require some ability to prevent, or at</div><div class="">&nbsp; least recognize, attempts to escape the value.</div><div class=""><br class=""></div><div class="">Certain kinds of low-level programming require stricter performance</div><div class="">guarantees. &nbsp;Often these guarantees are less about absolute performance</div><div class="">than *predictable* performance. &nbsp;For example, keeping up with an audio</div><div class="">stream is not a taxing job for a modern processor, even with significant</div><div class="">per-sample overheads, but any sort of unexpected hiccup is immediately</div><div class="">noticeable by users.</div><div class=""><br class=""></div><div class="">Another common programming task is to optimize existing code when something</div><div class="">about it falls short of a performance target. &nbsp;Often this means finding</div><div class="">"hot spots" in execution time or memory use and trying to fix them in some</div><div class="">way. &nbsp;When those hot spots are due to implicit copies, Swift's current</div><div class="">tools for fixing the problem are relatively poor; for example, a programmer</div><div class="">can fall back on using unsafe pointers, but this loses a lot of the</div><div class="">safety benefits and expressivity advantages of the library collection types.</div><div class=""><br class=""></div><div class="">We believe that these problems can be addressed with an opt-in set of</div><div class="">features that we collectively call *ownership*.</div><div class=""><br class=""></div><div class="">### What is ownership?</div><div class=""><br class=""></div><div class="">*Ownership* is the responsibility of some piece of code to</div><div class="">eventually cause a value to be destroyed. &nbsp;An *ownership system*</div><div class="">is a set of rules or conventions for managing and transferring</div><div class="">ownership.</div><div class=""><br class=""></div><div class="">Any language with a concept of destruction has a concept of</div><div class="">ownership. &nbsp;In some languages, like C and non-ARC Objective-C,</div><div class="">ownership is managed explicitly by programmers. &nbsp;In other</div><div class="">languages, like C++ (in part), ownership is managed by the</div><div class="">language. &nbsp;Even languages with implicit memory management still</div><div class="">have libraries with concepts of ownership, because there are</div><div class="">other program resources besides memory, and it is important</div><div class="">to understand what code has the responsibility to release</div><div class="">those resources.</div><div class=""><br class=""></div><div class="">Swift already has an ownership system, but it's "under the covers":</div><div class="">it's an implementation detail that programmers have little</div><div class="">ability to influence. &nbsp;What we are proposing here is easy</div><div class="">to summarize:</div><div class=""><br class=""></div><div class="">- We should add a core rule to the ownership system, called</div><div class="">&nbsp; the Law of Exclusivity, which requires the implementation</div><div class="">&nbsp; to prevent variables from being simultaneously accessed</div><div class="">&nbsp; in conflicting ways. &nbsp;(For example, being passed `inout`</div><div class="">&nbsp; to two different functions.) &nbsp;This will not be an opt-in</div><div class="">&nbsp; change, but we believe that most programs will not be</div><div class="">&nbsp; adversely affected.</div><div class=""><br class=""></div><div class="">- We should add features to give programmers more control over</div><div class="">&nbsp; the ownership system, chiefly by allowing the propagation</div><div class="">&nbsp; of "shared" values. &nbsp;This will be an opt-in change; it</div><div class="">&nbsp; will largely consist of annotations and language features</div><div class="">&nbsp; which programmers can simply not use.</div><div class=""><br class=""></div><div class="">- We should add features to allow programmers to express</div><div class="">&nbsp; types with unique ownership, which is to say, types that</div><div class="">&nbsp; cannot be implicitly copied. &nbsp;This will be an opt-in</div><div class="">&nbsp; feature intended for experienced programmers who desire</div><div class="">&nbsp; this level of control; we do not intend for ordinary</div><div class="">&nbsp; Swift programming to require working with such types.</div><div class=""><br class=""></div><div class="">These three tentpoles together have the effect of raising</div><div class="">the ownership system from an implementation detail to a more</div><div class="">visible aspect of the language. &nbsp;They are also somewhat</div><div class="">inseparable, for reasons we'll explain, although of course they</div><div class="">can be prioritized differently. &nbsp;For these reasons, we will</div><div class="">talk about them as a cohensive feature called "ownership".</div><div class=""><br class=""></div><div class="">### A bit more detail</div><div class=""><br class=""></div><div class="">The basic problem with Swift's current ownership system</div><div class="">is copies, and all three tentpoles of ownership are about</div><div class="">avoiding copies.</div><div class=""><br class=""></div><div class="">A value may be used in many different places in a program.</div><div class="">The implementation has to ensure that some copy of the value</div><div class="">survives and is usable at each of these places. &nbsp;As long as</div><div class="">a type is copyable, it's always possible to satisfy that by</div><div class="">making more copies of the value. &nbsp;However, most uses don't</div><div class="">actually require ownership of their own copy. &nbsp;Some do: a</div><div class="">variable that didn't own its current value would only be</div><div class="">able to store values that were known to be owned by something</div><div class="">else, which isn't very useful in general. &nbsp;But a simple thing</div><div class="">like reading a value out of a class instance only requires that</div><div class="">the instance still be valid, not that the code doing the</div><div class="">read actually own a reference to it itself. &nbsp;Sometimes the</div><div class="">difference is obvious, but often it's impossible to know.</div><div class="">For example, the compiler generally doesn't know how an</div><div class="">arbitrary function will use its arguments; it just falls</div><div class="">back on a default rule for whether to pass ownership of</div><div class="">the value. &nbsp;When that default rule is wrong, the program</div><div class="">will end up making extra copies at runtime. &nbsp;So one simple</div><div class="">thing we can do is allow programs to be more explicit at</div><div class="">certain points about whether they need ownership or not.</div><div class=""><br class=""></div><div class="">That closely dovetails with the desire to support non-copyable</div><div class="">types. &nbsp;Most resources require a unique point of destruction:</div><div class="">a memory allocation can only be freed once, a file can only</div><div class="">be closed once, a lock can only be released once, and so on.</div><div class="">An owning reference to such a resource is therefore naturally</div><div class="">unique and thus non-copyable. &nbsp;Of course, we can artificially</div><div class="">allow ownership to be shared by, say, adding a reference count</div><div class="">and only destroying the resource when the count reaches zero.</div><div class="">But this can substantially increase the overhead of working</div><div class="">with the resource; and worse, it introduces problems with</div><div class="">concurrency and re-entrancy. &nbsp;If ownership is unique, and the</div><div class="">language can enforce that certain operations on a resource</div><div class="">can only be performed by the code that owns the resource,</div><div class="">then by construction only one piece of code can perform those</div><div class="">operations at a time. &nbsp;As soon as ownership is shareable,</div><div class="">that property disappears. &nbsp;So it is interesting for the</div><div class="">language to directly support non-copyable types because they</div><div class="">allow the expression of optimally-efficient abstractions</div><div class="">over resources. &nbsp;However, working with such types requires</div><div class="">all of the abstraction points like function arguments to</div><div class="">be correctly annotated about whether they transfer ownership,</div><div class="">because the compiler can no longer just make things work</div><div class="">behind the scenes by adding copies.</div><div class=""><br class=""></div><div class="">Solving either of these problems well will require us to</div><div class="">also solve the problem of non-exclusive access to variables.</div><div class="">Swift today allows nested accesses to the same variable;</div><div class="">for example, a single variable can be passed as two different</div><div class="">`inout` arguments, or a method can be passed a callback that</div><div class="">somehow accesses the same variable that the method was called on.</div><div class="">Doing this is mostly discouraged, but it's not forbidden,</div><div class="">and both the compiler and the standard library have to bend</div><div class="">over backwards to ensure that the program won't misbehave</div><div class="">too badly if it happens. &nbsp;For example, `Array` has to retain</div><div class="">its buffer during an in-place element modification; otherwise,</div><div class="">if that modification somehow reassigned the array variable,</div><div class="">the buffer would be freed while the element was still being</div><div class="">changed. &nbsp;Similarly, the compiler generally finds it difficult</div><div class="">to prove that values in memory are the same at different points</div><div class="">in a function, because it has to assume that any opaque</div><div class="">function call might rewrite all memory; as a result, it</div><div class="">often has to insert copies or preserve redundant loads</div><div class="">out of paranoia. &nbsp;Worse, non-exclusive access greatly</div><div class="">limits the usefulness of explicit annotations. &nbsp;For example,</div><div class="">a "shared" argument is only useful if it's really guaranteed</div><div class="">to stay valid for the entire call, but the only way to</div><div class="">reliably satisfy that for the current value of a variable</div><div class="">that can be re-entrantly modified is to make a copy and pass</div><div class="">that instead. &nbsp;It also makes certain important patterns</div><div class="">impossible, like stealing the current value of a variable</div><div class="">in order to build something new; this is unsound if the</div><div class="">variable can be accessed by other code in the middle.</div><div class="">The only solution to this is to establish a rule that prevents</div><div class="">multiple contexts from accessing the same variable at the</div><div class="">same time. &nbsp;This is what we propose to do with the Law</div><div class="">of Exclusivity.</div><div class=""><br class=""></div><div class="">All three of these goals are closely linked and mutually</div><div class="">reinforcing. &nbsp;The Law of Exclusivity allows explicit annotations</div><div class="">to actually optimize code by default and enables mandatory</div><div class="">idioms for non-copyable types. &nbsp;Explicit annotations create</div><div class="">more optimization opportunities under the Law and enable</div><div class="">non-copyable types to function. &nbsp;Non-copyable types validate</div><div class="">that annotations are optimal even for copyable types and</div><div class="">create more situations where the Law can be satisfied statically.</div><div class=""><br class=""></div><div class="">### Criteria for success</div><div class=""><br class=""></div><div class="">As discussed above, it is the core team's expectation that</div><div class="">ownership can be delivered as an opt-in enhancement to Swift.</div><div class="">Programmers should be able to largely ignore ownership and not</div><div class="">suffer for it. &nbsp;If this expectation proves to not be satisfiable,</div><div class="">we will reject ownership rather than imposing substantial</div><div class="">burdens on regular programs.</div><div class=""><br class=""></div><div class="">The Law of Exclusivity will impose some new static and dynamic</div><div class="">restrictions. &nbsp;It is our belief that these restrictions will only</div><div class="">affect a small amount of code, and only code that does things</div><div class="">that we already document as producing unspecified results.</div><div class="">These restrictions, when enforced dynamically, will also hurt</div><div class="">performance. &nbsp;It is our hope that this will be "paid for" by</div><div class="">the improved optimization potential. &nbsp;We will also provide tools</div><div class="">for programmers to eliminate these safety checks where necessary.</div><div class="">We will discuss these restrictions in greater detail later in this</div><div class="">document.</div><div class=""><br class=""></div><div class="">## Core definitions</div><div class=""><br class=""></div><div class="">### Values</div><div class=""><br class=""></div><div class="">Any discussion of ownership systems is bound to be at a lower</div><div class="">level of abstraction. &nbsp;We will be talking a lot about</div><div class="">implementation topics. &nbsp;In this context, when we say "value",</div><div class="">we mean a specific instance of a semantic, user-language value.</div><div class=""><br class=""></div><div class="">For example, consider the following Swift code:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; var x = [1,2,3]</div><div class="">&nbsp; var y = x</div><div class="">```</div><div class=""><br class=""></div><div class="">People would often say that `x` and `y` have the same value</div><div class="">at this point. &nbsp;Let's call this a *semantic value*. &nbsp;But at</div><div class="">the level of the implementation, because the variables `x` and `y`</div><div class="">can be independently modified, the value in `y` must be a</div><div class="">copy of the value in `x`. &nbsp;Let's call this a *value instance*.</div><div class="">A value instance can be moved around in memory and remain the</div><div class="">same value instance, but a copy always yields a new value instance.</div><div class="">For the remainder of this document, when we use "value" without any</div><div class="">qualification, we mean it in this low-level sense of value instance.</div><div class=""><br class=""></div><div class="">What it means to copy or destroy a value instance depends on the type:</div><div class=""><br class=""></div><div class="">* Some types do not require extra work besides copying their</div><div class="">&nbsp; byte-representation; we call these *trivial*. &nbsp;For example,</div><div class="">&nbsp; `Int` and `Float` are trivial types, as are ordinary `struct`s</div><div class="">&nbsp; and `enum`s containing only such values. &nbsp;Most of what we have</div><div class="">&nbsp; to say about ownership in this document doesn't apply to the</div><div class="">&nbsp; values of such types. &nbsp;However, the Law of Exclusivity will still</div><div class="">&nbsp; apply to them.</div><div class=""><br class=""></div><div class="">* For reference types, the value instance is a reference to an object.</div><div class="">&nbsp; Copying the value instance means making a new reference, which</div><div class="">&nbsp; increases the reference count. &nbsp;Destroying the value instance means</div><div class="">&nbsp; destroying a reference, which decreases the reference count. &nbsp;Decreasing</div><div class="">&nbsp; the reference count can, of course, drop it to zero and thus destroy</div><div class="">&nbsp; the object, but it's important to remember that all this talk about</div><div class="">&nbsp; copying and destroying values means manipulating reference counts,</div><div class="">&nbsp; not copying the object or (necessarily) destroying it.</div><div class=""><br class=""></div><div class="">* For copy-on-write types, the value instance includes a reference to</div><div class="">&nbsp; a buffer, which then works basically like a reference type. &nbsp;Again,</div><div class="">&nbsp; it is important to remember that copying the value doesn't mean</div><div class="">&nbsp; copying the contents of the buffer into a new buffer.</div><div class=""><br class=""></div><div class="">There are similar rules for every kind of type.</div><div class=""><br class=""></div><div class="">### Memory</div><div class=""><br class=""></div><div class="">In general, a value can be owned in one of two ways: it can be</div><div class="">"in flight", a temporary value owned by a specific execution context</div><div class="">which computed the value as an operand, or it can be "at rest",</div><div class="">stored in some sort of memory.</div><div class=""><br class=""></div><div class="">We don't need to focus much on temporary values because their</div><div class="">ownership rules are straightforward. &nbsp;Temporary values are created</div><div class="">as the result of some expression; that expression is used in some</div><div class="">specific place; the value is needed in that place and not</div><div class="">thereafter; so the implementation should clearly take all possible</div><div class="">steps to forward the value directly to that place instead of</div><div class="">forcing it to be copied. &nbsp;Users already expect all of this to</div><div class="">happen, and there's nothing really to improve here.</div><div class=""><br class=""></div><div class="">Therefore, most of our discussion of ownership will center around</div><div class="">values stored in memory. &nbsp;There are five closely related concepts</div><div class="">in Swift's treatment of memory.</div><div class=""><br class=""></div><div class="">A *storage declaration* is the language-syntax concept of a declaration</div><div class="">that can be treated in the language like memory. &nbsp;Currently, these are</div><div class="">always introduced with `let`, `var`, and `subscript`. &nbsp;A storage</div><div class="">declaration has a type. &nbsp;It also has an implementation which defines</div><div class="">what it means to read or write the storage. &nbsp;The default implementation</div><div class="">of a `var` or `let` just creates a new variable to store the value,</div><div class="">but storage declarations can also be computed, and so there needn't</div><div class="">be any variables at all behind one.</div><div class=""><br class=""></div><div class="">A *storage reference expression* is the syntax concept of an expression</div><div class="">that refers to storage. &nbsp;This is similar to the concept from other</div><div class="">languages of an "l-value", except that it isn't necessarily usable on</div><div class="">the left side of an assignment because the storage doesn't have to be</div><div class="">mutable.</div><div class=""><br class=""></div><div class="">A *storage reference* is the language-semantics concept of a fully</div><div class="">filled-in reference to a specific storage declaration. &nbsp;In other</div><div class="">words, it is the result of evaluating a storage reference expression</div><div class="">in the abstract, without actually accessing the storage. &nbsp;If the</div><div class="">storage is a member, this includes a value or storage reference</div><div class="">for the base. &nbsp;If the storage is a subscript, this includes a value</div><div class="">for the index. &nbsp;For example, a storage reference expression like</div><div class="">`widgets[i].weight` might abstractly evaluate to this storage reference:</div><div class=""><br class=""></div><div class="">* the storage for the property `var weight: Double` of</div><div class="">* the storage for the subscript `subscript(index: Int)` at index value `19: Int` of</div><div class="">* the storage for the local variable `var widgets: [Widget]`</div><div class=""><br class=""></div><div class="">A *variable* is the semantics concept of a unique place in</div><div class="">memory that stores a value. &nbsp;It's not necessarily mutable, at least</div><div class="">as we're using it in this document. &nbsp;Variables are usually created for</div><div class="">storage declarations, but they can also be created dynamically in</div><div class="">raw memory, e.g. using UnsafeRawPointer. &nbsp;A variable always has a</div><div class="">specific type. &nbsp;It also has a *lifetime*, i.e. a point in the language</div><div class="">semantics where it comes into existence and a point (or several)</div><div class="">where it is destroyed.</div><div class=""><br class=""></div><div class="">A *memory location* is a contiguous range of addressable memory. &nbsp;In</div><div class="">Swift, this is mostly an implementation concept. &nbsp;Swift does not</div><div class="">guarantee that any particular variable will have a consistent memory</div><div class="">location throughout its lifetime, or in fact be stored in a memory</div><div class="">location at all. &nbsp;But a variable can sometimes be temporarily forced</div><div class="">to exist at a specific, consistent location: e.g. it can be passed</div><div class="">`inout` to `withUnsafeMutablePointer`.</div><div class=""><br class=""></div><div class="">### Accesses</div><div class=""><br class=""></div><div class="">A particular evaluation of a storage reference expression is</div><div class="">called an access. &nbsp;Accesses come in three kinds: *reads*,</div><div class="">*assignments*, and *modifications*. &nbsp;Assignments and modifications</div><div class="">are both *writes*, with the difference being that an assignment</div><div class="">completely replaces the old value without reading it, while a</div><div class="">modification does rely on the old value.</div><div class=""><br class=""></div><div class="">All storage reference expressions are classified into one of these</div><div class="">three kinds of access based on the context in which the expression</div><div class="">appears. &nbsp;It is important to note that this decision is superficial:</div><div class="">it relies only on the semantic rules of the immediate context, not</div><div class="">on a deeper analysis of the program or its dynamic behavior.</div><div class="">For example, a storage reference passed as an `inout` argument</div><div class="">is always evaluated as a modification in the caller, regardless</div><div class="">of whether the callee actually uses the current value, performs</div><div class="">any writes to it, or even refers to it at all.</div><div class=""><br class=""></div><div class="">The evaluation of a storage reference expression is divided into</div><div class="">two phases: it is first formally evaluated to a storage reference,</div><div class="">and then a formal access to that storage reference occurs for some</div><div class="">duration. &nbsp;The two phases are often evaluated in immediate</div><div class="">succession, but they can be separated in complex cases, such as</div><div class="">when an `inout` argument is not the last argument to a call.</div><div class="">The purpose of this phase division is to minimize the duration of</div><div class="">the formal access while still preserving, to the greatest extent</div><div class="">possible, Swift's left-to-right evaluation rules.</div><div class=""><br class=""></div><div class="">## The Law of Exclusivity</div><div class=""><br class=""></div><div class="">With all of that established, we can succinctly state the first</div><div class="">part of this proposal, the Law of Exclusivity:</div><div class=""><br class=""></div><div class="">&gt; If a storage reference expression evaluates to a storage</div><div class="">&gt; reference that is implemented by a variable, then the formal</div><div class="">&gt; access duration of that access may not overlap the formal</div><div class="">&gt; access duration of any other access to the same variable</div><div class="">&gt; unless both accesses are reads.</div><div class=""><br class=""></div><div class="">This is intentionally vague: it merely says that accesses</div><div class="">"may not" overlap, without specifying how that will be</div><div class="">enforced. &nbsp;This is because we will use different enforcement</div><div class="">mechanisms for different kinds of storage. &nbsp;We will discuss</div><div class="">those mechanisms in the next major section. &nbsp;First, however,</div><div class="">we need to talk in general about some of the implications of</div><div class="">this rule and our approach to satisfying it.</div><div class=""><br class=""></div><div class="">### Duration of exclusivity</div><div class=""><br class=""></div><div class="">The Law says that accesses must be exclusive for their entire</div><div class="">formal access duration. &nbsp;This duration is determined by the</div><div class="">immediate context which causes the access; that is, it's a</div><div class="">*static* property of the program, whereas the safety problems</div><div class="">we laid out in the introduction are *dynamic*. &nbsp;It is a general</div><div class="">truth that static approaches to dynamic problems can only be</div><div class="">conservatively correct: there will be dynamically-reasonable</div><div class="">programs that are nonetheless rejected. &nbsp;It is fair to ask how</div><div class="">that general principle applies here.</div><div class=""><br class=""></div><div class="">For example, when storage is passed as an `inout` argument, the</div><div class="">access lasts for the duration of the call. &nbsp;This demands</div><div class="">caller-side enforcement that no other accesses can occur to</div><div class="">that storage during the call. Is it possible that this is too</div><div class="">coarse-grained? &nbsp;After all, there may be many points within the</div><div class="">called function where it isn't obviously using its `inout`</div><div class="">argument. &nbsp;Perhaps we should track accesses to `inout` arguments</div><div class="">at a finer-grained level, within the callee, instead of attempting</div><div class="">to enforce the Law of Exclusivity in the caller. &nbsp;The problem</div><div class="">is that that idea is simply too dynamic to be efficiently</div><div class="">implemented.</div><div class=""><br class=""></div><div class="">A caller-side rule for `inout` has one key advantage: the</div><div class="">caller has an enormous amount of information about what</div><div class="">storage is being passed. &nbsp;This means that a caller-side rule</div><div class="">can often be enforced purely statically, without adding dynamic</div><div class="">checks or making paranoid assumptions. &nbsp;For example, suppose</div><div class="">that a function calls a `mutating` method on a local variable.</div><div class="">(Recall that `mutating` methods are passed `self` as an `inout`</div><div class="">argument.) &nbsp;Unless the variable has been captured in an</div><div class="">escaping closure, the function can easily examine every</div><div class="">access to the variable to see that none of them overlap</div><div class="">the call, thus proving that the rule is satisfied. &nbsp;Moreover,</div><div class="">that guarantee is then passed down to the callee, which can</div><div class="">use that information to prove the safety of its own accesses.</div><div class=""><br class=""></div><div class="">In contrast, a callee-side rule for `inout` cannot take</div><div class="">advantage of that kind of information: the information is</div><div class="">simply discarded at the point of the call. &nbsp;This leads to the</div><div class="">widespread optimization problems that we see today, as</div><div class="">discussed in the introduction. &nbsp;For example, suppose that</div><div class="">the callee loads a value from its argument, then calls</div><div class="">a function which the optimizer cannot reason about:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; extension Array {</div><div class="">&nbsp; &nbsp; mutating func organize(_ predicate: (Element) -&gt; Bool) {</div><div class="">&nbsp; &nbsp; &nbsp; let first = self[0]</div><div class="">&nbsp; &nbsp; &nbsp; if !predicate(first) { return }</div><div class="">&nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; &nbsp; // something here uses first</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">Under a callee-side rule, the optimizer must copy `self[0]`</div><div class="">into `first` because it must assume (paranoidly) that</div><div class="">`predicate` might somehow turn around and modify the</div><div class="">variable that `self` was bound to. &nbsp;Under a caller-side</div><div class="">rule, the optimizer can use the copy of value held in the</div><div class="">array element for as long as it can continue to prove that</div><div class="">the array hasn't been modified.</div><div class=""><br class=""></div><div class="">Moreover, as the example above suggests, what sort of code</div><div class="">would we actually be enabling by embracing a callee-side rule?</div><div class="">A higher-order operation like this should not have to worry</div><div class="">about the caller passing in a predicate that re-entrantly</div><div class="">modifies the array. &nbsp;Simple implementation choices, like</div><div class="">making the local variable `first` instead of re-accessing</div><div class="">`self[0]` in the example above, would become semantically</div><div class="">important; maintaining any sort of invariant would be almost</div><div class="">inconceivable. &nbsp;It is no surprise that Swift's libraries</div><div class="">generally forbid this kind of re-entrant access. &nbsp;But,</div><div class="">since the library can't completely prevent programmers</div><div class="">from doing it, the implementation must nonetheless do extra</div><div class="">work at runtime to prevent such code from running into</div><div class="">undefined behavior and corrupting the process. &nbsp;Because it</div><div class="">exists solely to work around the possibility of code that</div><div class="">should never occur in a well-written program, we see this</div><div class="">as no real loss.</div><div class=""><br class=""></div><div class="">Therefore, this proposal generally proposes access-duration</div><div class="">rules like caller-side `inout` enforcement, which allow</div><div class="">substantial optimization opportunities at little semantic</div><div class="">cost.</div><div class=""><br class=""></div><div class="">### Components of value and reference types</div><div class=""><br class=""></div><div class="">We've been talking about *variables* a lot. &nbsp;A reader might</div><div class="">reasonably wonder what all this means for *properties*.</div><div class=""><br class=""></div><div class="">Under the definition we laid out above, a property is a</div><div class="">storage declaration, and a stored property creates a</div><div class="">corresponding variable in its container. &nbsp;Accesses to that</div><div class="">variable obviously need to obey the Law of Exclusivity, but are</div><div class="">there any additional restrictions in play due to the fact</div><div class="">that the properties are organized together into a container?</div><div class="">In particular, should the Law of Exclusivity prevent accesses</div><div class="">to different properties of the same variable or value from</div><div class="">overlapping?</div><div class=""><br class=""></div><div class="">Properties can be classified into three groups:</div><div class="">- instance properties of value types,</div><div class="">- instance properties of reference types, and</div><div class="">- `static` and `class` properties on any kind of type.</div><div class=""><br class=""></div><div class="">We propose to always treat reference-type and `static` properties</div><div class="">as independent from one another other, but to treat value-type</div><div class="">properties as generally non-independent outside of a specific</div><div class="">(but important) special case. &nbsp;That's a potentially significant</div><div class="">restriction, and it's reasonable to wonder both why it's necessary</div><div class="">and why we need to draw this distinction between different</div><div class="">kinds of property. &nbsp;There are three reasons.</div><div class=""><br class=""></div><div class="">#### Independence and containers</div><div class=""><br class=""></div><div class="">The first relates to the container.</div><div class=""><br class=""></div><div class="">For value types, it is possible to access both an individual</div><div class="">property and the entire aggregate value. &nbsp;It is clear that an</div><div class="">access to a property can conflict with an access to the aggregate,</div><div class="">because an access to the aggregate is essentially an access to</div><div class="">all of the properties at once. &nbsp;For example, consider a variable</div><div class="">(not necessarily a local one) `p: Point` with stored properties</div><div class="">`x`, `y`, and `z`. &nbsp;If it were possible to simultaneously and</div><div class="">independently modify `p` and `p.x`, that would be an enormous</div><div class="">hole in the Law of Exclusivity. &nbsp;So we do need to enforce the</div><div class="">Law somehow here. &nbsp;We have three options.</div><div class=""><br class=""></div><div class="">(This may make more sense after reading the main section</div><div class="">about enforcing the Law.)</div><div class=""><br class=""></div><div class="">The first option is to simply treat `p.x` as also an access to `p`.</div><div class="">This neatly eliminates the hole because whatever enforcement</div><div class="">we're using for `p` will naturally prevent conflicting accesses</div><div class="">to it. &nbsp;But this will also prevent accesses to different</div><div class="">properties from overlapping, because each will cause an access</div><div class="">to `p`, triggering the enforcement.</div><div class=""><br class=""></div><div class="">The other two options involve reversing that relationship.</div><div class="">We could split enforcement out for all the individual stored</div><div class="">properties, not for the aggregate: an access to `p` would be</div><div class="">treated as an access to `p.x`, `p.y`, and `p.z`. &nbsp;Or we could</div><div class="">parameterize enforcement and teach it to record the specific</div><div class="">path of properties being accessed: "", ".x", and so on.</div><div class="">Unfortunately, there are two problems with these schemes.</div><div class="">The first is that we don't always know the full set of</div><div class="">properties, or which properties are stored; the implementation</div><div class="">of a type might be opaque to us due to e.g. generics or</div><div class="">resilience. &nbsp;An access to a computed property must be treated</div><div class="">as an access to the whole value because it involves passing</div><div class="">the variable to a getter or setter either `inout` or `shared`;</div><div class="">thus it does actually conflict with all other properties.</div><div class="">Attempting to make things work despite that by using dynamic</div><div class="">information would introduce ubiquitous bookkeeping into</div><div class="">value-type accessors, endangering the core design goal of</div><div class="">value types that they serve as a low-cost abstraction tool.</div><div class="">The second is that, while these schemes can be applied to</div><div class="">static enforcement relatively easily, applying them to</div><div class="">dynamic enforcement would require a fiendish amount of</div><div class="">bookkeeping to be carried out dynamically; this is simply</div><div class="">not compatible with our performance goals.</div><div class=""><br class=""></div><div class="">Thus, while there is a scheme which allows independent access</div><div class="">to different properties of the same aggregate value, it</div><div class="">requires us to be using static enforcement for the aggregate</div><div class="">access and to know that both properties are stored. &nbsp;This is an</div><div class="">important special case, but it is just a special case.</div><div class="">In all other cases, we must fall back on the general rule</div><div class="">that an access to a property is also an access to the aggregate.</div><div class=""><br class=""></div><div class="">These considerations do not apply to `static` properties and</div><div class="">properties of reference types. &nbsp;There are no language constructs</div><div class="">in Swift which access every property of a class simultaneously,</div><div class="">and it doesn't even make sense to talk about "every" `static`</div><div class="">property of a type because an arbitrary module can add a new</div><div class="">one at any time.</div><div class=""><br class=""></div><div class="">#### Idioms of independent access</div><div class=""><br class=""></div><div class="">The second relates to user expectations.</div><div class=""><br class=""></div><div class="">Preventing overlapping accesses to different properties of a</div><div class="">value type is at most a minor inconvenience. &nbsp;The Law of Exclusivity</div><div class="">prevents "spooky action at a distance" with value types anyway:</div><div class="">for example, calling a method on a variable cannot kick off a</div><div class="">non-obvious sequence of events which eventually reach back and</div><div class="">modify the original variable, because that would involve two</div><div class="">conflicting and overlapping accesses to the same variable.</div><div class=""><br class=""></div><div class="">In contrast, many established patterns with reference types</div><div class="">depend on exactly that kind of notification-based update. &nbsp;In</div><div class="">fact, it's not uncommon in UI code for different properties of</div><div class="">the same object to be modified concurrently: one by the UI and</div><div class="">the other by some background operation. &nbsp;Preventing independent</div><div class="">access would break those idioms, which is not acceptable.</div><div class=""><br class=""></div><div class="">As for `static` properties, programmers expect them to be</div><div class="">independent global variables; it would make no sense for</div><div class="">an access to one global to prevent access to another.</div><div class=""><br class=""></div><div class="">#### Independence and the optimizer</div><div class=""><br class=""></div><div class="">The third relates to the optimization potential of properties.</div><div class=""><br class=""></div><div class="">Part of the purpose of the Law of Exclusivity is that it</div><div class="">allows a large class of optimizations on values. &nbsp;For example,</div><div class="">a non-`mutating` method on a value type can assume that `self`</div><div class="">remains exactly the same for the duration of the method. &nbsp;It</div><div class="">does not have to worry that an unknown function it calls</div><div class="">in the middle will somehow reach back and modify `self`,</div><div class="">because that modification would violate the Law. &nbsp;Even in a</div><div class="">`mutating` method, no code can access `self` unless the</div><div class="">method knows about it. &nbsp;Those assumptions are extremely</div><div class="">important for optimizing Swift code.</div><div class=""><br class=""></div><div class="">However, these assumptions simply cannot be done in general</div><div class="">for the contents of global variables or reference-type</div><div class="">properties. &nbsp;Class references can be shared arbitrarily,</div><div class="">and the optimizer must assume that an unknown function</div><div class="">might have access to the same instance. &nbsp;And any code in</div><div class="">the system can potentially access a global variable (ignoring</div><div class="">access control). &nbsp;So the language implementation would</div><div class="">gain little to nothing from treating accesses to different</div><div class="">properties as non-independent.</div><div class=""><br class=""></div><div class="">#### Subscripts</div><div class=""><br class=""></div><div class="">Much of this discussion also applies to subscripts, though</div><div class="">in the language today subscripts are never technically stored.</div><div class="">Accessing a component of a value type through a subscript</div><div class="">is treated as accessing the entire value, and so is considered</div><div class="">to overlap any other access to the value. &nbsp;The most important</div><div class="">consequence of this is that two different array elements cannot</div><div class="">be simultaneously accessed. &nbsp;This will interfere with certain</div><div class="">common idioms for working with arrays, although some cases</div><div class="">(like concurrently modifying different slices of an array)</div><div class="">are already quite problematic in Swift. &nbsp;We believe that we</div><div class="">can mitigate the majority of the impact here with targetted</div><div class="">improvements to the collection APIs.</div><div class=""><br class=""></div><div class="">## Enforcing the Law of Exclusivity</div><div class=""><br class=""></div><div class="">There are three available mechanisms for enforcing the Law of</div><div class="">Exclusivity: static, dynamic, and undefined. &nbsp;The choice</div><div class="">of mechanism must be decidable by a simple inspection of the</div><div class="">storage declaration, because the definition and all of its</div><div class="">direct accessors must agree on how it is done. &nbsp;Generally,</div><div class="">it will be decided by the kind of storage being declared,</div><div class="">its container (if any), and any attributes that might be</div><div class="">present.</div><div class=""><br class=""></div><div class="">### Static enforcement</div><div class=""><br class=""></div><div class="">Under static enforcement, the compiler detects that the</div><div class="">law is being violated and reports an error. &nbsp;This is the</div><div class="">preferred mechanism where possible because it is safe, reliable,</div><div class="">and imposes no runtime costs.</div><div class=""><br class=""></div><div class="">This mechanism can only be used when it is perfectly decidable.</div><div class="">For example, it can be used for value-type properties because</div><div class="">the Law, recursively applied, ensures that the base storage is</div><div class="">being exclusively accessed. &nbsp;It cannot be used for ordinary</div><div class="">reference-type properties because there is no way to prove in</div><div class="">general that a particular object reference is the unique</div><div class="">reference to an object. &nbsp;However, if we supported</div><div class="">uniquely-referenced class types, it could be used for their</div><div class="">properties.</div><div class=""><br class=""></div><div class="">In some cases, where desired, the compiler may be able to</div><div class="">preserve source compatibility and avoid an error by implicitly</div><div class="">inserting a copy instead. &nbsp;This likely something we would only</div><div class="">do in a source-compatibility mode.</div><div class=""><br class=""></div><div class="">Static enforcement will be used for:</div><div class=""><br class=""></div><div class="">- immutable variables of all kinds,</div><div class=""><br class=""></div><div class="">- local variables, except as affected by the use of closures</div><div class="">&nbsp; (see below),</div><div class=""><br class=""></div><div class="">- `inout` arguments, and</div><div class=""><br class=""></div><div class="">- instance properties of value types.</div><div class=""><br class=""></div><div class="">### Dynamic enforcement</div><div class=""><br class=""></div><div class="">Under dynamic enforcement, the implementation will maintain</div><div class="">a record of whether each variable is currently being accessed.</div><div class="">If a conflict is detected, it will trigger a dynamic failure.</div><div class="">The compiler may emit an error statically if it detects that</div><div class="">dynamic enforcement will always detect a conflict.</div><div class=""><br class=""></div><div class="">The bookkeeping requires two bits per variable, using a tri-state</div><div class="">of "unaccessed", "read", and "modified". &nbsp;Although multiple</div><div class="">simultaneous reads can be active at once, a full count can be</div><div class="">avoided by saving the old state across the access, with a little</div><div class="">cleverness.</div><div class=""><br class=""></div><div class="">The bookkeeping is intended to be best-effort. &nbsp;It should reliably</div><div class="">detect deterministic violations. &nbsp;It is not required to detect</div><div class="">race conditions; it often will, and that's good, but it's not</div><div class="">required to. &nbsp;It *is* required to successfully handle the case</div><div class="">of concurrent reads without e.g. leaving the bookkeeping record</div><div class="">permanently in the "read" state. &nbsp;But it is acceptable for the</div><div class="">concurrent-reads case to e.g. leave the bookkeeping record in</div><div class="">the "unaccessed" case even if there are still active readers;</div><div class="">this permits the bookkeeping to use non-atomic operations.</div><div class="">However, atomic operations would have to be used if the bookkeeping</div><div class="">records were packed into a single byte for, say, different</div><div class="">properties of a class, because concurrent accesses are</div><div class="">allowed on different variables within a class.</div><div class=""><br class=""></div><div class="">When the compiler detects that an access is "instantaneous",</div><div class="">in the sense that none of the code executed during the access</div><div class="">can possibly cause a re-entrant access to the same variable,</div><div class="">it can avoid updating the bookkeeping record and instead just</div><div class="">check that it has an appropriate value. &nbsp;This is common for</div><div class="">reads, which will often simply copy the value during the access.</div><div class="">When the compiler detects that all possible accesses are</div><div class="">instantaneous, e.g. if the variable is `private` or `internal`,</div><div class="">it can eliminate all bookkeeping. &nbsp;We expect this to be fairly</div><div class="">common.</div><div class=""><br class=""></div><div class="">Dynamic enforcement will be used for:</div><div class=""><br class=""></div><div class="">- local variables, when necessary due to the use of closures</div><div class="">&nbsp; (see below),</div><div class=""><br class=""></div><div class="">- instance properties of class types,</div><div class=""><br class=""></div><div class="">- `static` and `class` properties, and</div><div class=""><br class=""></div><div class="">- global variables.</div><div class=""><br class=""></div><div class="">We should provide an attribute to allow dynamic enforcement</div><div class="">to be downgraded to undefined enforcement for a specific</div><div class="">property or class. &nbsp;It is likely that some clients will find</div><div class="">the performance consequences of dynamic enforcement to be</div><div class="">excessive, and it will be important to provide them an opt-out.</div><div class="">This will be especially true in the early days of the feature,</div><div class="">while we're still exploring implementation alternatives and</div><div class="">haven't yet implemented any holistic optimizations.</div><div class=""><br class=""></div><div class="">Future work on isolating class instances may allow us to</div><div class="">use static enforcement for some class instance properties.</div><div class=""><br class=""></div><div class="">### Undefined enforcement</div><div class=""><br class=""></div><div class="">Undefined enforcement means that conflicts are not detected</div><div class="">either statically or dynamically, and instead simply have</div><div class="">undefined behavior. &nbsp;This is not a desireable mechanism</div><div class="">for ordinary code given Swift's "safe by default" design,</div><div class="">but it's the only real choice for things like unsafe pointers.</div><div class=""><br class=""></div><div class="">Undefined enforcement will be used for:</div><div class=""><br class=""></div><div class="">- the `memory` properties of unsafe pointers.</div><div class=""><br class=""></div><div class="">### Enforcement for local variables captured by closures</div><div class=""><br class=""></div><div class="">Our ability to statically enforce the Law of Exclusivity</div><div class="">relies on our ability to statically reason about where</div><div class="">uses occur. &nbsp;This analysis is usually straightforward for a</div><div class="">local variable, but it becomes complex when the variable is</div><div class="">captured in a closure because the control flow leading to</div><div class="">the use can be obscured. &nbsp;A closure can potentially be</div><div class="">executed re-entrantly or concurrently, even if it's known</div><div class="">not to escape. &nbsp;The following principles apply:</div><div class=""><br class=""></div><div class="">- If a closure `C` potentially escapes, then for any variable</div><div class="">&nbsp; `V` captured by `C`, all accesses to `V` potentially executed</div><div class="">&nbsp; after a potential escape (including the accesses within `C`</div><div class="">&nbsp; itself) must use dynamic enforcement unless all such acesses</div><div class="">&nbsp; are reads.</div><div class=""><br class=""></div><div class="">- If a closure `C` does not escape a function, then its</div><div class="">&nbsp; use sites within the function are known; at each, the closure</div><div class="">&nbsp; is either directly called or used as an argument to another</div><div class="">&nbsp; call. &nbsp;Consider the set of non-escaping closures used at</div><div class="">&nbsp; each such call. &nbsp;For each variable `V` captured by `C`, if</div><div class="">&nbsp; any of those closures contains a write to `V`, all accesses</div><div class="">&nbsp; within those closures must use dynamic enforcement, and</div><div class="">&nbsp; the call is treated for purposes of static enforcement</div><div class="">&nbsp; as if it were a write to `V`; otherwise, the accesses may use</div><div class="">&nbsp; static enforcement, and the call is treated as if it were a</div><div class="">&nbsp; read of `V`.</div><div class=""><br class=""></div><div class="">It is likely that these rules can be improved upon over time.</div><div class="">For example, we should be able to improve on the rule for</div><div class="">direct calls to closures.</div><div class=""><br class=""></div><div class="">## Explicit tools for ownership</div><div class=""><br class=""></div><div class="">### Shared values</div><div class=""><br class=""></div><div class="">A lot of the discussion in this section involves the new concept</div><div class="">of a *shared value*. &nbsp;As the name suggests, a shared value is a</div><div class="">value that has been shared with the current context by another</div><div class="">part of the program that owns it. &nbsp;To be consistent with the</div><div class="">Law of Exclusivity, because multiple parts of the program can</div><div class="">use the value at once, it must be read-only in all of them</div><div class="">(even the owning context). &nbsp;This concept allows programs to</div><div class="">abstract over values without copying them, just like `inout`</div><div class="">allows programs to abstract over variables.</div><div class=""><br class=""></div><div class="">(Readers familiar with Rust will see many similarities between</div><div class="">shared values and Rust's concept of an immutable borrow.)</div><div class=""><br class=""></div><div class="">When the source of a shared value is a storage reference, the</div><div class="">shared value acts essentially like an immutable reference</div><div class="">to that storage. &nbsp;The storage is accessed as a read for the</div><div class="">duration of the shared value, so the Law of Exclusivity</div><div class="">guarantees that no other accesses will be able to modify the</div><div class="">original variable during the access. &nbsp;Some kinds of shared</div><div class="">value may also bind to temporary values (i.e. an r-value).</div><div class="">Since temporary values are always owned by the current</div><div class="">execution context and used in one place, this poses no</div><div class="">additional semantic concerns.</div><div class=""><br class=""></div><div class="">A shared value can be used in the scope that binds it</div><div class="">just like an ordinary parameter or `let` binding.</div><div class="">If the shared value is used in a place that requires</div><div class="">ownership, Swift will simply implicitly copy the value —</div><div class="">again, just like an ordinary parameter or `let` binding.</div><div class=""><br class=""></div><div class="">#### Limitations of shared values</div><div class=""><br class=""></div><div class="">This section of the document describes several ways to form</div><div class="">and use shared values. &nbsp;However, our current design does not</div><div class="">provide general, "first-class" mechanisms for working with them.</div><div class="">A program cannot return a shared value, construct an array</div><div class="">of shared values, store shared values into `struct` fields,</div><div class="">and so on. &nbsp;These limitations are similar to the existing</div><div class="">limitations on `inout` references. &nbsp;In fact, the similarities</div><div class="">are so common that it will be useful to have a term that</div><div class="">encompasses both: we will call them *ephemerals*.</div><div class=""><br class=""></div><div class="">The fact that our design does not attempt to provide first-class</div><div class="">facilities for ephemerals is a well-considered decision,</div><div class="">born from a trio of concerns:</div><div class=""><br class=""></div><div class="">- We have to scope this proposal to something that can</div><div class="">&nbsp; conceivably be implemented in the coming months. &nbsp;We expect this</div><div class="">&nbsp; proposal to yield major benefits to the language and its</div><div class="">&nbsp; implementaton, but it is already quite broad and aggressive.</div><div class="">&nbsp; First-class ephemerals would add enough complexity to the</div><div class="">&nbsp; implementation and design that they are clearly out of scope.</div><div class="">&nbsp; Furthermore, the remaining language-design questions are</div><div class="">&nbsp; quite large; several existing languages have experimented</div><div class="">&nbsp; with first-class ephemerals, and the results haven't been</div><div class="">&nbsp; totally satisfactory.</div><div class=""><br class=""></div><div class="">- Type systems trade complexity for expressivity.</div><div class="">&nbsp; You can always accept more programs by making the type</div><div class="">&nbsp; system more sophisticated, but that's not always a good</div><div class="">&nbsp; trade-off. &nbsp;The lifetime-qualification systems behind</div><div class="">&nbsp; first-class references in languages like Rust add a lot</div><div class="">&nbsp; of complexity to the user model. &nbsp;That complexity has real</div><div class="">&nbsp; costs for users. &nbsp;And it's still inevitably necessary</div><div class="">&nbsp; to sometimes drop down to unsafe code to work around the</div><div class="">&nbsp; limitations of the ownership system. &nbsp;Given that a line</div><div class="">&nbsp; does have to drawn somewhere, it's not completely settled</div><div class="">&nbsp; that lifetime-qualification systems deserve to be on the</div><div class="">&nbsp; Swift side of the line.</div><div class=""><br class=""></div><div class="">- A Rust-like lifetime system would not necessarily be</div><div class="">&nbsp; as powerful in Swift as it is in Rust. &nbsp;Swift intentionally</div><div class="">&nbsp; provides a language model which reserves a lot of</div><div class="">&nbsp; implementation flexibility to both the authors of types</div><div class="">&nbsp; and to the Swift compiler itself.</div><div class=""><br class=""></div><div class="">&nbsp; For example, polymorphic storage is quite a bit more</div><div class="">&nbsp; flexible in Swift than it is in Rust. &nbsp;A</div><div class="">&nbsp; `MutableCollection` in Swift is required to implement a</div><div class="">&nbsp; `subscript` that provides accessor to an element for an index,</div><div class="">&nbsp; but the implementation can satisfy this pretty much any way</div><div class="">&nbsp; it wants. &nbsp;If generic code accesses this `subscript`, and it</div><div class="">&nbsp; happens to be implemented in a way that provides direct access</div><div class="">&nbsp; to the underlying memory, then the access will happen in-place;</div><div class="">&nbsp; but if the `subscript` is implemented with a computed getter</div><div class="">&nbsp; and setter, then the access will happen in a temporary</div><div class="">&nbsp; variable and the getter and setter will be called as necessary.</div><div class="">&nbsp; This only works because Swift's access model is highly</div><div class="">&nbsp; lexical and maintains the ability to run arbitrary code</div><div class="">&nbsp; at the end of an access. &nbsp;Imagine what it would take to</div><div class="">&nbsp; implement a loop that added these temporary mutable</div><div class="">&nbsp; references to an array — each iteration of the loop would</div><div class="">&nbsp; have to be able to queue up arbitrary code to run as a clean-up</div><div class="">&nbsp; when the function was finished with the array. &nbsp;This would</div><div class="">&nbsp; hardly be a low-cost abstraction! &nbsp;A more Rust-like</div><div class="">&nbsp; `MutableCollection` interface that worked within the</div><div class="">&nbsp; lifetime rules would have to promise that the `subscript`</div><div class="">&nbsp; returned a pointer to existing memory; and that wouldn't</div><div class="">&nbsp; allow a computed implementation at all.</div><div class=""><br class=""></div><div class="">&nbsp; A similar problem arises even with simple `struct` members.</div><div class="">&nbsp; The Rust lifetime rules say that, if you have a pointer to</div><div class="">&nbsp; a `struct`, you can make a pointer to a field of that `struct`</div><div class="">&nbsp; and it'll have the same lifetime as the original pointer.</div><div class="">&nbsp; But this assumes not only that the field is actually stored</div><div class="">&nbsp; in memory, but that it is stored *simply*, such that you can</div><div class="">&nbsp; form a simple pointer to it and that pointer will obey the</div><div class="">&nbsp; standard ABI for pointers to that type. &nbsp;This means that</div><div class="">&nbsp; Rust cannot use layout optimizations like packing boolean</div><div class="">&nbsp; fields together in a byte or even just decreasing the</div><div class="">&nbsp; alignment of a field. &nbsp;This is not a guarantee that we are</div><div class="">&nbsp; willing to make in Swift.</div><div class=""><br class=""></div><div class="">For all of these reasons, while we remain theoretically</div><div class="">interested in exploring the possibilities of a more</div><div class="">sophisticated system that would allow broader uses of</div><div class="">ephemerals, we are not proposing to take that on now. &nbsp;Since</div><div class="">such a system would primarily consist of changes to the type</div><div class="">system, we are not concerned that this will cause ABI-stability</div><div class="">problems in the long term. &nbsp;Nor are we concerned that we will</div><div class="">suffer from source incompatibilities; we believe that any</div><div class="">enhancements here can be done as extensions and generalizations</div><div class="">of the proposed features.</div><div class=""><br class=""></div><div class="">### Local ephemeral bindings</div><div class=""><br class=""></div><div class="">It is already a somewhat silly limitation that Swift provides</div><div class="">no way to abstract over storage besides passing it as an</div><div class="">`inout` argument. &nbsp;It's an easy limitation to work around,</div><div class="">since programmers who want a local `inout` binding can simply</div><div class="">introduce a closure and immediately call it, but that's an</div><div class="">awkward way of achieving something that ought to be fairly easy.</div><div class=""><br class=""></div><div class="">Shared values make this limitation even more apparent, because</div><div class="">a local shared value is an interesting alternative to a local `let`:</div><div class="">it avoids a copy at the cost of preventing other accesses to</div><div class="">the original storage. &nbsp;We would not encourage programmers to</div><div class="">use `shared` instead of `let` throughout their code, especially</div><div class="">because the optimizer will often be able to eliminate the copy</div><div class="">anyway. &nbsp;However, the optimizer cannot always remove the copy,</div><div class="">and so the `shared` micro-optimization can be useful in select</div><div class="">cases. &nbsp;Furthermore, eliminating the formal copy may also be</div><div class="">semantically necessary when working with non-copyable types.</div><div class=""><br class=""></div><div class="">We propose to remove this limitation in a straightforward way:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; inout root = &amp;tree.root</div><div class=""><br class=""></div><div class="">&nbsp; shared elements = self.queue</div><div class="">```</div><div class=""><br class=""></div><div class="">The initializer is required and must be a storage reference</div><div class="">expression. &nbsp;The access lasts for the remainder of the scope.</div><div class=""><br class=""></div><div class="">### Function parameters</div><div class=""><br class=""></div><div class="">Function parameters are the most important way in which</div><div class="">programs abstract over values. &nbsp;Swift currently provides</div><div class="">three kinds of argument-passing:</div><div class=""><br class=""></div><div class="">- Pass-by-value, owned. &nbsp;This is the rule for ordinary</div><div class="">&nbsp; arguments. &nbsp;There is no way to spell this explicitly.</div><div class=""><br class=""></div><div class="">- Pass-by-value, shared. &nbsp;This is the rule for the `self`</div><div class="">&nbsp; arguments of `nonmutating` methods. &nbsp;There is no way to</div><div class="">&nbsp; spell this explicitly.</div><div class=""><br class=""></div><div class="">- Pass-by-reference. &nbsp;This is the rule used for `inout`</div><div class="">&nbsp; arguments and the `self` arguments of `mutating` methods.</div><div class=""><br class=""></div><div class="">Our proposal here is just to allow the non-standard</div><div class="">cases to be spelled explicitly:</div><div class=""><br class=""></div><div class="">- A function argument can be explicitly declared `owned`:</div><div class=""><br class=""></div><div class="">&nbsp; ```</div><div class="">&nbsp; &nbsp; func append(_ values: owned [Element]) {</div><div class="">&nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; ```</div><div class=""><br class=""></div><div class="">&nbsp; This cannot be combined with `shared` or `inout`.</div><div class=""><br class=""></div><div class="">&nbsp; This is just an explicit way of writing the default, and</div><div class="">&nbsp; we do not expect that users will write it often unless</div><div class="">&nbsp; they're working with non-copyable types.</div><div class=""><br class=""></div><div class="">- A function argument can be explicitly declared `shared`.</div><div class=""><br class=""></div><div class="">&nbsp; ```</div><div class="">&nbsp; &nbsp; func ==(left: shared String, right: shared String) -&gt; Bool {</div><div class="">&nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; ```</div><div class=""><br class=""></div><div class="">&nbsp; This cannot be combined with `owned` or `inout`.</div><div class=""><br class=""></div><div class="">&nbsp; If the function argument is a storage reference expression,</div><div class="">&nbsp; that storage is accessed as a read for the duration of the</div><div class="">&nbsp; call. &nbsp;Otherwise, the argument expression is evaluated as</div><div class="">&nbsp; an r-value and that temporary value is shared for the call.</div><div class="">&nbsp; It's important to allow temporary values to be shared for</div><div class="">&nbsp; function arguments because many function parameters will be</div><div class="">&nbsp; marked as `shared` simply because the functions don't</div><div class="">&nbsp; actually from owning that parameter, not because it's in</div><div class="">&nbsp; any way semantically important that they be passed a</div><div class="">&nbsp; reference to an existing variable. &nbsp;For example, we expect</div><div class="">&nbsp; to change things like comparison operators to take their</div><div class="">&nbsp; parameters `shared`, because it needs to be possible to</div><div class="">&nbsp; compare non-copyable values without claiming them, but</div><div class="">&nbsp; this should not prevent programmers from comparing things</div><div class="">&nbsp; to literal values.</div><div class=""><br class=""></div><div class="">&nbsp; Like `inout`, this is part of the function type. &nbsp;Unlike</div><div class="">&nbsp; `inout`, most function compatibility checks (such as override</div><div class="">&nbsp; and function conversion checking) should succeed with a</div><div class="">&nbsp; `shared` / `owned` mismatch. &nbsp;If a function with an `owned`</div><div class="">&nbsp; parameter is converted to (or overrides) a function with a</div><div class="">&nbsp; `shared` parameter, the argument type must actually be</div><div class="">&nbsp; copyable.</div><div class=""><br class=""></div><div class="">- A method can be explicitly declared `consuming`.</div><div class=""><br class=""></div><div class="">&nbsp; ```</div><div class="">&nbsp; &nbsp; consuming func moveElements(into collection: inout [Element]) {</div><div class="">&nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; ```</div><div class=""><br class=""></div><div class="">&nbsp; This causes `self` to be passed as an owned value and therefore</div><div class="">&nbsp; cannot be combined with `mutating` or `nonmutating`.</div><div class=""><br class=""></div><div class="">&nbsp; `self` is still an immutable binding within the method.</div><div class=""><br class=""></div><div class="">### Function results</div><div class=""><br class=""></div><div class="">As discussed at the start of this section, Swift's lexical</div><div class="">access model does not extend well to allowing ephemerals</div><div class="">to be returned from functions. &nbsp;Performing an access requires</div><div class="">executing storage-specific code at both the beginning and</div><div class="">the end of the access. &nbsp;After a function returns, it has no</div><div class="">further ability to execute code.</div><div class=""><br class=""></div><div class="">We could, conceivably, return a callback along with the</div><div class="">ephemeral, with the expectation that the callback will be</div><div class="">executed when the caller is done with the ephemeral.</div><div class="">However, this alone would not be enough, because the callee</div><div class="">might be relying on guarantees from its caller. &nbsp;For example,</div><div class="">considering a `mutating` method on a `struct` which wants</div><div class="">to returns an `inout` reference to a stored property. &nbsp;The</div><div class="">correctness of this depends not only on the method being able</div><div class="">to clean up after the access to the property, but on the</div><div class="">continued validity of the variable to which `self` was bound.</div><div class="">What we really want is to maintain the current context in the</div><div class="">callee, along with all the active scopes in the caller, and</div><div class="">simply enter a new nested scope in the caller with the</div><div class="">ephemeral as a sort of argument. &nbsp;But this is a well-understood</div><div class="">situation in programming languages: it is just a kind of</div><div class="">co-routine. &nbsp;(Because of the scoping restrictions, it can</div><div class="">also be thought of as sugar for a callback function in</div><div class="">which `return`, `break`, etc. actually work as expected.)</div><div class=""><br class=""></div><div class="">In fact, co-routines are useful for solving a number of</div><div class="">problems relating to ephemerals. &nbsp;We will explore this</div><div class="">idea in the next few sub-sections.</div><div class=""><br class=""></div><div class="">### `for` loops</div><div class=""><br class=""></div><div class="">In the same sense that there are three interesting ways of</div><div class="">passing an argument, we can identify three interesting styles</div><div class="">of iterating over a sequence. &nbsp;Each of these can be expressed</div><div class="">with a `for` loop.</div><div class=""><br class=""></div><div class="">#### Consuming iteration</div><div class=""><br class=""></div><div class="">The first iteration style is what we're already familiar with</div><div class="">in Swift: a consuming iteration, where each step is presented</div><div class="">with an owned value. &nbsp;This is the only way we can iterate over</div><div class="">an arbitrary sequence where the values might be created on demand.</div><div class="">It is also important for working with collections of non-copyable</div><div class="">types because it allows the collection to be destructured and the</div><div class="">loop to take ownership of the elements. &nbsp;Because it takes ownership</div><div class="">of the values produced by a sequence, and because an arbitrary</div><div class="">sequence cannot be iterated multiple times, this is a</div><div class="">`consuming` operation on `Sequence`.</div><div class=""><br class=""></div><div class="">This can be explicitly requested by declaring the iteration</div><div class="">variable `owned`:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; for owned employee in company.employees {</div><div class="">&nbsp; &nbsp; newCompany.employees.append(employee)</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">It is also used implicitly when the requirements for a</div><div class="">non-mutating iteration are not met. &nbsp;(Among other things,</div><div class="">this is necessary for source compatibility.)</div><div class=""><br class=""></div><div class="">The next two styles make sense only for collections.</div><div class=""><br class=""></div><div class="">#### Non-mutating iteration</div><div class=""><br class=""></div><div class="">A non-mutating iteration simply visits each of the elements</div><div class="">in the collection, leaving it intact and unmodified. &nbsp;We have</div><div class="">no reason to copy the elements; the iteration variable can</div><div class="">simply be bound to a shared value. &nbsp;This is a `nonmutating`</div><div class="">operaton on `Collection`.</div><div class=""><br class=""></div><div class="">This can be explicitly requested by declaring the iteration</div><div class="">variable `shared`:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; for shared employee in company.employees {</div><div class="">&nbsp; &nbsp; if !employee.respected { throw CatastrophicHRFailure() }</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">It is also used by default when the sequence type is known to</div><div class="">conform to `Collection`, since this is the optimal way of</div><div class="">iterating over a collection.</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; for employee in company.employees {</div><div class="">&nbsp; &nbsp; if !employee.respected { throw CatastrophicHRFailure() }</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">If the sequence operand is a storage reference expression,</div><div class="">the storage is accessed for the duration of the loop. &nbsp;Note</div><div class="">that this means that the Law of Exclusivity will implicitly</div><div class="">prevent the collection from being modified during the</div><div class="">iteration. &nbsp;Programs can explicitly request an iteration</div><div class="">over a copy of the value in that storage by using the `copy`</div><div class="">intrinsic function on the operand.</div><div class=""><br class=""></div><div class="">#### Mutating iteration</div><div class=""><br class=""></div><div class="">A mutating iteration visits each of the elements and</div><div class="">potentially changes it. &nbsp;The iteration variable is an</div><div class="">`inout` reference to the element. &nbsp;This is a `mutating`</div><div class="">operation on `MutableCollection`.</div><div class=""><br class=""></div><div class="">This must be explicitly requested by declaring the</div><div class="">iteration variable `inout`:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; for inout employee in company.employees {</div><div class="">&nbsp; &nbsp; employee.respected = true</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">The sequence operand must be a storage reference expression.</div><div class="">The storage will be accessed for the duraton of the loop,</div><div class="">which (as above) will prevent any other overlapping accesses</div><div class="">to the collection. &nbsp;(But this rule does not apply if the</div><div class="">collection type defines the operation as a non-mutating</div><div class="">operation, which e.g. a reference-semantics collection might.)</div><div class=""><br class=""></div><div class="">#### Expressing mutating and non-mutating iteration</div><div class=""><br class=""></div><div class="">Mutating and non-mutating iteration require the collection</div><div class="">to produce ephemeral values at each step. &nbsp;There are several</div><div class="">ways we could express this in the language, but one reasonable</div><div class="">approach would be to use co-routines. &nbsp;Since a co-routine does</div><div class="">not abandon its execution context when yielding a value to its</div><div class="">caller, it is reasonable to allow a co-routine to yield</div><div class="">multiple times, which corresponds very well to the basic</div><div class="">code pattern of a loop. &nbsp;This produces a kind of co-routine</div><div class="">often called a generator, which is used in several major</div><div class="">languages to conveniently implement iteration. &nbsp;In Swift,</div><div class="">to follow this pattern, we would need to allow the definition</div><div class="">of generator functions, e.g.:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; mutating generator iterateMutable() -&gt; inout Element {</div><div class="">&nbsp; &nbsp; var i = startIndex, e = endIndex</div><div class="">&nbsp; &nbsp; while i != e {</div><div class="">&nbsp; &nbsp; &nbsp; yield &amp;self[i]</div><div class="">&nbsp; &nbsp; &nbsp; self.formIndex(after: &amp;i)</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">On the client side, it is clear how this could be used to</div><div class="">implement `for` loops; what is less clear is the right way to</div><div class="">allow generators to be used directly by code. &nbsp;There are</div><div class="">interesting constraints on how the co-routine can be used</div><div class="">here because, as mentioned above, the entire co-routine</div><div class="">must logically execute within the scope of an access to the</div><div class="">base value. &nbsp;If, as is common for generators, the generator</div><div class="">function actually returns some sort of generator object,</div><div class="">the compiler must ensure that that object does not escape</div><div class="">that enclosing access. &nbsp;This is a significant source of</div><div class="">complexity.</div><div class=""><br class=""></div><div class="">### Generalized accessors</div><div class=""><br class=""></div><div class="">Swift today provides very coarse tools for implementing</div><div class="">properties and subscripts: essentially, just `get` and `set`</div><div class="">methods. &nbsp;These tools are inadequate for tasks where</div><div class="">performance is critical because they don't allow direct</div><div class="">access to values without copies. &nbsp;The standard library</div><div class="">has access to a slightly broader set of tools which can</div><div class="">provide such direct access in limited cases, but they're</div><div class="">still quite weak, and we've been reluctant to expose them to</div><div class="">users for a variety of reasons.</div><div class=""><br class=""></div><div class="">Ownership offers us an opportunity to revisit this problem</div><div class="">because `get` doesn't work for collections of non-copyable</div><div class="">types because it returns a value, which must therefore be</div><div class="">owned. &nbsp;The accessor really needs to be able to yield a</div><div class="">shared value instead of returning an owned one. &nbsp;Again,</div><div class="">one reasonable approach for allowing this is to use a</div><div class="">special kind of co-routine. &nbsp;Unlike a generator, this</div><div class="">co-routine would be required to yield exactly once.</div><div class="">And there is no need to design an explicit way for programmers</div><div class="">to invoke one because these would only be used in accessors.</div><div class=""><br class=""></div><div class="">The idea is that, instead of defining `get` and `set`,</div><div class="">a storage declaration could define `read` and `modify`:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; var x: String</div><div class="">&nbsp; var y: String</div><div class="">&nbsp; var first: String {</div><div class="">&nbsp; &nbsp; read {</div><div class="">&nbsp; &nbsp; &nbsp; if x &lt; y { yield x }</div><div class="">&nbsp; &nbsp; &nbsp; else { yield y }</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; modify {</div><div class="">&nbsp; &nbsp; &nbsp; if x &lt; y { yield &amp;x }</div><div class="">&nbsp; &nbsp; &nbsp; else { yield &amp;y }</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">A storage declaration must define either a `get` or a `read`</div><div class="">(or be a stored property), but not both.</div><div class=""><br class=""></div><div class="">To be mutable, a storage declaration must also define either a</div><div class="">`set` or a `modify`. &nbsp;It may also choose to define *both*, in</div><div class="">which case `set` will be used for assignments and `modify` will</div><div class="">be used for modifications. &nbsp;This is useful for optimizing</div><div class="">certain complex computed properties because it allows modifications</div><div class="">to be done in-place without forcing simple assignments to first</div><div class="">read the old value; however, care must be taken to ensure that</div><div class="">the `modify` is consistent in behavior with the `get` and the</div><div class="">`set`.</div><div class=""><br class=""></div><div class="">### Intrinsic functions</div><div class=""><br class=""></div><div class="">#### `move`</div><div class=""><br class=""></div><div class="">The Swift optimizer will generally try to move values around</div><div class="">instead of copying them, but it can be useful to force its hand.</div><div class="">For this reason, we propose the `move` function. &nbsp;Conceptually,</div><div class="">`move` is simply a top-level function in the Swift standard</div><div class="">library:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; func move&lt;T&gt;(_ value: T) -&gt; T {</div><div class="">&nbsp; &nbsp; return value</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">However, it is blessed with some special semantics. &nbsp;It cannot</div><div class="">be used indirectly. &nbsp;The argument expression must be a reference</div><div class="">to some kind of local owning storage: either a `let`, a `var`,</div><div class="">or an `inout` binding. &nbsp;A call to `move` is evaluated by</div><div class="">semantically moving the current value out of the argument</div><div class="">variable and returning it as the type of the expression,</div><div class="">leaving the variable uninitialized for the purposes of the</div><div class="">definitive-initialization analysis. &nbsp;What happens with the</div><div class="">variable next depends on the kind of variable:</div><div class=""><br class=""></div><div class="">- A `var` simply transitions back to being uninitialized.</div><div class="">&nbsp; Uses of it are illegal until it is assigned a new value and</div><div class="">&nbsp; thus reinitialized.</div><div class=""><br class=""></div><div class="">- An `inout` binding is just like a `var`, except that it is</div><div class="">&nbsp; illegal for it to go out of scope uninitialized. &nbsp;That is,</div><div class="">&nbsp; if a program moves out of an `inout` binding, the program</div><div class="">&nbsp; must assign a new value to it before it can exit the scope</div><div class="">&nbsp; in any way (including by throwing an error). &nbsp;Note that the</div><div class="">&nbsp; safety of leaving an `inout` temporarily uninitialized</div><div class="">&nbsp; depends on the Law of Exclusivity.</div><div class=""><br class=""></div><div class="">- A `let` cannot be reinitialized and so cannot be used</div><div class="">&nbsp; again at all.</div><div class=""><br class=""></div><div class="">This should be a straightforward addition to the existing</div><div class="">definitive-initialization analysis, which proves that local</div><div class="">variables are initialized before use.</div><div class=""><br class=""></div><div class="">#### `copy`</div><div class=""><br class=""></div><div class="">`copy` is a top-level function in the Swift standard library:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; func copy&lt;T&gt;(_ value: T) -&gt; T {</div><div class="">&nbsp; &nbsp; return value</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">The argument must be a storage reference expression. &nbsp;The</div><div class="">semantics are exactly as given in the above code: the argument</div><div class="">value is returned. &nbsp;This is useful for several reasons:</div><div class=""><br class=""></div><div class="">- It suppresses syntactic special-casing. &nbsp;For example, as</div><div class="">&nbsp; discussed above, if a `shared` argument is a storage</div><div class="">&nbsp; reference, that storage is normally accessed for the duration</div><div class="">&nbsp; of the call. &nbsp;The programmer can suppress this and force the</div><div class="">&nbsp; copy to complete before the call by calling `copy` on the</div><div class="">&nbsp; storage reference before&nbsp;</div><div class=""><br class=""></div><div class="">- It is necessary for types that have suppressed implicit</div><div class="">&nbsp; copies. &nbsp;See the section below on non-copyable types.</div><div class=""><br class=""></div><div class="">#### `endScope`</div><div class=""><br class=""></div><div class="">`endScope` is a top-level function in the Swift standard library:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; func endScope&lt;T&gt;(_ value: T) -&gt; () {}</div><div class="">```</div><div class=""><br class=""></div><div class="">The argument must be a reference to a local `let`, `var`, or</div><div class="">standalone (non-parameter, non-loop) `inout` or `shared`</div><div class="">declaration. &nbsp;If it's a `let` or `var`, the variable is</div><div class="">immediately destroyed. &nbsp;If it's an `inout` or `shared`,</div><div class="">the access immediately ends.</div><div class=""><br class=""></div><div class="">The definitive-initialization analysis must prove that</div><div class="">the declaration is not used after this call. &nbsp;It's an error</div><div class="">if the storage is a `var` that's been captured in an escaping</div><div class="">closure.</div><div class=""><br class=""></div><div class="">This is useful for ending an access before control reaches the</div><div class="">end of a scope, as well as for micro-optimizing the destruction</div><div class="">of values.</div><div class=""><br class=""></div><div class="">`endScope` provides a guarantee that the given variable has</div><div class="">been destroyed, or the given access has ended, by the time</div><div class="">of the execution of the call. &nbsp;It does not promise that these</div><div class="">things happen exactly at that point: the implementation is</div><div class="">still free to end them earlier.</div><div class=""><br class=""></div><div class="">### Lenses</div><div class=""><br class=""></div><div class="">Currently, all storage reference expressions in Swift are *concrete*:</div><div class="">every component is statically resolvable to a storage declaration.</div><div class="">There is some recurring interest in the community in allowing programs</div><div class="">to abstract over storage, so that you might say:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; let prop = Widget.weight</div><div class="">```</div><div class=""><br class=""></div><div class="">and then `prop` would be an abstract reference to the `weight`</div><div class="">property, and its type would be something like `(Widget) -&gt; Double`.</div><div class=""><br class=""></div><div class="">This feature is relevant to the ownership model because an ordinary</div><div class="">function result must be an owned value: not shared, and not mutable.</div><div class="">This means lenses could only be used to abstract *reads*, not</div><div class="">*writes*, and could only be created for copyable properties. &nbsp;It</div><div class="">also means code using lenses would involve more copies than the</div><div class="">equivalent code using concrete storage references.</div><div class=""><br class=""></div><div class="">Suppose that, instead of being simple functions, lenses were their</div><div class="">own type of value. &nbsp;An application of a lens would be a storage</div><div class="">reference expression, but an *abstract* one which accessed</div><div class="">statically-unknown members. &nbsp;This would require the language</div><div class="">implementation to be able to perform that sort of access</div><div class="">dynamically. &nbsp;However, the problem of accessing an unknown</div><div class="">property is very much like the problem of accessing a known</div><div class="">property whose implementation is unknown; that is, the language</div><div class="">already has to do very similar things in order to implement</div><div class="">generics and resilience.</div><div class=""><br class=""></div><div class="">Overall, such a feature would fit in very neatly with the</div><div class="">ownership model laid out here.</div><div class=""><br class=""></div><div class="">## Non-copyable types</div><div class=""><br class=""></div><div class="">Non-copyable types are useful in a variety of expert situations.</div><div class="">For example, they can be used to efficiently express unique</div><div class="">ownership. &nbsp;They are also interesting for expressing values</div><div class="">that have some sort of independent identity, such as atomic</div><div class="">types. &nbsp;They can also be used as a formal mechanism for</div><div class="">encouraging code to work more efficiently with types that</div><div class="">might be expensive to copy, such as large struct types. &nbsp;The</div><div class="">unifying theme is that we do not want to allow the type to</div><div class="">be copied implicitly.</div><div class=""><br class=""></div><div class="">The complexity of handling non-copyable types in Swift</div><div class="">comes from two main sources:</div><div class=""><br class=""></div><div class="">- The language must provide tools for moving values around</div><div class="">&nbsp; and sharing them without forcing copies. &nbsp;We've already</div><div class="">&nbsp; proposed these tools in this document because they're</div><div class="">&nbsp; equally important for optimizing the use of copyable types.</div><div class=""><br class=""></div><div class="">- The generics system has to be able to express generics over</div><div class="">&nbsp; non-copyable types without massively breaking source</div><div class="">&nbsp; compatibility and forcing non-copyable types on everybody.</div><div class=""><br class=""></div><div class="">Otherwise, the feature itself is pretty small. &nbsp;The compiler</div><div class="">implicitly emits moves instead of copies, just like we discussed</div><div class="">above for the `move` intrinsic, and then diagnoses anything</div><div class="">that that didn't work for.</div><div class=""><br class=""></div><div class="">### `moveonly` contexts</div><div class=""><br class=""></div><div class="">The generics problem is real, though. &nbsp;The most obvious way</div><div class="">to model copyability in Swift is to have a `Copyable`</div><div class="">protocol which types can conform to. &nbsp;An unconstrained type</div><div class="">parameter `T` would then not be assumed to be copyable.</div><div class="">Unfortunately, this would be a disaster for both source</div><div class="">compatibility and usability, because almost all the existing</div><div class="">generic code written in Swift assumes copyability, and</div><div class="">we really don't want programmers to have to worry about</div><div class="">non-copyable types in their first introduction to generic</div><div class="">code.</div><div class=""><br class=""></div><div class="">Furthermore, we don't want types to have to explicitly</div><div class="">declare conformance to `Copyable`. &nbsp;That should be the</div><div class="">default.</div><div class=""><br class=""></div><div class="">The logical solution is to maintain the default assumption</div><div class="">that all types are copyable, and then allow select contexts</div><div class="">to turn that assumption off. &nbsp;We will cause these contexts</div><div class="">`moveonly` contexts. &nbsp;All contexts lexically nested within</div><div class="">a `moveonly` context are also implicitly `moveonly`.</div><div class=""><br class=""></div><div class="">A type can be a `moveonly` context:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; moveonly struct Array&lt;Element&gt; {</div><div class="">&nbsp; &nbsp; // Element and Array&lt;Element&gt; are not assumed to be copyable here</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">This suppresses the `Copyable` assumption for the type</div><div class="">declared, its generic arguments (if any), and their</div><div class="">hierarchies of associated types.</div><div class=""><br class=""></div><div class="">An extension can be a `moveonly` context:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; moveonly extension Array {</div><div class="">&nbsp; &nbsp; // Element and Array&lt;Element&gt; are not assumed to be copyable here</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">A type can declare conditional copyability using a conditional</div><div class="">conformance:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; moveonly extension Array: Copyable where Element: Copyable {</div><div class="">&nbsp; &nbsp; ...</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">Conformance to `Copyable`, conditional or not, is an</div><div class="">inherent property of a type and must be declared in the</div><div class="">same module that defines the type. &nbsp;(Or possibly even the</div><div class="">same file.)</div><div class=""><br class=""></div><div class="">A non-`moveonly` extension of a type reintroduces the</div><div class="">copyability assumption for the type and its generic</div><div class="">arguments. &nbsp;This is necessary in order to allow standard</div><div class="">library types to support non-copyable elements without</div><div class="">breaking compatibility with existing extensions. &nbsp;If the</div><div class="">type doesn't declare any conformance to `Copyable`, giving</div><div class="">it a non-`moveonly` extension is an error.</div><div class=""><br class=""></div><div class="">A function can be a `moveonly` context:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; extension Array {</div><div class="">&nbsp; &nbsp; moveonly func report&lt;U&gt;(_ u: U)</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">This suppresses the copyability assumption for any new</div><div class="">generic arguments and their hierarchies of associated types.</div><div class=""><br class=""></div><div class="">A lot of the details of `moveonly` contexts are still up</div><div class="">in the air. &nbsp;It is likely that we will need substantial</div><div class="">implementation experience before we can really settle on</div><div class="">the right design here.</div><div class=""><br class=""></div><div class="">One possibility we're considering is that `moveonly`</div><div class="">contexts will also suppress the implicit copyability</div><div class="">assumption for values of copyable types. &nbsp;This would</div><div class="">provide an important optimization tool for code that</div><div class="">needs to be very careful about copies.</div><div class=""><br class=""></div><div class="">### `deinit` for non-copyable types</div><div class=""><br class=""></div><div class="">A value type declared `moveonly` which does not conform</div><div class="">to `Copyable` (even conditionally) may define a `deinit`</div><div class="">method. &nbsp;`deinit` must be defined in the primary type</div><div class="">definition, not an extension.</div><div class=""><br class=""></div><div class="">`deinit` will be called to destroy the value when it is</div><div class="">no longer required. &nbsp;This permits non-copyable types to be</div><div class="">used to express the unique ownership of resources. &nbsp;For</div><div class="">example, here is a simple file-handle type that ensures</div><div class="">that the handle is closed when the value is destroyed:</div><div class=""><br class=""></div><div class="">```</div><div class="">&nbsp; moveonly struct File {</div><div class="">&nbsp; &nbsp; var descriptor: Int32</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; init(filename: String) throws {</div><div class="">&nbsp; &nbsp; &nbsp; descriptor = Darwin.open(filename, O_RDONLY)</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp; // Abnormally exiting 'init' at any point prevents deinit</div><div class="">&nbsp; &nbsp; &nbsp; // from being called.</div><div class="">&nbsp; &nbsp; &nbsp; if descriptor == -1 { throw ... }</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; deinit {</div><div class="">&nbsp; &nbsp; &nbsp; _ = Darwin.close(descriptor)</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; consuming func close() throws {</div><div class="">&nbsp; &nbsp; &nbsp; if Darwin.fsync(descriptor) != 0 { throw ... }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp; // This is a consuming function, so it has ownership of self.</div><div class="">&nbsp; &nbsp; &nbsp; // It doesn't consume self in any other way, so it will</div><div class="">&nbsp; &nbsp; &nbsp; // destroy it when it exits by calling deinit. &nbsp;deinit</div><div class="">&nbsp; &nbsp; &nbsp; // will then handle actually closing the descriptor.</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; }</div><div class="">```</div><div class=""><br class=""></div><div class="">Swift is permitted to destroy a value (and thus call `deinit`)</div><div class="">at any time between its last use and its formal point of</div><div class="">destruction. &nbsp;The exact definition of "use" for the purposes</div><div class="">of this definition is not yet fully decided.</div><div class=""><br class=""></div><div class="">If the value type is a `struct`, `self` can only be used</div><div class="">in `deinit` in order to refer to the stored properties</div><div class="">of the type. &nbsp;The stored properties of `self` are treated</div><div class="">like local `let` constants for the purposes of the</div><div class="">definitive-initialization analysis; that is, they are owned</div><div class="">by the `deinit` and can be moved out of.</div><div class=""><br class=""></div><div class="">If the value type is an `enum`, `self` can only be used</div><div class="">in `deinit` as the operand of a `switch`. &nbsp;Within this</div><div class="">`switch`, any associated values are used to initialize</div><div class="">the corresponding bindings, which take ownership of those</div><div class="">values. &nbsp;Such a `switch` leaves `self` uninitialized.</div><div class=""><br class=""></div><div class="">### Explicitly-copyable types</div><div class=""><br class=""></div><div class="">Another idea in the area of non-copyable types that we're</div><div class="">exploring is the ability to declare that a type cannot</div><div class="">be implicitly copied. &nbsp;For example, a very large struct</div><div class="">can formally be copied, but it might be an outsized</div><div class="">impact on performance if it is copied unnecessarily.</div><div class="">Such a type should conform to `Copyable`, and it should</div><div class="">be possible to request a copy with the `copy` function,</div><div class="">but the compiler should diagnose any implicit copies</div><div class="">the same way that it would diagnose copies of a</div><div class="">non-copyable type.</div><div class=""><br class=""></div><div class="">## Implementation priorities</div><div class=""><br class=""></div><div class="">This document has laid out a large amount of work.</div><div class="">We can summarize it as follows:</div><div class=""><br class=""></div><div class="">- Enforcing the Law of Exclusivity:</div><div class=""><br class=""></div><div class="">&nbsp; - Static enforcement</div><div class="">&nbsp; - Dynamic enforcement</div><div class="">&nbsp; - Optimization of dynamic enforcement</div><div class=""><br class=""></div><div class="">- New annotations and declarations:</div><div class=""><br class=""></div><div class="">&nbsp; - `shared` parameters</div><div class="">&nbsp; - `consuming` methods</div><div class="">&nbsp; - Local `shared` and `inout` declarations</div><div class=""><br class=""></div><div class="">- New intrinsics affecting DI:</div><div class=""><br class=""></div><div class="">&nbsp; - The `move` function and its DI implications</div><div class="">&nbsp; - The `endScope` function and its DI implications</div><div class=""><br class=""></div><div class="">- Co-routine features:</div><div class=""><br class=""></div><div class="">&nbsp; - Generalized accessors</div><div class="">&nbsp; - Generators</div><div class=""><br class=""></div><div class="">- Non-copyable types</div><div class=""><br class=""></div><div class="">&nbsp; - Further design work</div><div class="">&nbsp; - DI enforcement</div><div class="">&nbsp; - `moveonly` contexts</div><div class=""><br class=""></div><div class="">The single most important goal for the upcoming releases is</div><div class="">ABI stability. &nbsp;The prioritization and analysis of these</div><div class="">features must center around their impact on the ABI. &nbsp;With</div><div class="">that in mind, here are the primary ABI considerations:</div><div class=""><br class=""></div><div class="">The Law of Exclusivity affects the ABI because it</div><div class="">changes the guarantees made for parameters. &nbsp;We must adopt</div><div class="">this rule before locking down on the ABI, or else we will</div><div class="">get stuck making conservative assumptions forever.</div><div class="">However, the details of how it is enforced do not affect</div><div class="">the ABI unless we choose to offload some of the work to the</div><div class="">runtime, which is not necessary and which can be changed</div><div class="">in future releases. &nbsp;(As a technical note, the Law</div><div class="">of Exclusivity is likely to have a major impact on the</div><div class="">optimizer; but this is an ordinary project-scheduling</div><div class="">consideration, not an ABI-affecting one.)</div><div class=""><br class=""></div><div class="">The standard library is likely to enthusiastically adopt</div><div class="">ownership annotations on parameters. &nbsp;Those annotations will</div><div class="">affect the ABI of those library routines. &nbsp;Library</div><div class="">developers will need time in order to do this adoption,</div><div class="">but more importantly, they will need some way to validate</div><div class="">that their annotations are useful. &nbsp;Unfortunately, the best</div><div class="">way to do that validation is to implement non-copyable types,</div><div class="">which are otherwise very low on the priority list.</div><div class=""><br class=""></div><div class="">The generalized accessors work includes changing the standard</div><div class="">set of "most general" accessors for properties and subscripts</div><div class="">from `get`/`set`/`materializeForSet` to (essentially)</div><div class="">`read`/`set`/`modify`. &nbsp;This affects the basic ABI of</div><div class="">all polymorphic property and subscript accesses, so it</div><div class="">needs to happen. &nbsp;However, this ABI change can be done</div><div class="">without actually taking the step of allowing co-routine-style</div><div class="">accessors to be defined in Swift. &nbsp;The important step is</div><div class="">just ensuring that the ABI we've settled on is good</div><div class="">enough for co-routines in the future.</div><div class=""><br class=""></div><div class="">The generators work may involve changing the core collections</div><div class="">protocols. &nbsp;That will certainly affect the ABI. &nbsp;In contrast</div><div class="">with the generalized accessors, we will absolutely need</div><div class="">to implement generators in order to carry this out.</div><div class=""><br class=""></div><div class="">Non-copyable types and algorithms only affect the ABI</div><div class="">inasmuch as they are adopted in the standard library.</div><div class="">If the library is going to extensively adopt them for</div><div class="">standard collections, that needs to happen before we</div><div class="">stabilize the ABI.</div><div class=""><br class=""></div><div class="">The new local declarations and intrinsics do not affect the ABI.</div><div class="">(As is often the case, the work with the fewest implications</div><div class="">is also some of the easiest.)</div><div class=""><br class=""></div><div class="">Adopting ownership and non-copyable types in the standard</div><div class="">library is likely to be a lot of work, but will be important</div><div class="">for the usability of non-copyable types. &nbsp;It would be very</div><div class="">limiting if it was not possible to create an `Array`</div><div class="">of non-copyable types.</div><div class=""><br class=""></div><div class="">(end)</div><div class=""><br class=""></div></body></html>