Skip to content

Commit 9a0f9d1

Browse files
rintarojrose-apple
authored andcommitted
[Sema] Minimum access for override method is fileprivate (#4404)
1 parent f66da2e commit 9a0f9d1

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5549,11 +5549,12 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
55495549
std::min(classDecl->getFormalAccess(), overriddenAccess);
55505550
if (requiredAccess == Accessibility::Open && decl->isFinal())
55515551
requiredAccess = Accessibility::Public;
5552+
else if (requiredAccess == Accessibility::Private)
5553+
requiredAccess = Accessibility::FilePrivate;
55525554

55535555
bool shouldDiagnose = false;
55545556
bool shouldDiagnoseSetter = false;
5555-
if (requiredAccess > Accessibility::Private &&
5556-
!isa<ConstructorDecl>(decl)) {
5557+
if (!isa<ConstructorDecl>(decl)) {
55575558
shouldDiagnose = (decl->getFormalAccess() < requiredAccess);
55585559

55595560
if (!shouldDiagnose && matchDecl->isSettable(classDecl)) {
@@ -5563,6 +5564,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
55635564
const DeclContext *accessDC = nullptr;
55645565
if (requiredAccess == Accessibility::Internal)
55655566
accessDC = classDecl->getParentModule();
5567+
else if (requiredAccess == Accessibility::FilePrivate)
5568+
accessDC = classDecl->getDeclContext();
55665569
shouldDiagnoseSetter = ASD->isSettable(accessDC) &&
55675570
!ASD->isSetterAccessibleFrom(accessDC);
55685571
}
@@ -6495,11 +6498,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
64956498

64966499
if (CD->isRequired() && ContextTy) {
64976500
if (auto nominal = ContextTy->getAnyNominal()) {
6498-
if (CD->getFormalAccess() <
6499-
std::min(nominal->getFormalAccess(), Accessibility::Public)) {
6501+
auto requiredAccess = std::min(nominal->getFormalAccess(),
6502+
Accessibility::Public);
6503+
if (requiredAccess == Accessibility::Private)
6504+
requiredAccess = Accessibility::FilePrivate;
6505+
if (CD->getFormalAccess() < requiredAccess) {
65006506
auto diag = TC.diagnose(CD,
65016507
diag::required_initializer_not_accessible);
6502-
fixItAccessibility(diag, CD, nominal->getFormalAccess());
6508+
fixItAccessibility(diag, CD, requiredAccess);
65036509
}
65046510
}
65056511
}

test/SILGen/Inputs/mangling_private_helper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ open class Base {
55
// Demonstrate the need for a vtable entry for privateMethod().
66
// This isn't strictly necessary.
77
private class Subclass : Base {
8-
override private func privateMethod() {}
8+
override fileprivate func privateMethod() {}
99
}

test/SILOptimizer/Inputs/devirt_access_other_module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ public func getExternalClass() -> ExternalClass {
1414
}
1515

1616
private class PrivateSubclass : ExternalClass {
17-
override private func foo() {}
17+
override fileprivate func foo() {}
1818
}

test/Sema/accessibility.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,38 @@ internal class InternalSubPrivateSet: Base {
198198
}
199199
}
200200

201+
private class PrivateSub: Base {
202+
required private init() {} // expected-error {{'required' initializer must be as accessible as its enclosing type}} {{12-19=fileprivate}}
203+
private override func foo() {} // expected-error {{overriding instance method must be as accessible as its enclosing type}} {{3-10=fileprivate}}
204+
private override var bar: Int { // expected-error {{overriding var must be as accessible as its enclosing type}} {{3-10=fileprivate}}
205+
get { return 0 }
206+
set {}
207+
}
208+
private override subscript () -> () { return () } // expected-error {{overriding subscript must be as accessible as its enclosing type}} {{3-10=fileprivate}}
209+
}
210+
211+
private class PrivateSubGood: Base {
212+
required fileprivate init() {}
213+
fileprivate override func foo() {}
214+
fileprivate override var bar: Int {
215+
get { return 0 }
216+
set {}
217+
}
218+
fileprivate override subscript () -> () { return () }
219+
}
220+
221+
private class PrivateSubPrivateSet: Base {
222+
required fileprivate init() {}
223+
fileprivate override func foo() {}
224+
private(set) override var bar: Int { // expected-error {{setter of overriding var must be as accessible as its enclosing type}}
225+
get { return 0 }
226+
set {}
227+
}
228+
private(set) override subscript () -> () { // okay; read-only in base class
229+
get { return () }
230+
set {}
231+
}
232+
}
201233

202234
public typealias PublicTA1 = PublicStruct
203235
public typealias PublicTA2 = InternalStruct // expected-error {{type alias cannot be declared public because its underlying type uses an internal type}}

0 commit comments

Comments
 (0)