Supporting @available stored properties

I ran into an issue with someone today. I think this code represents the issue pretty closely.

@available(anyAppleOS 27.0, *)
struct SomeBrandNewType {
}

struct AdoptingType {
  // error: Stored properties cannot be marked potentially unavailable with '@available'
  @available(anyAppleOS 27.0, *)
  var maybeAvailable: SomeBrandNewType?
}

I get it. But, also, this feels a bit like lazy properties. Could such an arrangement work, and just resolve to nil unconditionally when unavailable? Or is there more complexity here than I have realized in the 30 seconds I've spent thinking about it?

5 Likes

Adding support for this is tracked by this issue. It's theoretically doable but there's significant implementation work required to make it happen (and a few different approaches that could be taken with different tradeoffs). This isn't really analogous to lazy properties in my mind. The compiler has to generate code for AdoptingType that avoids touching the type metadata for SomeBrandNewType in any way on runtimes earlier than anyAppleOS 27.0. That means that layout and all the value witnesses for AdoptingType have to become conditional on an availability check.

4 Likes

Probably you figured it out already, but if you can afford type erasure, you can emulate it with a computed property backed by Any?:

struct AdoptingType {
  @available(anyAppleOS 27.0, *)
  var maybeAvailable: SomeBrandNewType? {
    get { _maybeAvailable as! SomeBrandNewType? }
    set { _maybeAvailable = newValue }
  }
  private var _maybeAvailable: Any?
}
6 Likes

Should be macroable as well, though you may need the recent "available self" enhancement.

4 Likes