Skip to content

Commit 4276771

Browse files
committed
Sema: Consolidate diagnostics for decls that cannot be unavailable.
1 parent 6284dd4 commit 4276771

File tree

3 files changed

+26
-24
lines changed

3 files changed

+26
-24
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5097,23 +5097,10 @@ void AttributeChecker::checkAvailableAttrs(ArrayRef<AvailableAttr *> attrs) {
50975097
if (availabilityConstraint->isUnavailable()) {
50985098
auto attr = availabilityConstraint->getAttr();
50995099
if (auto diag = TypeChecker::diagnosticIfDeclCannotBeUnavailable(D)) {
5100-
diagnose(attr.getParsedAttr()->getLocation(), diag.value());
5100+
diagnoseAndRemoveAttr(const_cast<AvailableAttr *>(attr.getParsedAttr()),
5101+
diag.value());
51015102
return;
51025103
}
5103-
5104-
if (auto *PD = dyn_cast<ProtocolDecl>(D->getDeclContext())) {
5105-
if (auto *VD = dyn_cast<ValueDecl>(D)) {
5106-
if (VD->isProtocolRequirement() && !PD->isObjC()) {
5107-
diagnoseAndRemoveAttr(
5108-
const_cast<AvailableAttr *>(attr.getParsedAttr()),
5109-
diag::unavailable_method_non_objc_protocol)
5110-
.warnInSwiftInterface(D->getDeclContext());
5111-
// Be lenient in interfaces to accomodate @_spi_available, which has
5112-
// been accepted historically.
5113-
return;
5114-
}
5115-
}
5116-
}
51175104
}
51185105

51195106
// If the decl is potentially unavailable relative to its parent and it's
@@ -5484,6 +5471,21 @@ TypeChecker::diagnosticIfDeclCannotBeUnavailable(const Decl *D) {
54845471
return Diagnostic(diag::availability_decl_no_unavailable, D);
54855472
}
54865473

5474+
auto DC = D->getDeclContext();
5475+
if (auto *PD = dyn_cast<ProtocolDecl>(DC)) {
5476+
if (auto *VD = dyn_cast<ValueDecl>(D)) {
5477+
if (VD->isProtocolRequirement() && !PD->isObjC()) {
5478+
auto diag = Diagnostic(diag::unavailable_method_non_objc_protocol);
5479+
5480+
// Be lenient in interfaces to accomodate @_spi_available, which has
5481+
// been accepted historically.
5482+
if (DC->isInSwiftinterface())
5483+
diag.setBehaviorLimit(DiagnosticBehavior::Warning);
5484+
return diag;
5485+
}
5486+
}
5487+
}
5488+
54875489
if (auto *VD = dyn_cast<VarDecl>(D)) {
54885490
if (!VD->hasStorageOrWrapsStorage())
54895491
return std::nullopt;

test/Sema/availability_script_mode.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ struct Available50 {}
1111
struct Available51 {}
1212

1313
@available(macOS, unavailable)
14-
struct UnavailableOnMacOS {}
14+
struct UnavailableOnMacOS {} // expected-note {{'UnavailableOnMacOS' has been explicitly marked unavailable here}}
1515

1616
@available(*, unavailable)
17-
struct UnavailableUnconditionally {}
17+
struct UnavailableUnconditionally {} // expected-note {{'UnavailableUnconditionally' has been explicitly marked unavailable here}}
1818

1919
var alwaysAvailableVar: AlwaysAvailable = .init() // Ok
2020

@@ -28,7 +28,7 @@ var availableOn50Var: Available50 = .init() // Ok
2828
var potentiallyUnavailableVar: Available51 = .init()
2929

3030
@available(macOS, unavailable) // expected-error {{global variable cannot be marked unavailable with '@available' in script mode}}
31-
var unavailableOnMacOSVar: UnavailableOnMacOS = .init()
31+
var unavailableOnMacOSVar: UnavailableOnMacOS = .init() // expected-error {{'UnavailableOnMacOS' is unavailable in macOS}}
3232

3333
@available(*, unavailable) // expected-error {{global variable cannot be marked unavailable with '@available' in script mode}}
34-
var unconditionallyUnavailableVar: UnavailableUnconditionally = .init()
34+
var unconditionallyUnavailableVar: UnavailableUnconditionally = .init() // expected-error {{'UnavailableUnconditionally' is unavailable}}

test/Sema/availability_stored_unavailable.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
// REQUIRES: OS=macosx
44

55
@available(macOS, unavailable)
6-
struct UnavailableMacOSStruct {}
6+
struct UnavailableMacOSStruct {} // expected-note 2 {{'UnavailableMacOSStruct' has been explicitly marked unavailable here}}
77

88
@available(*, unavailable)
9-
public struct UniversallyUnavailableStruct {}
9+
public struct UniversallyUnavailableStruct {} // expected-note {{'UniversallyUnavailableStruct' has been explicitly marked unavailable here}}
1010

1111
// Ok, initialization of globals is lazy and boxed.
1212
@available(macOS, unavailable)
@@ -61,15 +61,15 @@ struct GoodUniversallyUnavailableStruct {
6161
struct BadStruct {
6262
// expected-error@+1 {{stored properties cannot be marked unavailable with '@available'}}
6363
@available(macOS, unavailable)
64-
var unavailableMacOS: UnavailableMacOSStruct = .init()
64+
var unavailableMacOS: UnavailableMacOSStruct = .init() // expected-error {{'UnavailableMacOSStruct' is unavailable in macOS}}
6565

6666
// expected-error@+1 {{stored properties cannot be marked unavailable with '@available'}}
6767
@available(macOS, unavailable)
68-
lazy var lazyUnavailableMacOS: UnavailableMacOSStruct = .init()
68+
lazy var lazyUnavailableMacOS: UnavailableMacOSStruct = .init() // expected-error {{'UnavailableMacOSStruct' is unavailable in macOS}}
6969

7070
// expected-error@+1 {{stored properties cannot be marked unavailable with '@available'}}
7171
@available(*, unavailable)
72-
var universallyUnavailable: UniversallyUnavailableStruct = .init()
72+
var universallyUnavailable: UniversallyUnavailableStruct = .init() // expected-error {{'UniversallyUnavailableStruct' is unavailable}}
7373
}
7474

7575
enum GoodAvailableEnum {

0 commit comments

Comments
 (0)