Skip to content

Commit 1ca852e

Browse files
committed
[Sema] Accept unavailable constructors override in unavailable types
Preserve the old behavior of accepted unavailable override of constructors as this change would be source breaking.
1 parent d2343f2 commit 1ca852e

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,8 @@ static bool diagnoseOverrideForAvailability(ValueDecl *override,
16871687
if (isRedundantAccessorOverrideAvailabilityDiagnostic(override, base))
16881688
return false;
16891689

1690-
auto &diags = override->getASTContext().Diags;
1690+
auto &ctx = override->getASTContext();
1691+
auto &diags = ctx.Diags;
16911692
if (auto *accessor = dyn_cast<AccessorDecl>(override)) {
16921693
diags.diagnose(override, diag::override_accessor_less_available,
16931694
accessor->getDescriptiveKind(),
@@ -1696,6 +1697,15 @@ static bool diagnoseOverrideForAvailability(ValueDecl *override,
16961697
return true;
16971698
}
16981699

1700+
// Don't report constructors that are marked unavailable as being less
1701+
// available than their introduction. This was previously allowed and
1702+
// can be used to forbid the direct use of a constructor in a subclass.
1703+
// Note that even when marked unavailable the constructor could be called
1704+
// by other inherited constructors.
1705+
if (isa<ConstructorDecl>(override) &&
1706+
override->getAttrs().isUnavailable(ctx))
1707+
return false;
1708+
16991709
diags.diagnose(override, diag::override_less_available,
17001710
override->getBaseName());
17011711
diags.diagnose(base, diag::overridden_here);

test/Sema/availability_versions.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,9 @@ class UnavailableClassExtendingUnavailableClass : ClassAvailableOn10_51 {
788788
// Method availability is contravariant
789789

790790
class SuperWithAlwaysAvailableMembers {
791+
792+
required init() {} // expected-note {{overridden declaration is here}}
793+
791794
func shouldAlwaysBeAvailableMethod() { // expected-note 2 {{overridden declaration is here}}
792795
}
793796

@@ -808,6 +811,10 @@ class SuperWithAlwaysAvailableMembers {
808811
}
809812

810813
class SubWithLimitedMemberAvailability : SuperWithAlwaysAvailableMembers {
814+
815+
@available(OSX, introduced: 10.51)
816+
required init() {} // expected-error {{overriding 'init' must be as available as declaration it overrides}}
817+
811818
@available(OSX, introduced: 10.51)
812819
override func shouldAlwaysBeAvailableMethod() { // expected-error {{overriding 'shouldAlwaysBeAvailableMethod' must be as available as declaration it overrides}}
813820
}
@@ -833,6 +840,10 @@ class SubWithLimitedMemberAvailability : SuperWithAlwaysAvailableMembers {
833840
}
834841

835842
class SubWithUnavailableMembers : SuperWithAlwaysAvailableMembers {
843+
844+
@available(OSX, unavailable)
845+
required init() {}
846+
836847
@available(OSX, unavailable)
837848
override func shouldAlwaysBeAvailableMethod() { // expected-error {{overriding 'shouldAlwaysBeAvailableMethod' must be as available as declaration it overrides}}
838849
}

0 commit comments

Comments
 (0)