Files
swift-mirror/test/IRGen/Inputs/weak_import_availability_helper.swift
Allan Shortlidge a6eb7e494b AST: Fix weak linking for potentially unavailable accessors in extensions.
In https://github.com/swiftlang/swift/pull/78454 queries for the platform
availability of decl were consolidated into
`Decl::getAvailableAttrForPlatformIntroduction()`. In addition to checking the
attributes directly attached to the decl, this method also checks whether the
decl is a member directly contained inside of an extension and checks for
attributes attached to the extension as well. Previously, this logic was only
used for availability checking diagnostics, where special casing extension
members was a requirement. As a result of the consolidation, though, the logic
is now also shared by the query that determines whether to weakly link symbols
associated with a decl. That determination already had its own way of handling
members of extensions but it seemed like consolidating the logic would stil be
a net improvement that would reduce overall complexity.

Unfortunately, the existing approach to getting the availability of the
enclosing extension had a subtle bug for both AccessorDecl and OpaqueTypeDecl.
If an AvailableAttr was not directly attached to the immediate decl, then
`Decl::getAvailableAttrForPlatformIntroduction()` would check if the enclosing
decl context was an extension and look at its attributes as well. For
AccessorDecl and OpaqueTypeDecl, checking the enclosing decl context would
accidentally skip over the VarDecl and AbstractFunctionDecl that are formally
the parents of those decls for the purposes of attribute inheritance. As a
result, the availability of the enclosing property or function could be ignored
if the enclosing extension had explicit availability attributes.

The fix is to use `AvailabilityInference::parentDeclForInferredAvailability()`
instead of `getDeclContext()` when looking for the immediately enclosing
extension.

Resolves rdar://143139472.
2025-01-24 17:43:42 -08:00

104 lines
2.4 KiB
Swift

@available(macOS 50, *)
public func conditionallyAvailableFunction() {}
@available(macOS, unavailable)
public func unavailableFunction() {}
@available(macOS 50, *)
public func conditionallyAvailableOpaqueReturnFunction() -> some AlwaysAvailableProtocol {
return AlwaysAvailableStruct()
}
@available(macOS 50, *)
public var conditionallyAvailableGlobal: Int {
get {return 0}
set {}
}
@available(macOS, unavailable)
public var unavailableGlobal: Int {
get {return 0}
set {}
}
@available(macOS 50, *)
public struct ConditionallyAvailableStruct {
public func conditionallyAvailableMethod() {}
}
extension ConditionallyAvailableStruct {
public struct NestedStruct {}
}
@available(macOS, unavailable)
public struct UnavailableStruct {
public func unavailableMethod() {}
}
public protocol AlwaysAvailableProtocol {}
public struct AlwaysAvailableStruct {}
@available(macOS 50, *)
extension AlwaysAvailableStruct {
public func methodInConditionallyAvailableExtension() {}
public func opaqueReturnMethodInConditionallyAvailableExtension() -> some AlwaysAvailableProtocol {
return AlwaysAvailableStruct()
}
public var varInConditionallyAvailableExtension: Int {
get {return 0}
set {}
}
}
extension AlwaysAvailableStruct {
@available(macOS 50, *)
public func conditionallyAvailableMethodInExtension() {}
@available(macOS 50, *)
public func conditionallyAvailableOpaqueReturnMethodInExtension() -> some AlwaysAvailableProtocol {
return AlwaysAvailableStruct()
}
@available(macOS 50, *)
public var conditionallyAvailableVarInExtension: Int {
get {return 0}
set {}
}
}
@available(macOS 10.9, *)
extension AlwaysAvailableStruct {
@available(macOS 50, *)
public func conditionallyAvailableMethodInExplicitlyAvailableExtension() {}
@available(macOS 50, *)
public func conditionallyAvailableOpaqueReturnMethodInExplicitlyAvailableExtension() -> some AlwaysAvailableProtocol {
return AlwaysAvailableStruct()
}
@available(macOS 50, *)
public var conditionallyAvailableVarInExplicitlyAvailablextension: Int {
get {return 0}
set {}
}
}
@available(macOS 50, *)
extension AlwaysAvailableStruct : AlwaysAvailableProtocol {}
@available(macOS, unavailable)
public protocol UnavailableProtocol {}
@available(macOS, unavailable)
extension AlwaysAvailableStruct : UnavailableProtocol {}
public enum AlwaysAvailableEnum {
case alwaysAvailableCase
@available(macOS 50, *)
case conditionallyAvailableCase
}