Commit Graph

12 Commits

Author SHA1 Message Date
Allan Shortlidge
4d41db3b5d Sema: Rationalize availability checking in unavailable contexts.
Correct several behaviors of availability checking in unavailable contexts that
were inconsistent with the checking model:

- Avoid diagnosing unintroduced and obsolted declarations in contexts that are
  unavailable in the same domain.
- Diagnose unavailability normally in type signature contexts.
2025-08-08 07:57:44 -07:00
Anthony Latsis
2cd90bdd69 AST: Quote attributes more consistently in DiagnosticsSema.def 2025-04-22 18:23:36 +01:00
Allan Shortlidge
ae21f8d390 AST: Stop diagnosing potentially unavailable declarations in unavailable contexts.
Potential unavailability of a declaration has always been diagnosed in contexts
that do not have a sufficient platform introduction constraint, even when those
contexts are also unavailable on the target platform. This behavior is overly
strict, since the potential unavailability will never matter, but it's a
longstanding quirk of availability checking. As a result, some source code has
been written to work around this quirk by marking declarations as
simultaneously unavailable and introduced for a given platform:

```
@available(macOS, unavailable, introduced: 15)
func unavailableAndIntroducedInMacOS15() {
  // ... allowed to call functions introduced in macOS 15.
}
```

When availability checking was refactored to be based on a constraint engine in
https://github.com/swiftlang/swift/pull/79260, the compiler started effectively
treating `@available(macOS, unavailable, introduced: 15)` as just
`@available(macOS, unavailable)` because the introduction constraint was
treated as lower priority and therefore superseded by the unavailability
constraint. This caused a regression for the code that was written to work
around the availability checker's strictness.

We could try to match the behavior from previous releases, but it's actually
tricky to match the behavior well enough in the new availability checking
architecture to fully fix source compatibility. Consequently, it seems like the
best fix is actually to address this long standing issue and stop diagnosing
potential unavailability in unavailable contexts. The main risk of this
approach is source compatibility for regions of unavailable code. It's
theoretically possible that restricting available declarations by introduction
version in unavailable contexts is important to prevent ambiguities during
overload resolution in some codebases. If we find that is a problem that is too
prevalent, we may have to take a different approach.

Resolves rdar://147945883.
2025-04-11 11:50:29 -07:00
Allan Shortlidge
7c47d0a9b2 Tests: Add more coverage of unavailable decls in unavailable contexts.
Specifically, calls to extension members with various kinds of unavailability
in the context of a program compiled for app extensions.
2025-03-10 16:33:33 -07:00
Allan Shortlidge
eafea5b21e Sema: Relax availability checking in universally unavailable contexts.
Recent refactoring fixed a bug that previously caused `f()` to be checked as if
it were unavailable only on macOS in the following example:

```
@available(macOS, unavailable)
struct Outer {
  @available(*, unavailable)
  func f() {
    someFunctionUnavailableOnMacOS()
  }
}
```

Unfortunately, fixing that bug made a different existing availability checking
rule more problematic. References to declarations that are unavailable on the
current platform have been diagnosed as unavailable even in contexts that are
universally unavailable. This long standing behavior is overly strict but it
rarely had consequences. However, now that the example above is modeled
correctly, this overly strict behavior is causing some source compatibility
issues. The easiest solution is to relax the overly strict checking.

Resolves rdar://141124478.
2024-12-09 17:15:15 -08:00
Allan Shortlidge
7c75b26f1b Sema: Make suppression of availability checking for types more consistent.
Availability checking for types was only suppressed when the immediate context
for the use of the type was explicitly marked unavailable. Availability is
lexical so the checking should be suppressed in the entire scope instead.
2024-11-01 08:18:13 -07:00
Allan Shortlidge
7797681960 AST: Fix AvailabilityContext's containment check for platforms.
The unavailable platform kind of the outer AvailabilityContext must not inherit
availability from the platform of the inner context.
2024-11-01 08:18:13 -07:00
Allan Shortlidge
d08520dc74 Tests: Improve tests for availability checking in unavailable contexts.
Rewrite attr_availability_transitive_osx.swift to be more use a more thorough
cartesian product approach to testing possible combinations. Free up
Sema/availability.swift to run on platforms besides macOS.

NFC.
2024-11-01 08:18:13 -07:00
Ben Langmuir
9943ef0eed [test] Move test/attr/attr_availability_transitive_osx_appext.swift to fake version
Keep this test independent of the default deployment target by using a
larger version number.
2024-08-28 13:52:10 -07:00
Allan Shortlidge
6d1a6c5f20 Sema: Avoid application extension platforms in if #available fix-its.
When the type checker noticed that a declaration with application extension
availability markup was used somewhere that it would be potentially unavailable
at runtime, the fix-it emitted by the compiler would check for the application
extension platform's availability:

```
if #available(macOSApplicationExtension 12, *) {
  // Use potentially unavailable declarations
}
```

This runtime check won't work. The fix-it should just suggest checking the
availability of the base, non-extension platform instead.

Resolves rdar://125860317.
2024-08-20 17:25:36 -07:00
Allan Shortlidge
35afd7fa90 AST: App extension platforms always inherit availability from their parents. 2024-01-29 16:57:29 -08:00
Allan Shortlidge
6c08e4e280 NFC: Clarify the names of a couple availability tests that are concerned with app extensions by replacing "extension" with "appext" since extension usually refers to Swift extension declarations. 2022-07-11 12:05:36 -07:00