When an `if #unavalable` statement also includes a secondary (non-availability)
condition, the availability scope for the else branch should not be refined.
The else branch can be reached because the secondary condition failed, in which
case the availability condition may not hold.
Resolves rdar://165863221.
Fix a Swift 6.3 regression in which extension members that are obsolete in the
current Swift language version are still considered available in contexts that
are also obsolete in the current Swift language version.
When computing the AvailabilityConstraints for a member of an extension,
constraints are first gathered for the member and then again for the extension
in case there are some attributes on the extension that should be effectively
inherited by the member. After gathering constraints, the core implementation
of `getAvailabilityConstraintsForDecl()` removes any constraints that can be
ignored in the given `AvailabilityContext`. That determination depends on the
kind of declaration the constraints are for, though, and it was being performed
first for the member on its own constraints and then again for the extension
for the combination of their constraints. This could result in member
constraints being ignored incorrectly.
The fix is to check whether a constraint ought to be ignored before adding it
to the set in the first place, rather than post-processing the entire
collection of constraints.
Resolves rdar://165942115.
- Use -verify instead of FileCheck.
- Use the Swift 5 and Swift 6 language modes so the test doesn't need to be
updated for Swift 4 deprecation.
- Add test cases for overload selection in contexts that are obsoleted in the
current Swift language mode.
- Add a test case for members of extensions.
When a protocol requirement is unreachable due to a custom availability domain
constraint, emission of the thunk and witness table entry for the requirement
should be skipped. The previous logic did not handle accessors or constructors
and it used a bespoke query instead of `Decl::isAvailableDuringLowering()`.
Resolves rdar://174172039.
Expand the fix-its to cover declarations with availability that is split
accross multiple attributes instead listed together in a single short form
`@available` attribute.
Resolves rdar://175677817.
The previously emitted fix-its would only replace the last availability spec
instead of all of the specs. I didn't notice this until I tried it in an
editor.
Resolves rdar://173814157.
Relax `-Wwarning UseAnyAppleOSAvailability` so that it triggers on any
declaration with matching availability on more than one Apple platform - don't
require availability annotations to be present for all of macOS, iOS, watchOS,
and tvOS.
Resolves rdar://173437121.
Enabling `UseAnyAppleOSAvailability` diagnostics will cause the compiler to
diagnose declarations where `anyAppleOS` availability can be used a concise
replacement for platform-specific availability annotations.
Resolves rdar://163819878.
Loosen availability checking to allow references to a decl that is unavailable
in a broader platform context in contexts which are unavailable in a more
specific platform context. For example, `@available(macOS, unavailable)` decls
should be allowed in `@available(macOSApplicationExtension, unavailable)`
contexts. This enhancement, which has always been desirable but wasn't high
priority, became more important with the introduction of `anyAppleOS`. Some
library authors may replace platform-specific availability annotations with
`anyAppleOS` availability and without this behavior change those attribute
updates would be source breaking.
Test updates assisted by claude.
Modeling the universal AvailabilityDomain as the bottom element of a lattice
containing all domains was useful for checking unavailability, but it makes
some other algorithms harder to write elegantly using availability domain
algebra. Instead, special case `*` in unavailability computations and only form
an availability domain lattice with the ABI stable platform domains,
`anyAppleOS`, and `Swift`.
In some cases, it's useful to allow an availability macro to expand to an empty
availability specification list. Allow developers to express this using macros
that are defined to exactly the string `*`, while continuing to reject `*` in
availability macros that contain other entries.
We don't consider an associated type of a @reparentable protocol
to be an overridden decl of any protocols inheriting from it.
If we did, then it'd affect how getReducedType and other bits of
comparison between associated types work, because they prefer
anchors, i.e., associated types not overriding anything else
(see `swift::compareAssociatedTypes`).
That worked fine until availability checking brought to light that
name lookup also relies getOverriddenDecls() to determine which
associated type decl one would be the one we refer to in a protocol.
So in this case it's not the reduced type, but rather the actual
`DeclRefTypeRepr` that name-lookup finds for `Element`, that actually
_does_ need to view that one coming from the @reparentable one as being
"overridden", or shadowed I guess, by any other protocols downstream of it.
rdar://170819864
Since reparentable protocols can have less availability
than the protocols inheriting from it, we need to first
loosen availability checking inheritance clauses to allow
for the statement of retroactive refinement.
Then, we need to tighten it in other places in terms of
expression checking, because we now cannot refer to
members of a generic type that originate from an unavailable
ancestor of a protocol to which the value conforms. Previously
it was not possible for that to be the case, so no checking
was performed.
It's now possible to have a base protocol that's less available
than one inheriting from it:
```
@available(macOS 200)
@reparentable public protocol P {}
public protocol Q: P {}
```
In this case, the protocol conformance descriptor for a client type
conforming to Q would contain in its resilient witnesses a base conformance
descriptor for Q conforming to P. That symbol (ending in 'Tb') won't be
available on older versions of the library. So, we choose to weak-link
that symbol (i.e., expect it to be extern_weak) in order to allow the client
targeting an older deployment target to still work.
This helps to propagate types bi-directionally and avoid extraneous
failures related to generic parameter inference when the real issue
is mutability or type erasure.
If the type of a key path literal is read-only due to setter
availability constraints but the context requires a writable
key path, let's produce a tailed availability diagnostic that
points to the offending setter.
Resolves: rdar://157249275
When a custom domain is described on the command line, there is no
backing declaration for it. Serialize such custom domains by
identifier and look them up globally at the point of deserialization.
When that fails, warn and drop the annotation.
This is all a stopgap until we have a way to spell custom availability
domains in the Swift language itself.
When compiling a Swift module in incremental mode, each Swift source file is compiled into an object file
and we use linker to link them together. Because the predicate function for checking dynamic feature
availability is eagerly synthesized per compilation unit, the linker will complain about duplicated
symbols for them. Setting their visibility as private ensures that linker doesn't see them, thus addressing
the linker errors.
One workaround for this problem is to enable WMO.
rdar://164971313
For dynamic features defined from a header, we synthesize a pure Clang function to check whether the feature should
be enabled at runtime. Swift modules don't have capability to deserialize this clang predicate function, leading to
crasher as a result. This change fixes the crasher by hiding the synthesized function to be a module internal one.
rdar://164410957
Emit a proper diagnostic for a conformance that is not available due to
custom availability that doesn't have version information, eliminating
an assertion.
`anyAppleOS` represents a meta-platform for availability checks that can be
used to check availability across all of Apple's operating systems. It
supports versions 26.0 and up since version 26.0 is the first OS version number
that is aligned accross macOS, iOS, watchOS, tvOS, and visionOS.
Apple platform-specific availability specification take precedence over
`anyAppleOS` availability specifications when specified simultaneously.
Resolves rdar://153834380.
This experimental feature will be used to force the compiler to treat `Swift`
runtime availability as separate from platform availability when compiling for
targets that have the Swift runtime built-in.
Replace the `here` part of the generic exportability diagnostic for
variables with: `in a property declaration marked public or in a
'@frozen' or '@usableFromInline' context`.
The full diagnostic now looks like:
```
error: cannot use struct 'ImportedType' in a property declaration marked
public or in a '@frozen' or '@usableFromInline' context;
'HiddenDependency' has been imported as implementation-only
```
This should be improved further to support implicitly exported memory
layouts in non-library-evolution and embedded.
Add support for the `Swift` availability domain, which represents availability
with respect to the Swift runtime. Use of this domain is restricted by the
experimental feature `SwiftRuntimeAvailability`.
These are tests that fail in the next commit without this flag. This
does not add -verify-ignore-unrelated to all tests with -verify, only
the ones that would fail without it. This is NFC since this flag is
currently a no-op.
Accessor availability diagnostics for key path expressions were first
introduced by https://github.com/swiftlang/swift/pull/83931. Those changes were
insufficient because sometimes key path expressions are generated in the AST
with more mutability than is needed by the context and so setter availability
could be diagnosed inappropriately. Key path expression binding was refined in
https://github.com/swiftlang/swift/pull/84491 to make this less likely to
occur. However, there are still some circumstances in which a mutable key path
is generated in the AST and then immediately coerced into an immutable key path
to satisfy the contextual type. This change infers the immutability of these key
path expressions by looking through surrounding conversion expressions.
An always enabled availability domain is implicitly available in all contexts,
so uses of declarations that are marked as `@available` in the domain are never
rejected. This is useful for an availability domain representing a feature flag
that has become permanently enabled.
Partially resolves rdar://157593409.
Diagnose the availability of the specific accessors that are referenced
implicitly via a key path reference. This causes setter availability to be
diagnosed when passing a key path to a function that takes a `WritableKeyPath`.
Resolves rdar://157232221.
Previously, whether a declaration is unavailable because it is obsolete was
determined based solely on the deployment target and not based on contextual
availability. Taking contextual availability into account makes availability
checking more internally consistent and allows library authors to evolve APIs
by obsoleting the previous declaration while introducing a new declaration in the
same version:
```
@available(macOS, obsoleted: 15)
func foo(_ x: Int) { }
@available(macOS, introduced: 15)
func foo(_ x: Int, y: Int = 0) { }
foo(42) // unambiguous, regardless of contextual version of macOS
```
This change primarily accepts more code that wasn't accepted previously, but it
could also be source breaking for some code that was previously allowed to use
obsoleted declarations in contexts that will always run on OS versions where
the declaration is obsolete. That code was clearly taking advantage of an
availabilty loophole, though, and in practice I don't expect it to be common.
Resolves rdar://144647964.