#unavailable control flow requires else?

#unavailable seems to require an else clause for the available-availing code, which creates unnecessary indentation; as a precondition, there’s typically a lot of code affected.

It would be nice if the control-transfer statements like return or continue would result in the block being recognized as available.

It’s written up as < Availability control flow requires if/else · Issue #85061 · swiftlang/swift · GitHub >

enum Demo {
  @available(macOS 26.0, *)
  static func new26() {}
  static func f() {
    if #unavailable(macOS 26.0) {
      // report errors, etc.
      return
    }
    // ok:  else { new26() }
    // Compiler error: 'new26()' is only available in macOS 26.0 or newer
    new26() 
  }
}

Is there a reason for this? Am I missing some logic?

I’m starting to use #unavailable a lot and surprised if this hasn’t come up since it was introduced. But then searching for it on github swift files, I see very few usages. hmm.

The compiler can't make any guarantees about the OS runtime version the code after the if. I think you must be assuming that the compiler takes the presence of the return statement into account, but it doesn't. To communicate the invariant you want to the compiler, you need to use a guard statement, which guarantees structurally that the following code is unreachable if the condition does not hold.

enum Demo {
  @available(macOS 26.0, *)
  static func new26() {}
  static func f() {
    guard #available(macOS 26.0, *) else {
      // report errors, etc.
      return
    }
    new26() // OK
  }
}
5 Likes