`unsafeAddress` and `unsafeMutableAddress`

  1. Well, that depends. It really depends on what you want your semantics to be for the "getter"/"setter" of a property/subscript. It's totally valid to have something like this:
var something: Noncopyable {
  Noncopyable()
}

and this is just using a regular get for the noncopyable. This returns its value as +1/owned/consuming meaning the caller of the property now owns the noncopyable value. In most cases with collectiony types, the collection itself owns the noncopyable value and only wants users to be able to borrow or peek at the noncopyable value.

There is also _read/_modify (which has a proposal to make these public: SE-0474: Yielding Accessors) which allow you to write:

public struct UniqueString : ~Copyable {...}

public struct UniqueBorrow : ~Copyable {
  var _x: UniqueString

  public var property: UniqueString {
    yielding borrow {
        yield x
    }
  }
}

which will let users have a +0/guaranteed/borrow of the UniqueString that's currently being owned by UniqueBorrow.

  1. Sort of. These accessors provide the illusion that all you're working with is in memory values, but most of the time you need to load values out of memory to be able to do simple things like call methods on it (depending on the ABI of the type). Consider the following example:
extension Int {
  func hello() {
    print("Hello! I am \(self)")
  }
}

The ABI of the function hello directly takes self by value here because Int is not what's considered an "address only" type (and because self is just a simple integer that can be passed around in registers). So a type that has something like:

var property: Int {
  unsafeAddress {
    ...
  }
}

is providing the +0 borrow of the int, but doing something like property.hello() will immediately load the integer out of memory into a register to be able to perform the method call hello.

  1. It's not possible to have both on the same property, you must have either a getter or addressor.
2 Likes