Commit Graph

18 Commits

Author SHA1 Message Date
Anthony Latsis
5e41794680 AST: Quote attributes more consistently in DiagnosticsSema.def 2025-04-23 19:18:08 +01:00
Allan Shortlidge
64fadaf828 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:55:05 -07:00
Allan Shortlidge
3c8a57f86d AST: Use consolidated availability constraint query for diagnostics.
Switch to calling `swift::getAvailabilityConstraintsForDecl()` to get the
unsatisfied availability constraints that should be diagnosed.

This was intended to be NFC, but it turns out it fixed a bug in the recently
introduced objc_implementation_direct_to_storage.swift test. In the test,
the stored properties are as unavailable as the context that is accessing them
so the accesses should not be diagnosed. However, this test demonstrates a
bigger issue with `@objc @implementation`, which is that it allows the
implementations of Obj-C interfaces to be less available than the interface,
which effectively provides an availability checking loophole that can be used
to invoke unavailable code.
2025-02-16 07:44:45 -08:00
Allan Shortlidge
aa7bd6063c Tests: Add tests for decls that are unavailable and introduced later.
NFC.
2025-02-12 07:20:15 -08:00
Allan Shortlidge
113568f569 Tests: Fix spelling in attr_availability_transitive_osx.swift. 2025-01-20 18:27:45 -08: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
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
Allan Shortlidge
ac98262798 Sema: Adopt AvailabilityContext in ExportContext.
Query for an AvailabilityContext instead of computing availability with a
DeclContext traversal when forming an ExportContext.
2024-10-22 08:39:30 -07:00
Allan Shortlidge
7dc313f1be NFC: Fix tests that mistakenly rely on unavailable stored properties.
Preparation for rdar://107449845
2023-04-04 08:52:39 -07:00
Allan Shortlidge
620462ddf6 Sema: Don't diagnose declarations more available than unavailable container.
It turns out that we must allow declarations with `introduced:` availability
nested inside of other declarations that are `unavailable` in order to
influence weak linking. Stop diagnosing declarations as being more available
than their unavailable containers and revert some changes to availability
inference that were designed to avoid creating these nestings but caused
regressions for declarations marked `@_spi_available.`

Reverts parts of https://github.com/apple/swift/pull/64310,
https://github.com/apple/swift/pull/64015, and
https://github.com/apple/swift/pull/62900.
2023-03-21 13:55:05 -07:00
Allan Shortlidge
f796dc9417 Sema: Don't diagnose explicitly unavailable decls as "more available than unavailable scope."
Fixes a logic error introduced in https://github.com/apple/swift/pull/61242.

Resolves rdar://102877953
2022-12-09 17:33:58 -08:00
Allan Shortlidge
cebfe57cab Sema: Diagnose declarations that are annotated to be more available than their unavailable enclosing scope.
Resolves rdar://92552186
2022-09-21 18:00:43 -07:00
Allan Shortlidge
c78090bc40 Sema: When computing potential unavailability of a decl, first check whether the decl is explicitly unavailable and the context is also unavailable. If those conditions are met, treat the decl as if it were always available since unavailable code is allowed to reference unavailable decls.
Previously, `TypeChecker::checkDeclarationAvailability()` would behave this way for most explicitly unavailable decls by _accident_. An explicitly unavailable decl has no introduction version, and the existing logic therefore would fail to find a lower bound on the availability of the decl. The edge case that exposed the fragility of this logic was an unavailable extension containing a member with it's own explicit availability. The unavailability of the extension ought to trump the availability of the member, but the existing logic couldn't detect that.

The compiler also ought to diagnose the conflicting availability annotations but I'd like to address that separately.

Resolves rdar://92551870
2022-05-05 07:21:30 -07:00
Allan Shortlidge
6f8057d1e0 Sema: Avoid diagnosing potential unavailability of type components (extension nominal type, superclass, etc.) on declarations that are explicitly unavailable.
Resolves rdar://92179327
2022-04-26 16:03:10 -07:00
Slava Pestov
998e62005a Sema: Don't diagnose availability errors twice in non-single-expression closures 2019-04-02 20:37:01 -04:00
Jordan Rose
722cb836f5 Extend transitive availability checking to initial value expressions
Because initial value expressions aren't actually considered /within/
the VarDecl or PatternBindingDecl they're initializing, the existing
logic to search for availability attributes wasn't kicking in, leading
to errors when a conditionally-unavailable value was used in an
initial value expression for a conditionally-unavailable binding. Fix
this by walking the enclosing type or extension to find the appropriate
PatternBindingDecl.

https://bugs.swift.org/browse/SR-9867
2019-02-08 11:39:32 -08:00
Timothy J. Wood
cffd2c33e4 Only skip unavailability diagnostics if the platforms match.
Add TypeChecker::isInsideCompatibleUnavailableDeclaration().
Pass in the call site's AvailableAttr and compare its platform to those
in the enclosing lexical scopes.

Added some basic tests.
2017-10-21 09:35:31 -07:00