# Diagnostics for unavailable declarations

**URL:** <https://forums.swift.org/t/diagnostics-for-unavailable-declarations/82281>\
**Category:** Using Swift\
**Tags:** compiler, availability\
**Created:** [September 22, 2025, 11:38am UTC](https://forums.swift.org/t/diagnostics-for-unavailable-declarations/82281 "2025-09-22T11:38:38Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![tshortli](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tshortli/32/15850_2.png) [@tshortli](https://forums.swift.org/u/tshortli)\
**Post date:** [September 22, 2025, 4:39pm UTC](https://forums.swift.org/t/diagnostics-for-unavailable-declarations/82281/2 "2025-09-22T16:39:46Z")

</div>

The rule is specifically that unavailable declarations can be referenced without a diagnostic from contexts that are at least as unavailable. For example, a function that is `@available(macOS, unavailable)` can be referenced from a contexts that are either `@available(macOS, unavailable)` or `@available(*, unavailable)` when compiling for a macOS target. However, there's an [exception](https://github.com/swiftlang/swift/blob/963aad355617ccb928811b7107101e33b169fc7d/lib/AST/AvailabilityConstraint.cpp#L153) to this logic in the compiler specifically for references to functions that are unavailable in `*`.

This logic that makes an exception for universally unavailable functions pre-dates my experience with the availability checker and I haven't found any concrete explanation for it, but I have a guess for the rationale. Since the compiler does not intend accept any program that would actually be able to call an `@available(*, unavailable)` function at runtime, it doesn't really make sense to references to them anywhere except for convenience. But there's a cost to that convenience during overload resolution. If `@available(*, unavailable)` functions were legal to call in `@available(*, unavailable)` contexts, then overload resolution in those contexts has to consider overloads that could otherwise be ruled out:

```swift
func f() -> String { "dynamic" }

@available(*, unavailable)
func f() -> StaticString { "static" }

@available(*, unavailable)
func g() {
  print(f()) // ambiguous unless the overload returning StaticString is ruled out
}

```

This may seem pretty niche, but I've seen it be relevant for some code where `@available(*, unavailable)` is applied conditionally to certain functions based on build settings. I think [custom availability](https://forums.swift.org/t/pitch-extensible-availability-checking/79308) would be a better tool for code that needs to become unavailable in certain build configurations, though.

> [@crontab](#):
>
> Using `deprecated` is not a very good option as a refactoring tool as Xcode doesn’t always show all compiler warnings for some reason.

Could you use deprecation and `-Werror DeprecatedDeclaration`? I suppose it depends on whether your code uses any other deprecated declarations, but it might be a reasonable workaround.

---

_[View the full topic](https://forums.swift.org/t/diagnostics-for-unavailable-declarations/82281)._
