Skip to content

Commit 805e06e

Browse files
authored
Flip the switch on 'private' and 'fileprivate'.
Merge pull request #3767 from jrose-apple/private-and-fileprivate
2 parents 8c7e75a + 6dea23a commit 805e06e

File tree

6 files changed

+128
-5
lines changed

6 files changed

+128
-5
lines changed

lib/AST/Decl.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1869,11 +1869,18 @@ const DeclContext *
18691869
ValueDecl::getFormalAccessScope(const DeclContext *useDC) const {
18701870
const DeclContext *result = getDeclContext();
18711871
Accessibility access = getFormalAccess(useDC);
1872+
bool swift3PrivateChecked = false;
18721873

18731874
while (!result->isModuleScopeContext()) {
18741875
if (result->isLocalContext())
18751876
return result;
18761877

1878+
if (access == Accessibility::Private && !swift3PrivateChecked) {
1879+
if (result->getASTContext().LangOpts.EnableSwift3Private)
1880+
return result;
1881+
swift3PrivateChecked = true;
1882+
}
1883+
18771884
if (auto enclosingNominal = dyn_cast<NominalTypeDecl>(result)) {
18781885
access = std::min(access, enclosingNominal->getFormalAccess(useDC));
18791886

@@ -1895,7 +1902,6 @@ ValueDecl::getFormalAccessScope(const DeclContext *useDC) const {
18951902

18961903
switch (access) {
18971904
case Accessibility::Private:
1898-
// TODO: Implement 'private'
18991905
case Accessibility::FilePrivate:
19001906
assert(result->isModuleScopeContext());
19011907
return result;

lib/AST/NameLookup.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,9 +1017,12 @@ static bool checkAccessibility(const DeclContext *useDC,
10171017
if (!useDC)
10181018
return access == Accessibility::Public;
10191019

1020+
assert(sourceDC && "ValueDecl being accessed must have a valid DeclContext");
10201021
switch (access) {
10211022
case Accessibility::Private:
1022-
// TODO: Implement 'private'.
1023+
if (sourceDC->getASTContext().LangOpts.EnableSwift3Private)
1024+
return useDC == sourceDC || useDC->isChildContextOf(sourceDC);
1025+
SWIFT_FALLTHROUGH;
10231026
case Accessibility::FilePrivate:
10241027
return useDC->getModuleScopeContext() == sourceDC->getModuleScopeContext();
10251028
case Accessibility::Internal: {

lib/Sema/TypeCheckDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6168,7 +6168,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
61686168
const DeclContext *desiredAccessScope;
61696169
switch (AA->getAccess()) {
61706170
case Accessibility::Private:
6171-
// TODO: Implement 'private'.
6171+
assert(ED->getDeclContext()->isModuleScopeContext() &&
6172+
"non-top-level extensions make 'private' != 'fileprivate'");
6173+
SWIFT_FALLTHROUGH;
61726174
case Accessibility::FilePrivate:
61736175
desiredAccessScope = ED->getModuleScopeContext();
61746176
break;

stdlib/public/SDK/Foundation/IndexPath.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public struct IndexPath : ReferenceConvertible, Equatable, Hashable, MutableColl
2626
public typealias Index = Array<Int>.Index
2727
public typealias Indices = DefaultRandomAccessIndices<IndexPath>
2828

29-
private var _indexes : Array<Int>
29+
fileprivate var _indexes : Array<Int>
3030

3131
/// Initialize an empty index path.
3232
public init() {

test/Sema/accessibility_private.swift

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// RUN: %target-parse-verify-swift
2+
3+
class Container {
4+
private func foo() {} // expected-note * {{declared here}}
5+
private var bar = 0 // expected-note * {{declared here}}
6+
7+
private struct PrivateInner {} // expected-note * {{declared here}}
8+
9+
func localTest() {
10+
foo()
11+
self.foo()
12+
13+
_ = bar
14+
bar = 5
15+
_ = self.bar
16+
self.bar = 5
17+
18+
privateExtensionMethod() // FIXME expected-error {{use of unresolved identifier 'privateExtensionMethod'}}
19+
self.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}}
20+
21+
_ = PrivateInner()
22+
_ = Container.PrivateInner()
23+
}
24+
25+
struct Inner {
26+
func test(obj: Container) {
27+
obj.foo()
28+
_ = obj.bar
29+
obj.bar = 5
30+
obj.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}}
31+
32+
_ = PrivateInner()
33+
_ = Container.PrivateInner()
34+
}
35+
36+
var inner: PrivateInner? // expected-error {{property must be declared private because its type uses a private type}}
37+
var innerQualified: Container.PrivateInner? // expected-error {{property must be declared private because its type uses a private type}}
38+
}
39+
40+
var inner: PrivateInner? // expected-error {{property must be declared private because its type uses a private type}}
41+
var innerQualified: Container.PrivateInner? // expected-error {{property must be declared private because its type uses a private type}}
42+
}
43+
44+
func test(obj: Container) {
45+
obj.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}}
46+
_ = obj.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}}
47+
obj.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}}
48+
obj.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}}
49+
50+
_ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}}
51+
}
52+
53+
extension Container {
54+
private func privateExtensionMethod() {} // expected-note * {{declared here}}
55+
56+
func extensionTest() {
57+
foo() // FIXME expected-error {{use of unresolved identifier 'foo'}}
58+
self.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}}
59+
60+
_ = bar // FIXME expected-error {{use of unresolved identifier 'bar'}}
61+
bar = 5 // FIXME expected-error {{use of unresolved identifier 'bar'}}
62+
_ = self.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}}
63+
self.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}}
64+
65+
privateExtensionMethod()
66+
self.privateExtensionMethod()
67+
68+
_ = PrivateInner() // FIXME expected-error {{use of unresolved identifier 'PrivateInner'}}
69+
_ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}}
70+
}
71+
72+
// FIXME: Why do these errors happen twice?
73+
var extensionInner: PrivateInner? { return nil } // FIXME expected-error 2 {{use of undeclared type 'PrivateInner'}}
74+
var extensionInnerQualified: Container.PrivateInner? { return nil } // FIXME expected-error 2 {{'PrivateInner' is not a member type of 'Container'}}
75+
}
76+
77+
extension Container.Inner {
78+
func extensionTest(obj: Container) {
79+
obj.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}}
80+
_ = obj.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}}
81+
obj.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}}
82+
obj.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}}
83+
84+
_ = PrivateInner() // FIXME expected-error {{use of unresolved identifier 'PrivateInner'}}
85+
_ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}}
86+
}
87+
88+
// FIXME: Why do these errors happen twice?
89+
var inner: PrivateInner? { return nil } // FIXME expected-error 2 {{use of undeclared type 'PrivateInner'}}
90+
var innerQualified: Container.PrivateInner? { return nil } // FIXME expected-error 2 {{'PrivateInner' is not a member type of 'Container'}}
91+
}
92+
93+
class Sub : Container {
94+
func subTest() {
95+
foo() // FIXME expected-error {{use of unresolved identifier 'foo'}}
96+
self.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}}
97+
98+
_ = bar // FIXME expected-error {{use of unresolved identifier 'bar'}}
99+
bar = 5 // FIXME expected-error {{use of unresolved identifier 'bar'}}
100+
_ = self.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}}
101+
self.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}}
102+
103+
privateExtensionMethod() // FIXME expected-error {{use of unresolved identifier 'privateExtensionMethod'}}
104+
self.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}}
105+
106+
_ = PrivateInner() // FIXME expected-error {{use of unresolved identifier 'PrivateInner'}}
107+
_ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}}
108+
}
109+
110+
var subInner: PrivateInner? // FIXME expected-error {{use of undeclared type 'PrivateInner'}}
111+
var subInnerQualified: Container.PrivateInner? // FIXME expected-error {{'PrivateInner' is not a member type of 'Container'}}
112+
}

validation-test/compiler_crashers_2_fixed/0016-rdar21437203.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ struct Curds {
55
}
66

77
private class Butter {
8-
private func churn<T>(block: () throws -> T) throws -> T {
8+
fileprivate func churn<T>(block: () throws -> T) throws -> T {
99
return try block()
1010
}
1111
}

0 commit comments

Comments
 (0)