diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 0df71e8715055..f325fec44f60b 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1869,11 +1869,18 @@ const DeclContext * ValueDecl::getFormalAccessScope(const DeclContext *useDC) const { const DeclContext *result = getDeclContext(); Accessibility access = getFormalAccess(useDC); + bool swift3PrivateChecked = false; while (!result->isModuleScopeContext()) { if (result->isLocalContext()) return result; + if (access == Accessibility::Private && !swift3PrivateChecked) { + if (result->getASTContext().LangOpts.EnableSwift3Private) + return result; + swift3PrivateChecked = true; + } + if (auto enclosingNominal = dyn_cast(result)) { access = std::min(access, enclosingNominal->getFormalAccess(useDC)); @@ -1895,7 +1902,6 @@ ValueDecl::getFormalAccessScope(const DeclContext *useDC) const { switch (access) { case Accessibility::Private: - // TODO: Implement 'private' case Accessibility::FilePrivate: assert(result->isModuleScopeContext()); return result; diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index b42bf7bb4ed81..a64b99a618b5c 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -1017,9 +1017,12 @@ static bool checkAccessibility(const DeclContext *useDC, if (!useDC) return access == Accessibility::Public; + assert(sourceDC && "ValueDecl being accessed must have a valid DeclContext"); switch (access) { case Accessibility::Private: - // TODO: Implement 'private'. + if (sourceDC->getASTContext().LangOpts.EnableSwift3Private) + return useDC == sourceDC || useDC->isChildContextOf(sourceDC); + SWIFT_FALLTHROUGH; case Accessibility::FilePrivate: return useDC->getModuleScopeContext() == sourceDC->getModuleScopeContext(); case Accessibility::Internal: { diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 1a65b1370f169..96b6e278603d8 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -6168,7 +6168,9 @@ class DeclChecker : public DeclVisitor { const DeclContext *desiredAccessScope; switch (AA->getAccess()) { case Accessibility::Private: - // TODO: Implement 'private'. + assert(ED->getDeclContext()->isModuleScopeContext() && + "non-top-level extensions make 'private' != 'fileprivate'"); + SWIFT_FALLTHROUGH; case Accessibility::FilePrivate: desiredAccessScope = ED->getModuleScopeContext(); break; diff --git a/stdlib/public/SDK/Foundation/IndexPath.swift b/stdlib/public/SDK/Foundation/IndexPath.swift index 0aa210aa00441..a61ab67cff965 100644 --- a/stdlib/public/SDK/Foundation/IndexPath.swift +++ b/stdlib/public/SDK/Foundation/IndexPath.swift @@ -26,7 +26,7 @@ public struct IndexPath : ReferenceConvertible, Equatable, Hashable, MutableColl public typealias Index = Array.Index public typealias Indices = DefaultRandomAccessIndices - private var _indexes : Array + fileprivate var _indexes : Array /// Initialize an empty index path. public init() { diff --git a/test/Sema/accessibility_private.swift b/test/Sema/accessibility_private.swift new file mode 100644 index 0000000000000..a2ab83cc08345 --- /dev/null +++ b/test/Sema/accessibility_private.swift @@ -0,0 +1,112 @@ +// RUN: %target-parse-verify-swift + +class Container { + private func foo() {} // expected-note * {{declared here}} + private var bar = 0 // expected-note * {{declared here}} + + private struct PrivateInner {} // expected-note * {{declared here}} + + func localTest() { + foo() + self.foo() + + _ = bar + bar = 5 + _ = self.bar + self.bar = 5 + + privateExtensionMethod() // FIXME expected-error {{use of unresolved identifier 'privateExtensionMethod'}} + self.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}} + + _ = PrivateInner() + _ = Container.PrivateInner() + } + + struct Inner { + func test(obj: Container) { + obj.foo() + _ = obj.bar + obj.bar = 5 + obj.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}} + + _ = PrivateInner() + _ = Container.PrivateInner() + } + + var inner: PrivateInner? // expected-error {{property must be declared private because its type uses a private type}} + var innerQualified: Container.PrivateInner? // expected-error {{property must be declared private because its type uses a private type}} + } + + var inner: PrivateInner? // expected-error {{property must be declared private because its type uses a private type}} + var innerQualified: Container.PrivateInner? // expected-error {{property must be declared private because its type uses a private type}} +} + +func test(obj: Container) { + obj.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}} + _ = obj.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}} + obj.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}} + obj.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}} + + _ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}} +} + +extension Container { + private func privateExtensionMethod() {} // expected-note * {{declared here}} + + func extensionTest() { + foo() // FIXME expected-error {{use of unresolved identifier 'foo'}} + self.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}} + + _ = bar // FIXME expected-error {{use of unresolved identifier 'bar'}} + bar = 5 // FIXME expected-error {{use of unresolved identifier 'bar'}} + _ = self.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}} + self.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}} + + privateExtensionMethod() + self.privateExtensionMethod() + + _ = PrivateInner() // FIXME expected-error {{use of unresolved identifier 'PrivateInner'}} + _ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}} + } + + // FIXME: Why do these errors happen twice? + var extensionInner: PrivateInner? { return nil } // FIXME expected-error 2 {{use of undeclared type 'PrivateInner'}} + var extensionInnerQualified: Container.PrivateInner? { return nil } // FIXME expected-error 2 {{'PrivateInner' is not a member type of 'Container'}} +} + +extension Container.Inner { + func extensionTest(obj: Container) { + obj.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}} + _ = obj.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}} + obj.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}} + obj.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}} + + _ = PrivateInner() // FIXME expected-error {{use of unresolved identifier 'PrivateInner'}} + _ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}} + } + + // FIXME: Why do these errors happen twice? + var inner: PrivateInner? { return nil } // FIXME expected-error 2 {{use of undeclared type 'PrivateInner'}} + var innerQualified: Container.PrivateInner? { return nil } // FIXME expected-error 2 {{'PrivateInner' is not a member type of 'Container'}} +} + +class Sub : Container { + func subTest() { + foo() // FIXME expected-error {{use of unresolved identifier 'foo'}} + self.foo() // expected-error {{'foo' is inaccessible due to 'private' protection level}} + + _ = bar // FIXME expected-error {{use of unresolved identifier 'bar'}} + bar = 5 // FIXME expected-error {{use of unresolved identifier 'bar'}} + _ = self.bar // expected-error {{'bar' is inaccessible due to 'private' protection level}} + self.bar = 5 // expected-error {{'bar' is inaccessible due to 'private' protection level}} + + privateExtensionMethod() // FIXME expected-error {{use of unresolved identifier 'privateExtensionMethod'}} + self.privateExtensionMethod() // expected-error {{'privateExtensionMethod' is inaccessible due to 'private' protection level}} + + _ = PrivateInner() // FIXME expected-error {{use of unresolved identifier 'PrivateInner'}} + _ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}} + } + + var subInner: PrivateInner? // FIXME expected-error {{use of undeclared type 'PrivateInner'}} + var subInnerQualified: Container.PrivateInner? // FIXME expected-error {{'PrivateInner' is not a member type of 'Container'}} +} diff --git a/validation-test/compiler_crashers_2_fixed/0016-rdar21437203.swift b/validation-test/compiler_crashers_2_fixed/0016-rdar21437203.swift index f70ccaa63c444..f80d42b6f2f8f 100644 --- a/validation-test/compiler_crashers_2_fixed/0016-rdar21437203.swift +++ b/validation-test/compiler_crashers_2_fixed/0016-rdar21437203.swift @@ -5,7 +5,7 @@ struct Curds { } private class Butter { - private func churn(block: () throws -> T) throws -> T { + fileprivate func churn(block: () throws -> T) throws -> T { return try block() } }