Skip to content

Commit fb76ff1

Browse files
committed
[Sema] Report non-constructor unavailable overrides as warnings
Report unavailable overrides as a warning to avoid breaking sources.
1 parent fca7d36 commit fb76ff1

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,10 +2455,16 @@ NOTE(suggest_removing_override, none,
24552455
ERROR(override_less_available,none,
24562456
"overriding %0 must be as available as declaration it overrides",
24572457
(DeclBaseName))
2458+
WARNING(override_less_available_warn,none,
2459+
"overriding %0 must be as available as declaration it overrides",
2460+
(DeclBaseName))
24582461

24592462
ERROR(override_accessor_less_available,none,
24602463
"overriding %0 for %1 must be as available as declaration it overrides",
24612464
(DescriptiveDeclKind, DeclBaseName))
2465+
WARNING(override_accessor_less_available_warn,none,
2466+
"overriding %0 for %1 must be as available as declaration it overrides",
2467+
(DescriptiveDeclKind, DeclBaseName))
24622468

24632469
ERROR(override_let_property,none,
24642470
"cannot override immutable 'let' property %0 with the getter of a 'var'",

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,23 +1690,34 @@ static bool diagnoseOverrideForAvailability(ValueDecl *override,
16901690
auto &ctx = override->getASTContext();
16911691
auto &diags = ctx.Diags;
16921692
if (auto *accessor = dyn_cast<AccessorDecl>(override)) {
1693-
diags.diagnose(override, diag::override_accessor_less_available,
1693+
bool downgradeToWarning = override->getAttrs().isUnavailable(ctx);
1694+
diags.diagnose(override,
1695+
downgradeToWarning?
1696+
diag::override_accessor_less_available_warn :
1697+
diag::override_accessor_less_available,
16941698
accessor->getDescriptiveKind(),
16951699
accessor->getStorage()->getBaseName());
16961700
diags.diagnose(base, diag::overridden_here);
16971701
return true;
16981702
}
16991703

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;
1704+
bool downgradeToWarning = false;
1705+
if (override->getAttrs().isUnavailable(ctx)) {
1706+
// Don't report constructors that are marked unavailable as being less
1707+
// available than their introduction. This was previously allowed and
1708+
// can be used to forbid the direct use of a constructor in a subclass.
1709+
// Note that even when marked unavailable the constructor could be called
1710+
// by other inherited constructors.
1711+
if (isa<ConstructorDecl>(override))
1712+
return false;
1713+
1714+
// Report as a warning other unavailable overrides.
1715+
downgradeToWarning = true;
1716+
}
17081717

1709-
diags.diagnose(override, diag::override_less_available,
1718+
diags.diagnose(override,
1719+
downgradeToWarning? diag::override_less_available_warn :
1720+
diag::override_less_available,
17101721
override->getBaseName());
17111722
diags.diagnose(base, diag::overridden_here);
17121723

test/Sema/availability_versions.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -845,25 +845,25 @@ class SubWithUnavailableMembers : SuperWithAlwaysAvailableMembers {
845845
required init() {}
846846

847847
@available(OSX, unavailable)
848-
override func shouldAlwaysBeAvailableMethod() { // expected-error {{overriding 'shouldAlwaysBeAvailableMethod' must be as available as declaration it overrides}}
848+
override func shouldAlwaysBeAvailableMethod() { // expected-warning {{overriding 'shouldAlwaysBeAvailableMethod' must be as available as declaration it overrides}}
849849
}
850850

851851
@available(OSX, unavailable)
852-
override var shouldAlwaysBeAvailableProperty: Int { // expected-error {{overriding 'shouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}}
852+
override var shouldAlwaysBeAvailableProperty: Int { // expected-warning {{overriding 'shouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}}
853853
get { return 10 }
854854
set(newVal) {}
855855
}
856856

857857
override var setterShouldAlwaysBeAvailableProperty: Int {
858858
get { return 9 }
859859
@available(OSX, unavailable)
860-
set(newVal) {} // expected-error {{overriding setter for 'setterShouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}}
860+
set(newVal) {} // expected-warning {{overriding setter for 'setterShouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}}
861861
// This is a terrible diagnostic. rdar://problem/20427938
862862
}
863863

864864
override var getterShouldAlwaysBeAvailableProperty: Int {
865865
@available(OSX, unavailable)
866-
get { return 9 } // expected-error {{overriding getter for 'getterShouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}}
866+
get { return 9 } // expected-warning {{overriding getter for 'getterShouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}}
867867
set(newVal) {}
868868
}
869869
}

0 commit comments

Comments
 (0)