SE-0507: Borrow and Mutate Accessors

some questions after reading and playing around with the initial implementation:


currently it appears that this feature only works with structs – is that an inherent limitation? i know that reference types are explicitly called out as being unsupported, but are enumerations expected to be compatible with the feature in some manner? if not, maybe that should be stated explicitly.

perhaps relatedly, it seems that forwarding through to an optional of a non-bitwisecopyable type doesn't work:

struct Source {
    var _s: String? = ""

    var s: String? {
        borrow { _s }
    }
}

struct Wrapper {
    var i: Source?

    var prop: String? {
        borrow { i?.s } // 🛑 – but this works if it's e.g. `Int?`
    }
}

what is the restriction at play here? temporary values in the optional chain?


Note that the value being returned must be a stored value that will outlive the execution of the accessor. It is illegal to return a local or temporary value

this wording in the proposal made me think the following could work because the storage lifetimes seem like they meet the constraint, though neither do:

var global = 0

struct S {
  var p: Int {
    borrow { global } // ✅
    mutate { &global } // 🛑
  }
}

do {
  var i = 0
  var local: Int {
    borrow { i } // 🛑
  }
}

the accessors vision doc on the other hand makes it sound like none of these should work including the borrow returning the global.


it seems reference storage types are also currently unsupported – is that an inherent limitation (perhaps the 'can't return a temporary value' one?)?

struct Ref {
    unowned var _obj: AnyObject

    unowned var val: AnyObject {
        borrow { _obj } // 🛑
    }
}

i had a reflexive sense of distaste that both mutating borrow and nonmutating mutate are expected to be valid. do i understand correctly that the '-ing form' specifies the semantics that apply to the container during the property access rather than the value, so should be interpreted as something like nonmutating(self) mutate(value) var ...?

i saw in the pitch thread some discussion about the meaning of borrowing borrow. is a borrowing mutate a valid combination (it does not appear to compile at the moment)?

5 Likes