From 8789242474b61b0a08f4a5b7c94acaeb3525ce23 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 12 May 2018 01:36:20 -0700 Subject: [PATCH 1/2] Sema: Fix bug with private access scopes in Swift 3 mode In Swift 3 mode, the canonical private DeclContext should not look through extensions. The only way I can reproduce this is with a missing warning and we don't really care about missing warnings in Swift 3 mode. However, the next patch in this PR regresses more things so let's fix it properly. --- lib/AST/DeclContext.cpp | 3 +++ test/Compatibility/accessibility_private.swift | 2 ++ test/Sema/accessibility_private.swift | 2 ++ 3 files changed, 7 insertions(+) diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp index 3ee8f65ec0743..f4861fc895077 100644 --- a/lib/AST/DeclContext.cpp +++ b/lib/AST/DeclContext.cpp @@ -821,6 +821,9 @@ IterableDeclContext::castDeclToIterableDeclContext(const Decl *D) { /// declaration or extension, the supplied context is returned. static const DeclContext * getPrivateDeclContext(const DeclContext *DC, const SourceFile *useSF) { + if (DC->getASTContext().isSwiftVersion3()) + return DC; + auto NTD = DC->getAsNominalTypeOrNominalTypeExtensionContext(); if (!NTD) return DC; diff --git a/test/Compatibility/accessibility_private.swift b/test/Compatibility/accessibility_private.swift index d234ea32d08e7..1d26677c98eea 100644 --- a/test/Compatibility/accessibility_private.swift +++ b/test/Compatibility/accessibility_private.swift @@ -171,8 +171,10 @@ extension Container { extension Container { private struct VeryPrivateStruct { // expected-note * {{type declared here}} private typealias VeryPrivateType = Int // expected-note * {{type declared here}} + private struct VeryPrivateInnerStruct {} var privateVar: VeryPrivateType { fatalError() } // expected-warning {{property should be declared private because its type uses a private type}} var privateVar2 = VeryPrivateType() // expected-warning {{property should be declared private because its type 'Container.VeryPrivateStruct.VeryPrivateType' (aka 'Int') uses a private type}} + var privateVar3 = VeryPrivateInnerStruct() // expected-warning {{property should be declared private because its type 'Container.VeryPrivateStruct.VeryPrivateInnerStruct' uses a private type}} typealias PrivateAlias = VeryPrivateType // expected-warning {{type alias should be declared private because its underlying type uses a private type}} subscript(_: VeryPrivateType) -> Void { return () } // expected-warning {{subscript should be declared private because its index uses a private type}} func privateMethod(_: VeryPrivateType) -> Void {} // expected-warning {{method should be declared private because its parameter uses a private type}} {{none}} diff --git a/test/Sema/accessibility_private.swift b/test/Sema/accessibility_private.swift index d5110be66ce87..16d47986a6c2d 100644 --- a/test/Sema/accessibility_private.swift +++ b/test/Sema/accessibility_private.swift @@ -171,8 +171,10 @@ extension Container { extension Container { private struct VeryPrivateStruct { // expected-note * {{type declared here}} private typealias VeryPrivateType = Int // expected-note * {{type declared here}} + private struct VeryPrivateInnerStruct {} var privateVar: VeryPrivateType { fatalError() } // expected-error {{property must be declared private because its type uses a private type}} var privateVar2 = VeryPrivateType() // expected-error {{property must be declared private because its type 'Container.VeryPrivateStruct.VeryPrivateType' (aka 'Int') uses a private type}} + var privateVar3 = VeryPrivateInnerStruct() // expected-error {{property must be declared private because its type 'Container.VeryPrivateStruct.VeryPrivateInnerStruct' uses a private type}} typealias PrivateAlias = VeryPrivateType // expected-error {{type alias must be declared private because its underlying type uses a private type}} subscript(_: VeryPrivateType) -> Void { return () } // expected-error {{subscript must be declared private because its index uses a private type}} func privateMethod(_: VeryPrivateType) -> Void {} // expected-error {{method must be declared private because its parameter uses a private type}} {{none}} From c2153ff299e2eabe341f912e483d48df1a4bc73a Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 12 May 2018 00:55:02 -0700 Subject: [PATCH 2/2] Sema: Fix access control regression with generic type aliases If a property had an inferred type that is a generic type alias, we weren't checking the access level of the generic arguments. This used to work in 4.1 because we didn't have a sugared representation for generic type aliases, so we were checking the substituted underlying type here. But now that NameAliasType can store generic arguments, make sure we visit them here. Fixes . --- lib/Sema/TypeCheckDecl.cpp | 3 +-- test/Sema/accessibility_typealias.swift | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index f42f22a3c1cfc..8f338b33a46fb 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -1408,8 +1408,7 @@ class TypeAccessScopeChecker : private TypeWalker, AccessScopeChecker { return Action::Stop; if (!CanonicalizeParentTypes) { - return isa(T.getPointer()) ? Action::SkipChildren - : Action::Continue; + return Action::Continue; } Type nominalParentTy; diff --git a/test/Sema/accessibility_typealias.swift b/test/Sema/accessibility_typealias.swift index e9373b892a7a5..6e7cac2ccaabb 100644 --- a/test/Sema/accessibility_typealias.swift +++ b/test/Sema/accessibility_typealias.swift @@ -90,3 +90,13 @@ public var failNested2: (_ x: (main.ActuallyPrivate) -> Void) -> Void = { _ in } public func failTest(x: ActuallyPrivate) {} // expected-error {{cannot be declared public}} public func failTest2(x: main.ActuallyPrivate) {} // expected-error {{cannot be declared public}} +// Property has an inferred type, public alias with +// private generic parameter bound. +public struct PublicGeneric {} + +public typealias GenericAlias = PublicGeneric + +fileprivate func makeAValue() -> GenericAlias { } + +public var cannotBePublic = makeAValue() +// expected-error@-1 {{variable cannot be declared public because its type 'GenericAlias' (aka 'PublicGeneric') uses a private type}}