@available annotation not preventing missing symbol crash

I'm experiencing a really strange crash, so I spent some time making the absolute minimal reproduction possible, and I'm hoping someone can look into it.

(The reproduction repo is here, but note that you need to switch to the test-available branch to test the crash)

Suppose I have some multi-platform SwiftUI code, and I want to conditionally add a view modifier for platforms that support an api. Here's some code that calls out to fullScreenCover(isPresented:onDismiss:content:), which is not available at all for macOS:

public extension View {
  @available(iOS 14, tvOS 14, watchOS 7, *)
  @available(macOS, unavailable) // <-- NB: guard macOS 👍
  func myModifier() -> some View {
    self.fullScreenCover(isPresented: .constant(true)) {
      Text("Hello fullscreen cover!")
    }
  }
}

Take note that the function is guarded with an @available(macOS, unavailable) atttribute.

Now, with this code in my project, without even CALLING that function anywhere, I'm immediately getting a crash on macOS 10.15 Catalina, for a missing symbol. The core line of the crash is below, and if helpful, the entire crash report is here.

Symbol not found: _$s7SwiftUI4ViewPAAE15fullScreenCover11isPresented9onDismiss7contentQrAA7BindingVySbG_yycSgqd__yctAaBRd__lFQOMQ

This shouldn't be, right? That code path should never be taken on 10.15, if I'm understanding correctly? Is this a bug? Is there some sort of alternative compiler directive that would prevent this crash?

Again, I have a super simple git repo reproducing this crash, just checkout the test-available branch, archive, sign, and it will crash on Catalina.

Any help would be greatly appreciated! 🙏

Hmm, what does the call-site for myModifier look like?

I'm still researching the exact answer, but my current understanding is that the cross-platform SwiftUI module that you imported has the declaration fullScreenCover(isPresented:onDismiss:content:) even on macOS, but marked unavailable for macOS. That's why, if you try to compile the above code for macOS without any @available annotation, you get an error that the function is unavailable, not that it's undefined.

However, that API was introduced in iOS 14, which means it's only been declared that way in SwiftUI releases since iOS 14 (2020). Catalina was 2019, so that version doesn't have this function for any platform. Note that I don't get a crash with your above code on Ventura, since that's obviously more recent than 2020.

All this is leading up to saying that I think @available isn't what you should be using here. It sounds like you really want some kind of conditional compilation where either you don't want to compile myModifier at all on macOS, or you want to compile myModifier (perhaps with an availability annotation) but you don't want to compile any code inside that function on macOS.

Either way, I think #if … is what you're really looking for, something like #if !os(macOS) for straightforward conditional compilation.

@available annotation not preventing missing symbol crash
 
 
Q