mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
This commit is contained in:
@@ -172,28 +172,9 @@ static bool canIgnoreConstraintInUnavailableContexts(
|
||||
return true;
|
||||
|
||||
case AvailabilityConstraint::Reason::Unintroduced:
|
||||
switch (domain.getKind()) {
|
||||
case AvailabilityDomain::Kind::Universal:
|
||||
case AvailabilityDomain::Kind::SwiftLanguage:
|
||||
case AvailabilityDomain::Kind::PackageDescription:
|
||||
case AvailabilityDomain::Kind::Embedded:
|
||||
case AvailabilityDomain::Kind::Custom:
|
||||
return false;
|
||||
case AvailabilityDomain::Kind::Platform:
|
||||
// Platform availability only applies to the target triple that the
|
||||
// binary is being compiled for. Since the same declaration can be
|
||||
// potentially unavailable from a given context when compiling for one
|
||||
// platform, but available from that context when compiling for a
|
||||
// different platform, it is overly strict to enforce potential platform
|
||||
// unavailability constraints in contexts that are unavailable to that
|
||||
// platform.
|
||||
return true;
|
||||
}
|
||||
return constraint.getDomain().isPlatform();
|
||||
|
||||
case AvailabilityConstraint::Reason::UnavailableObsolete:
|
||||
case AvailabilityConstraint::Reason::UnavailableUnintroduced:
|
||||
return false;
|
||||
return domain.isVersioned();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2073,11 +2073,6 @@ class DeclAvailabilityChecker : public DeclVisitor<DeclAvailabilityChecker> {
|
||||
// Don't bother checking errors.
|
||||
if (type && type->hasError())
|
||||
return;
|
||||
|
||||
// If the decl which references this type is unavailable on the current
|
||||
// platform, don't diagnose the availability of the type.
|
||||
if (Where.getAvailability().isUnavailable())
|
||||
return;
|
||||
|
||||
diagnoseTypeAvailability(typeRepr, type, context->getLoc(),
|
||||
Where.withReason(reason), flags);
|
||||
|
||||
@@ -1502,9 +1502,12 @@ static void diagnoseIfDeprecated(SourceRange ReferenceRange,
|
||||
// We match the behavior of clang to not report deprecation warnings
|
||||
// inside declarations that are themselves deprecated on all deployment
|
||||
// targets.
|
||||
if (Availability.isDeprecated()) {
|
||||
if (Availability.isDeprecated())
|
||||
return;
|
||||
|
||||
// Skip diagnosing deprecated types in unavailable contexts.
|
||||
if (Availability.isUnavailable() && isa<TypeDecl>(DeprecatedDecl))
|
||||
return;
|
||||
}
|
||||
|
||||
auto *ReferenceDC = Where.getDeclContext();
|
||||
auto &Context = ReferenceDC->getASTContext();
|
||||
|
||||
@@ -11,7 +11,7 @@ public struct UnavailableInEmbedded {}
|
||||
|
||||
@available(*, unavailable, message: "always unavailable")
|
||||
public struct UniverallyUnavailable {}
|
||||
// expected-note@-1 {{'UniverallyUnavailable' has been explicitly marked unavailable here}}
|
||||
// expected-note@-1 3 {{'UniverallyUnavailable' has been explicitly marked unavailable here}}
|
||||
|
||||
@_unavailableInEmbedded
|
||||
public func unavailable_in_embedded() { }
|
||||
@@ -43,7 +43,7 @@ public struct Available {}
|
||||
extension Available {
|
||||
public func unavailable_in_embedded_method( // expected-note {{'unavailable_in_embedded_method' has been explicitly marked unavailable here}}
|
||||
_ uie: UnavailableInEmbedded,
|
||||
_ uu: UniverallyUnavailable,
|
||||
_ uu: UniverallyUnavailable, // expected-error {{'UniverallyUnavailable' is unavailable: always unavailable}}
|
||||
_ a: Available,
|
||||
) {
|
||||
unavailable_in_embedded()
|
||||
@@ -67,7 +67,7 @@ public func available(
|
||||
@_unavailableInEmbedded
|
||||
public func also_unavailable_in_embedded(
|
||||
_ uie: UnavailableInEmbedded, // OK
|
||||
_ uu: UniverallyUnavailable, // OK
|
||||
_ uu: UniverallyUnavailable, // expected-error {{'UniverallyUnavailable' is unavailable: always unavailable}}
|
||||
_ a: Available,
|
||||
) {
|
||||
unavailable_in_embedded() // OK
|
||||
|
||||
@@ -522,11 +522,11 @@ class DerivedLessAvailable: BaseAvailableInEnabledDomain { // expected-error {{'
|
||||
}
|
||||
|
||||
@available(EnabledDomain, unavailable)
|
||||
class DerivedUnavailable: BaseAvailableInEnabledDomain { }
|
||||
class DerivedUnavailable: BaseAvailableInEnabledDomain { } // expected-error {{'BaseAvailableInEnabledDomain' is only available in EnabledDomain}}
|
||||
|
||||
// FIXME: This shouldn't be accepted
|
||||
@available(DisabledDomain, unavailable)
|
||||
class DerivedUnavailable2: BaseAvailableInEnabledDomain { }
|
||||
class DerivedUnavailable2: BaseAvailableInEnabledDomain { } // expected-error {{'BaseAvailableInEnabledDomain' is only available in EnabledDomain}}
|
||||
// expected-note@-1 {{add '@available' attribute to enclosing class}}
|
||||
|
||||
@available(EnabledDomain)
|
||||
@available(DisabledDomain, unavailable)
|
||||
|
||||
@@ -350,7 +350,7 @@ public func alwaysUnavailable(
|
||||
_ = BetweenTargets()
|
||||
_ = AtDeploymentTarget()
|
||||
_ = AfterDeploymentTarget()
|
||||
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
|
||||
_ = ObsoletedBetweenTargets()
|
||||
_ = Unavailable()
|
||||
|
||||
if #available(macOS 11, *) {
|
||||
@@ -630,7 +630,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
|
||||
defer {
|
||||
_ = AtDeploymentTarget()
|
||||
_ = AfterDeploymentTarget()
|
||||
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
|
||||
_ = ObsoletedBetweenTargets()
|
||||
}
|
||||
_ = NoAvailable()
|
||||
_ = BeforeInliningTarget()
|
||||
@@ -638,12 +638,12 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
|
||||
_ = BetweenTargets()
|
||||
_ = AtDeploymentTarget()
|
||||
_ = AfterDeploymentTarget()
|
||||
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
|
||||
_ = ObsoletedBetweenTargets()
|
||||
_ = Unavailable()
|
||||
|
||||
if #available(macOS 11, *) {
|
||||
_ = AfterDeploymentTarget()
|
||||
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
|
||||
_ = ObsoletedBetweenTargets()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -930,7 +930,7 @@ public func defaultArgsUseUnavailable(
|
||||
_: Any = BetweenTargets.self,
|
||||
_: Any = AtDeploymentTarget.self,
|
||||
_: Any = AfterDeploymentTarget.self,
|
||||
_: Any = ObsoletedBetweenTargets.self, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
|
||||
_: Any = ObsoletedBetweenTargets.self,
|
||||
_: Any = Unavailable.self
|
||||
) {}
|
||||
|
||||
@@ -1056,7 +1056,7 @@ public struct PublicStruct { // expected-note 21 {{add '@available' attribute}}
|
||||
|
||||
@available(macOS, unavailable)
|
||||
public var gUnavailable: ObsoletedBetweenTargets {
|
||||
ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
|
||||
ObsoletedBetweenTargets()
|
||||
}
|
||||
|
||||
// The inferred types of public properties are exposed.
|
||||
|
||||
@@ -70,7 +70,7 @@ public struct HasUnavailableConformance3 {}
|
||||
|
||||
@available(swift 12)
|
||||
extension HasUnavailableConformance3 : Horse {}
|
||||
// expected-note@-1 12{{conformance of 'HasUnavailableConformance3' to 'Horse' was introduced in Swift 12}}
|
||||
// expected-note@-1 6{{conformance of 'HasUnavailableConformance3' to 'Horse' was introduced in Swift 12}}
|
||||
|
||||
func passUnavailableConformance3(x: HasUnavailableConformance3) {
|
||||
takesHorse(x) // expected-error {{conformance of 'HasUnavailableConformance3' to 'Horse' is unavailable}}
|
||||
@@ -83,12 +83,12 @@ func passUnavailableConformance3(x: HasUnavailableConformance3) {
|
||||
|
||||
@available(swift 12)
|
||||
func passUnavailableConformance3a(x: HasUnavailableConformance3) {
|
||||
takesHorse(x) // expected-error {{conformance of 'HasUnavailableConformance3' to 'Horse' is unavailable}}
|
||||
takesHorseExistential(x) // expected-error {{conformance of 'HasUnavailableConformance3' to 'Horse' is unavailable}}
|
||||
x.giddyUp() // expected-error {{conformance of 'HasUnavailableConformance3' to 'Horse' is unavailable}}
|
||||
_ = x.isGalloping // expected-error {{conformance of 'HasUnavailableConformance3' to 'Horse' is unavailable}}
|
||||
_ = x[keyPath: \.isGalloping] // expected-error {{conformance of 'HasUnavailableConformance3' to 'Horse' is unavailable}}
|
||||
_ = UsesHorse<HasUnavailableConformance3>.self // expected-error {{conformance of 'HasUnavailableConformance3' to 'Horse' is unavailable}}
|
||||
takesHorse(x)
|
||||
takesHorseExistential(x)
|
||||
x.giddyUp()
|
||||
_ = x.isGalloping
|
||||
_ = x[keyPath: \.isGalloping]
|
||||
_ = UsesHorse<HasUnavailableConformance3>.self
|
||||
}
|
||||
|
||||
// Platform obsoleted
|
||||
@@ -96,7 +96,7 @@ public struct HasUnavailableConformance4 {}
|
||||
|
||||
@available(macOS, obsoleted: 10.1)
|
||||
extension HasUnavailableConformance4 : Horse {}
|
||||
// expected-note@-1 12{{conformance of 'HasUnavailableConformance4' to 'Horse' was obsoleted in macOS 10.1}}
|
||||
// expected-note@-1 6{{conformance of 'HasUnavailableConformance4' to 'Horse' was obsoleted in macOS 10.1}}
|
||||
|
||||
func passUnavailableConformance4(x: HasUnavailableConformance4) {
|
||||
takesHorse(x) // expected-error {{conformance of 'HasUnavailableConformance4' to 'Horse' is unavailable in macOS}}
|
||||
@@ -109,12 +109,12 @@ func passUnavailableConformance4(x: HasUnavailableConformance4) {
|
||||
|
||||
@available(macOS, obsoleted: 10.1)
|
||||
func passUnavailableConformance4a(x: HasUnavailableConformance4) {
|
||||
takesHorse(x) // expected-error {{conformance of 'HasUnavailableConformance4' to 'Horse' is unavailable in macOS}}
|
||||
takesHorseExistential(x) // expected-error {{conformance of 'HasUnavailableConformance4' to 'Horse' is unavailable in macOS}}
|
||||
x.giddyUp() // expected-error {{conformance of 'HasUnavailableConformance4' to 'Horse' is unavailable in macOS}}
|
||||
_ = x.isGalloping // expected-error {{conformance of 'HasUnavailableConformance4' to 'Horse' is unavailable}}
|
||||
_ = x[keyPath: \.isGalloping] // expected-error {{conformance of 'HasUnavailableConformance4' to 'Horse' is unavailable}}
|
||||
_ = UsesHorse<HasUnavailableConformance4>.self // expected-error {{conformance of 'HasUnavailableConformance4' to 'Horse' is unavailable in macOS}}
|
||||
takesHorse(x)
|
||||
takesHorseExistential(x)
|
||||
x.giddyUp()
|
||||
_ = x.isGalloping
|
||||
_ = x[keyPath: \.isGalloping]
|
||||
_ = UsesHorse<HasUnavailableConformance4>.self
|
||||
}
|
||||
|
||||
// Swift obsoleted
|
||||
@@ -122,7 +122,7 @@ public struct HasUnavailableConformance5 {}
|
||||
|
||||
@available(swift, obsoleted: 4)
|
||||
extension HasUnavailableConformance5 : Horse {}
|
||||
// expected-note@-1 12{{conformance of 'HasUnavailableConformance5' to 'Horse' was obsoleted in Swift 4}}
|
||||
// expected-note@-1 6{{conformance of 'HasUnavailableConformance5' to 'Horse' was obsoleted in Swift 4}}
|
||||
|
||||
func passUnavailableConformance5(x: HasUnavailableConformance5) {
|
||||
takesHorse(x) // expected-error {{conformance of 'HasUnavailableConformance5' to 'Horse' is unavailable}}
|
||||
@@ -135,12 +135,12 @@ func passUnavailableConformance5(x: HasUnavailableConformance5) {
|
||||
|
||||
@available(swift, obsoleted: 4)
|
||||
func passUnavailableConformance5a(x: HasUnavailableConformance5) {
|
||||
takesHorse(x) // expected-error {{conformance of 'HasUnavailableConformance5' to 'Horse' is unavailable}}
|
||||
takesHorseExistential(x) // expected-error {{conformance of 'HasUnavailableConformance5' to 'Horse' is unavailable}}
|
||||
x.giddyUp() // expected-error {{conformance of 'HasUnavailableConformance5' to 'Horse' is unavailable}}
|
||||
_ = x.isGalloping // expected-error {{conformance of 'HasUnavailableConformance5' to 'Horse' is unavailable}}
|
||||
_ = x[keyPath: \.isGalloping] // expected-error {{conformance of 'HasUnavailableConformance5' to 'Horse' is unavailable}}
|
||||
_ = UsesHorse<HasUnavailableConformance5>.self // expected-error {{conformance of 'HasUnavailableConformance5' to 'Horse' is unavailable}}
|
||||
takesHorse(x)
|
||||
takesHorseExistential(x)
|
||||
x.giddyUp()
|
||||
_ = x.isGalloping
|
||||
_ = x[keyPath: \.isGalloping]
|
||||
_ = UsesHorse<HasUnavailableConformance5>.self
|
||||
}
|
||||
|
||||
// Unavailable with message
|
||||
|
||||
@@ -23,7 +23,7 @@ struct DeprecatedWrapper<T> {
|
||||
|
||||
@available(*, unavailable)
|
||||
@propertyWrapper
|
||||
struct UnavailableWrapper<T> { // expected-note 8 {{'UnavailableWrapper' has been explicitly marked unavailable here}}
|
||||
struct UnavailableWrapper<T> { // expected-note 12 {{'UnavailableWrapper' has been explicitly marked unavailable here}}
|
||||
var wrappedValue: T
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ struct UnavailableOnMacOSStruct {
|
||||
@DeprecatedWrapper var deprecatedExplicit: S
|
||||
@DeprecatedWrapper var deprecatedInferred = S()
|
||||
|
||||
@UnavailableWrapper var unavailableExplicit: S
|
||||
@UnavailableWrapper var unavailableInferred = S()
|
||||
@UnavailableWrapper var unavailableExplicit: S // expected-error {{'UnavailableWrapper' is unavailable}}
|
||||
@UnavailableWrapper var unavailableInferred = S() // expected-error {{'UnavailableWrapper' is unavailable}}
|
||||
|
||||
@WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S
|
||||
@WrappedValueAvailable51 var wrappedValueAavailable51: S
|
||||
@@ -175,14 +175,14 @@ func unavailableOnMacOSFunc(
|
||||
@AlwaysAvailableWrapper _ alwaysAvailable: S,
|
||||
@Available51Wrapper _ available51: S,
|
||||
@DeprecatedWrapper _ deprecated: S,
|
||||
@UnavailableWrapper _ unavailable: S,
|
||||
@UnavailableWrapper _ unavailable: S, // expected-error {{'UnavailableWrapper' is unavailable}}
|
||||
@WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S,
|
||||
@WrappedValueAvailable51 _ wrappedValueAavailable51: S
|
||||
) {
|
||||
@AlwaysAvailableWrapper var alwaysAvailableLocal = S()
|
||||
@Available51Wrapper var available51Local = S()
|
||||
@DeprecatedWrapper var deprecatedLocal = S()
|
||||
@UnavailableWrapper var unavailableLocal = S()
|
||||
@UnavailableWrapper var unavailableLocal = S() // expected-error {{'UnavailableWrapper' is unavailable}}
|
||||
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S()
|
||||
@WrappedValueAvailable51 var wrappedValueAavailable51 = S()
|
||||
}
|
||||
|
||||
@@ -27,13 +27,13 @@ func never() -> NeverAvailable { // expected-note * {{'never()' has been explici
|
||||
@available(swift, obsoleted: 4)
|
||||
@discardableResult
|
||||
func unavailableInSwift4() -> UnavailableInSwift4 { // expected-note * {{'unavailableInSwift4()' was obsoleted in Swift 4}}
|
||||
UnavailableInSwift4() // expected-error {{'UnavailableInSwift4' is unavailable}}
|
||||
UnavailableInSwift4()
|
||||
}
|
||||
|
||||
@available(swift, introduced: 99)
|
||||
@discardableResult
|
||||
func availableInFutureSwift() -> AvailableInFutureSwift { // expected-note * {{'availableInFutureSwift()' was introduced in Swift 99}}
|
||||
AvailableInFutureSwift() // expected-error {{'AvailableInFutureSwift' is unavailable}}
|
||||
AvailableInFutureSwift()
|
||||
}
|
||||
|
||||
// MARK: Global functions
|
||||
@@ -59,34 +59,34 @@ func never_available_func(
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
|
||||
@available(swift, obsoleted: 4)
|
||||
func unavailable_in_swift4_func(
|
||||
_: AlwaysAvailable,
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: UnavailableInSwift4,
|
||||
_: AvailableInFutureSwift,
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
|
||||
@available(swift, introduced: 99)
|
||||
func introduced_in_future_swift_func(
|
||||
_: AlwaysAvailable,
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: UnavailableInSwift4,
|
||||
_: AvailableInFutureSwift,
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
|
||||
// MARK: Global vars
|
||||
@@ -112,34 +112,34 @@ var never_var: (
|
||||
) = (
|
||||
always(),
|
||||
never(), // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4(), // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift(), // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4(),
|
||||
availableInFutureSwift(),
|
||||
)
|
||||
|
||||
@available(swift, obsoleted: 4)
|
||||
var unavailable_in_swift4_var: (
|
||||
AlwaysAvailable,
|
||||
NeverAvailable,
|
||||
NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
UnavailableInSwift4,
|
||||
AvailableInFutureSwift
|
||||
) = (
|
||||
always(),
|
||||
never(), // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4(), // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift(), // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4(),
|
||||
availableInFutureSwift(),
|
||||
)
|
||||
|
||||
@available(swift, introduced: 99)
|
||||
var available_in_future_swift_var: (
|
||||
AlwaysAvailable,
|
||||
NeverAvailable,
|
||||
NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
UnavailableInSwift4,
|
||||
AvailableInFutureSwift
|
||||
) = (
|
||||
always(),
|
||||
never(), // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4(), // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift(), // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4(),
|
||||
availableInFutureSwift(),
|
||||
)
|
||||
|
||||
|
||||
@@ -156,27 +156,29 @@ struct AlwaysAvailableContainer {
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
struct NeverAvailableContainer { // expected-note {{'NeverAvailableContainer' has been explicitly marked unavailable here}}
|
||||
struct NeverAvailableContainer { // expected-note 3 {{'NeverAvailableContainer' has been explicitly marked unavailable here}}
|
||||
let always_var: AlwaysAvailable = always()
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
let unavailable_in_swift4_var: UnavailableInSwift4 = unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
let available_in_future_swift_var: AvailableInFutureSwift = availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
let unavailable_in_swift4_var: UnavailableInSwift4 = unavailableInSwift4()
|
||||
let available_in_future_swift_var: AvailableInFutureSwift = availableInFutureSwift()
|
||||
}
|
||||
|
||||
@available(swift, obsoleted: 4)
|
||||
struct UnavailableInSwift4Container { // expected-note {{'UnavailableInSwift4Container' was obsoleted in Swift 4}}
|
||||
let always_var: AlwaysAvailable = always()
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
let unavailable_in_swift4_var: UnavailableInSwift4 = unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
let available_in_future_swift_var: AvailableInFutureSwift = availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
// expected-error@-1 {{'NeverAvailable' is unavailable}}
|
||||
let unavailable_in_swift4_var: UnavailableInSwift4 = unavailableInSwift4()
|
||||
let available_in_future_swift_var: AvailableInFutureSwift = availableInFutureSwift()
|
||||
}
|
||||
|
||||
@available(swift, introduced: 99)
|
||||
struct AvailableInFutureSwiftContainer { // expected-note {{'AvailableInFutureSwiftContainer' was introduced in Swift 99}}
|
||||
let always_var: AlwaysAvailable = always()
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
let unavailable_in_swift4_var: UnavailableInSwift4 = unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
let available_in_future_swift_var: AvailableInFutureSwift = availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
// expected-error@-1 {{'NeverAvailable' is unavailable}}
|
||||
let unavailable_in_swift4_var: UnavailableInSwift4 = unavailableInSwift4()
|
||||
let available_in_future_swift_var: AvailableInFutureSwift = availableInFutureSwift()
|
||||
}
|
||||
|
||||
// MARK: Extensions
|
||||
@@ -198,7 +200,7 @@ extension AvailableInFutureSwiftContainer {}
|
||||
@available(swift, obsoleted: 4)
|
||||
extension AlwaysAvailableContainer {}
|
||||
@available(swift, obsoleted: 4)
|
||||
extension NeverAvailableContainer {}
|
||||
extension NeverAvailableContainer {} // expected-error {{'NeverAvailableContainer' is unavailable}}
|
||||
@available(swift, obsoleted: 4)
|
||||
extension UnavailableInSwift4Container {}
|
||||
@available(swift, obsoleted: 4)
|
||||
@@ -207,7 +209,7 @@ extension AvailableInFutureSwiftContainer {}
|
||||
@available(swift, introduced: 99)
|
||||
extension AlwaysAvailableContainer {}
|
||||
@available(swift, introduced: 99)
|
||||
extension NeverAvailableContainer {}
|
||||
extension NeverAvailableContainer {} // expected-error {{'NeverAvailableContainer' is unavailable}}
|
||||
@available(swift, introduced: 99)
|
||||
extension UnavailableInSwift4Container {}
|
||||
@available(swift, introduced: 99)
|
||||
@@ -227,8 +229,8 @@ extension ExtendMe {
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
@@ -240,8 +242,8 @@ extension ExtendMe {
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
|
||||
@available(swift, obsoleted: 4)
|
||||
@@ -253,8 +255,8 @@ extension ExtendMe {
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
|
||||
@available(swift, introduced: 99)
|
||||
@@ -266,10 +268,9 @@ extension ExtendMe {
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@available(swift, obsoleted: 4)
|
||||
@@ -285,8 +286,8 @@ extension ExtendMe {
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,8 +304,8 @@ extension ExtendMe {
|
||||
) {
|
||||
always()
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
unavailableInSwift4() // expected-error {{'unavailableInSwift4()' is unavailable}}
|
||||
availableInFutureSwift() // expected-error {{'availableInFutureSwift()' is unavailable}}
|
||||
unavailableInSwift4()
|
||||
availableInFutureSwift()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ func never_available_func(
|
||||
@available(OSX, unavailable)
|
||||
func osx_func(
|
||||
_: AlwaysAvailable,
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXFutureAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: MultiPlatformUnavailable,
|
||||
@@ -166,7 +166,7 @@ var never_var: (
|
||||
@available(OSX, unavailable)
|
||||
var osx_var: (
|
||||
AlwaysAvailable,
|
||||
NeverAvailable,
|
||||
NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
OSXFutureAvailable,
|
||||
OSXUnavailable,
|
||||
MultiPlatformUnavailable,
|
||||
@@ -213,7 +213,7 @@ struct AlwaysAvailableContainer { // expected-note 2 {{add '@available' attribut
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
struct NeverAvailableContainer { // expected-note 2 {{'NeverAvailableContainer' has been explicitly marked unavailable here}}
|
||||
struct NeverAvailableContainer { // expected-note 3 {{'NeverAvailableContainer' has been explicitly marked unavailable here}}
|
||||
let always_var: AlwaysAvailable = always()
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
let osx_future_var: OSXFutureAvailable = osx_future()
|
||||
@@ -226,6 +226,7 @@ struct NeverAvailableContainer { // expected-note 2 {{'NeverAvailableContainer'
|
||||
struct OSXUnavailableContainer { // expected-note 2 {{'OSXUnavailableContainer' has been explicitly marked unavailable here}}
|
||||
let always_var: AlwaysAvailable = always()
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
// expected-error@-1 {{'NeverAvailable' is unavailable}}
|
||||
let osx_future_var: OSXFutureAvailable = osx_future()
|
||||
let osx_var: OSXUnavailable = osx()
|
||||
let osx_ios_var: MultiPlatformUnavailable = osx_ios()
|
||||
@@ -265,7 +266,7 @@ extension OSXAppExtensionsUnavailableContainer {}
|
||||
@available(OSX, unavailable)
|
||||
extension AlwaysAvailableContainer {}
|
||||
@available(OSX, unavailable)
|
||||
extension NeverAvailableContainer {}
|
||||
extension NeverAvailableContainer {} // expected-error {{'NeverAvailableContainer' is unavailable}}
|
||||
@available(OSX, unavailable)
|
||||
extension OSXUnavailableContainer {}
|
||||
@available(OSX, unavailable)
|
||||
@@ -366,7 +367,7 @@ extension ExtendMe {
|
||||
|
||||
func osx_extension_available_method( // expected-note * {{add '@available' attribute to enclosing instance method}}
|
||||
_: AlwaysAvailable,
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXFutureAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: MultiPlatformUnavailable,
|
||||
@@ -400,7 +401,7 @@ extension ExtendMe {
|
||||
@available(OSX, unavailable)
|
||||
func osx_extension_osx_method(
|
||||
_: AlwaysAvailable,
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXFutureAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: MultiPlatformUnavailable,
|
||||
@@ -417,7 +418,7 @@ extension ExtendMe {
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
func osx_extension_osx_app_extension_method(
|
||||
_: AlwaysAvailable,
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXFutureAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: MultiPlatformUnavailable,
|
||||
@@ -476,7 +477,7 @@ extension ExtendMe { // expected-note * {{add '@available' attribute to enclosin
|
||||
@available(OSX, unavailable)
|
||||
func osx_app_extension_extension_osx_method(
|
||||
_: AlwaysAvailable,
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXFutureAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: MultiPlatformUnavailable,
|
||||
@@ -522,7 +523,7 @@ func available_func_call_extension_methods(_ e: ExtendMe) { // expected-note {{a
|
||||
}
|
||||
|
||||
@available(OSX, obsoleted: 10.9)
|
||||
struct OSXObsoleted {} // expected-note 4 {{'OSXObsoleted' was obsoleted in macOS 10.9}}
|
||||
struct OSXObsoleted {}
|
||||
|
||||
@available(OSX, unavailable)
|
||||
@available(OSX, introduced: 99)
|
||||
@@ -549,16 +550,15 @@ func osx_unavailable_func(
|
||||
OSXUnavailableAndIntroducedInFutureSameAttribute,
|
||||
OSXIntroducedInFutureAndUnavailable
|
||||
) {
|
||||
// FIXME: [availability] Stop diagnosing obsoletion in an unavailable context.
|
||||
_ = OSXFutureAvailable()
|
||||
_ = OSXObsoleted() // expected-error {{'OSXObsoleted' is unavailable in macOS}}
|
||||
_ = OSXObsoleted()
|
||||
_ = OSXUnavailableAndIntroducedInFuture()
|
||||
_ = OSXUnavailableAndIntroducedInFutureSameAttribute()
|
||||
_ = OSXIntroducedInFutureAndUnavailable()
|
||||
|
||||
func takesType<T>(_ t: T.Type) {}
|
||||
takesType(OSXFutureAvailable.self)
|
||||
takesType(OSXObsoleted.self) // expected-error {{'OSXObsoleted' is unavailable in macOS}}
|
||||
takesType(OSXObsoleted.self)
|
||||
takesType(OSXUnavailableAndIntroducedInFuture.self)
|
||||
takesType(OSXUnavailableAndIntroducedInFutureSameAttribute.self)
|
||||
takesType(OSXIntroducedInFutureAndUnavailable.self)
|
||||
@@ -580,16 +580,15 @@ func osx_unavailable_and_introduced_func(
|
||||
OSXUnavailableAndIntroducedInFutureSameAttribute,
|
||||
OSXIntroducedInFutureAndUnavailable
|
||||
) {
|
||||
// FIXME: [availability] Stop diagnosing obsoletion in an unavailable context.
|
||||
_ = OSXFutureAvailable()
|
||||
_ = OSXObsoleted() // expected-error {{'OSXObsoleted' is unavailable in macOS}}
|
||||
_ = OSXObsoleted()
|
||||
_ = OSXUnavailableAndIntroducedInFuture()
|
||||
_ = OSXUnavailableAndIntroducedInFutureSameAttribute()
|
||||
_ = OSXIntroducedInFutureAndUnavailable()
|
||||
|
||||
func takesType<T>(_ t: T.Type) {}
|
||||
takesType(OSXFutureAvailable.self)
|
||||
takesType(OSXObsoleted.self) // expected-error {{'OSXObsoleted' is unavailable in macOS}}
|
||||
takesType(OSXObsoleted.self)
|
||||
takesType(OSXUnavailableAndIntroducedInFuture.self)
|
||||
takesType(OSXUnavailableAndIntroducedInFutureSameAttribute.self)
|
||||
takesType(OSXIntroducedInFutureAndUnavailable.self)
|
||||
|
||||
@@ -55,7 +55,7 @@ func never_available_func(
|
||||
|
||||
@available(OSX, unavailable)
|
||||
func osx_func(
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable,
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
@@ -66,8 +66,8 @@ func osx_func(
|
||||
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
func osx_extension_func(
|
||||
_: NeverAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable, // expected-error {{'OSXUnavailable' is unavailable in macOS}}
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
@@ -100,7 +100,7 @@ var never_var: (
|
||||
|
||||
@available(OSX, unavailable)
|
||||
var osx_var: (
|
||||
NeverAvailable,
|
||||
NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
OSXUnavailable,
|
||||
OSXAppExtensionsUnavailable
|
||||
) = (
|
||||
@@ -111,8 +111,8 @@ var osx_var: (
|
||||
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
var osx_extension_var: (
|
||||
NeverAvailable,
|
||||
OSXUnavailable,
|
||||
NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
OSXUnavailable, // expected-error {{'OSXUnavailable' is unavailable in macOS}}
|
||||
OSXAppExtensionsUnavailable
|
||||
) = (
|
||||
never(), // expected-error {{'never()' is unavailable}}
|
||||
@@ -132,15 +132,16 @@ struct AlwaysAvailabileContainer {
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
struct NeverAvailableContainer { // expected-note {{'NeverAvailableContainer' has been explicitly marked unavailable here}}
|
||||
struct NeverAvailableContainer { // expected-note 3 {{'NeverAvailableContainer' has been explicitly marked unavailable here}}
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
let osx_var: OSXUnavailable = osx()
|
||||
let osx_extension_var: OSXAppExtensionsUnavailable = osx_extension()
|
||||
}
|
||||
|
||||
@available(OSX, unavailable)
|
||||
struct OSXUnavailableContainer { // expected-note {{'OSXUnavailableContainer' has been explicitly marked unavailable here}}
|
||||
struct OSXUnavailableContainer { // expected-note 2 {{'OSXUnavailableContainer' has been explicitly marked unavailable here}}
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
// expected-error@-1 {{'NeverAvailable' is unavailable}}
|
||||
let osx_var: OSXUnavailable = osx()
|
||||
let osx_extension_var: OSXAppExtensionsUnavailable = osx_extension()
|
||||
}
|
||||
@@ -148,7 +149,9 @@ struct OSXUnavailableContainer { // expected-note {{'OSXUnavailableContainer' ha
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
struct OSXAppExtensionsUnavailableContainer { // expected-note {{'OSXAppExtensionsUnavailableContainer' has been explicitly marked unavailable here}}
|
||||
let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}}
|
||||
// expected-error@-1 {{'NeverAvailable' is unavailable}}
|
||||
let osx_var: OSXUnavailable = osx() // expected-error {{'osx()' is unavailable}}
|
||||
// expected-error@-1 {{'OSXUnavailable' is unavailable in macOS}}
|
||||
let osx_extension_var: OSXAppExtensionsUnavailable = osx_extension()
|
||||
}
|
||||
|
||||
@@ -171,7 +174,7 @@ extension OSXAppExtensionsUnavailableContainer {}
|
||||
@available(OSX, unavailable)
|
||||
extension AlwaysAvailabileContainer {}
|
||||
@available(OSX, unavailable)
|
||||
extension NeverAvailableContainer {}
|
||||
extension NeverAvailableContainer {} // expected-error {{'NeverAvailableContainer' is unavailable}}
|
||||
@available(OSX, unavailable)
|
||||
extension OSXUnavailableContainer {}
|
||||
@available(OSX, unavailable)
|
||||
@@ -180,9 +183,9 @@ extension OSXAppExtensionsUnavailableContainer {}
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
extension AlwaysAvailabileContainer {}
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
extension NeverAvailableContainer {}
|
||||
extension NeverAvailableContainer {} // expected-error {{'NeverAvailableContainer' is unavailable}}
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
extension OSXUnavailableContainer {}
|
||||
extension OSXUnavailableContainer {} // expected-error {{'OSXUnavailableContainer' is unavailable in macOS}}
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
extension OSXAppExtensionsUnavailableContainer {}
|
||||
|
||||
@@ -256,7 +259,7 @@ extension ExtendMe {
|
||||
func osx_extension_osx_app_extension_method() {} // expected-note 2 {{'osx_extension_osx_app_extension_method()' has been explicitly marked unavailable here}}
|
||||
|
||||
func osx_extension_available_method(
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable,
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
@@ -278,7 +281,7 @@ extension ExtendMe {
|
||||
|
||||
@available(OSX, unavailable)
|
||||
func osx_extension_osx_method(
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable,
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
@@ -289,7 +292,7 @@ extension ExtendMe {
|
||||
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
func osx_extension_osx_app_extension_method(
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable,
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
@@ -316,8 +319,8 @@ extension ExtendMe {
|
||||
func osx_app_extension_extension_osx_app_extension_method() {} // expected-note {{'osx_app_extension_extension_osx_app_extension_method()' has been explicitly marked unavailable here}}
|
||||
|
||||
func osx_app_extension_extension_available_method(
|
||||
_: NeverAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable, // expected-error {{'OSXUnavailable' is unavailable in macOS}}
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
@@ -338,7 +341,7 @@ extension ExtendMe {
|
||||
|
||||
@available(OSX, unavailable)
|
||||
func osx_app_extension_extension_osx_method(
|
||||
_: NeverAvailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable,
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
@@ -349,8 +352,8 @@ extension ExtendMe {
|
||||
|
||||
@available(OSXApplicationExtension, unavailable)
|
||||
func osx_app_extension_extension_osx_app_extension_method(
|
||||
_: NeverAvailable,
|
||||
_: OSXUnavailable,
|
||||
_: NeverAvailable, // expected-error {{'NeverAvailable' is unavailable}}
|
||||
_: OSXUnavailable, // expected-error {{'OSXUnavailable' is unavailable in macOS}}
|
||||
_: OSXAppExtensionsUnavailable
|
||||
) {
|
||||
never() // expected-error {{'never()' is unavailable}}
|
||||
|
||||
@@ -9,7 +9,7 @@ public struct UnavailableInEmbedded {}
|
||||
|
||||
@available(*, unavailable, message: "always unavailable")
|
||||
public struct UniverallyUnavailable {}
|
||||
// expected-note@-1 {{'UniverallyUnavailable' has been explicitly marked unavailable here}}
|
||||
// expected-note@-1 3 {{'UniverallyUnavailable' has been explicitly marked unavailable here}}
|
||||
|
||||
@_unavailableInEmbedded
|
||||
public func unavailable_in_embedded() { }
|
||||
@@ -41,7 +41,7 @@ public struct Available {}
|
||||
extension Available {
|
||||
public func unavailable_in_embedded_method( // expected-note {{'unavailable_in_embedded_method' has been explicitly marked unavailable here}}
|
||||
_ uie: UnavailableInEmbedded,
|
||||
_ uu: UniverallyUnavailable,
|
||||
_ uu: UniverallyUnavailable, // expected-error {{'UniverallyUnavailable' is unavailable: always unavailable}}
|
||||
_ a: Available,
|
||||
) {
|
||||
unavailable_in_embedded()
|
||||
@@ -65,7 +65,7 @@ public func available(
|
||||
@_unavailableInEmbedded
|
||||
public func also_unavailable_in_embedded(
|
||||
_ uie: UnavailableInEmbedded, // OK
|
||||
_ uu: UniverallyUnavailable, // OK
|
||||
_ uu: UniverallyUnavailable, // expected-error {{'UniverallyUnavailable' is unavailable: always unavailable}}
|
||||
_ a: Available,
|
||||
) {
|
||||
unavailable_in_embedded() // OK
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// {"kind":"typecheck","signature":"constrainDomainInfos(llvm::SmallVectorImpl<swift::AvailabilityContext::DomainInfo>&, llvm::ArrayRef<swift::AvailabilityContext::DomainInfo>)","signatureAssert":"Assertion failed: (!isConstrained), function constrainDomainInfos"}
|
||||
// RUN: not --crash %target-swift-frontend -typecheck %s
|
||||
// RUN: not %target-swift-frontend -typecheck %s
|
||||
@available(*, unavailable) @available(_PackageDescription 3) func a {
|
||||
@available(_PackageDescription 5) func b
|
||||
Reference in New Issue
Block a user