diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp index f7d7e06ae5339..1b84fd616528a 100644 --- a/lib/AST/ASTVerifier.cpp +++ b/lib/AST/ASTVerifier.cpp @@ -869,7 +869,8 @@ class Verifier : public ASTWalker { if (D->hasAccess()) { PrettyStackTraceDecl debugStack("verifying access", D); - if (D->getFormalAccessScope().isPublic() && + if (!D->getASTContext().isAccessControlDisabled() && + D->getFormalAccessScope().isPublic() && D->getFormalAccess() < AccessLevel::Public) { Out << "non-public decl has no formal access scope\n"; D->dump(Out); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a2b42bdb1919a..8a308420ba390 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2578,9 +2578,9 @@ bool ValueDecl::shouldHideFromEditor() const { return false; } -/// Return the access level of an internal or public declaration -/// that's been testably imported. -static AccessLevel getTestableOrPrivateImportsAccess(const ValueDecl *decl) { +/// Return maximally open access level which could be associated with the +/// given declaration accounting for @testable importers. +static AccessLevel getMaximallyOpenAccessFor(const ValueDecl *decl) { // Non-final classes are considered open to @testable importers. if (auto cls = dyn_cast(decl)) { if (!cls->isFinal()) @@ -2606,6 +2606,11 @@ static AccessLevel getAdjustedFormalAccess(const ValueDecl *VD, AccessLevel access, const DeclContext *useDC, bool treatUsableFromInlineAsPublic) { + // If access control is disabled in the current context, adjust + // access level of the current declaration to be as open as possible. + if (useDC && VD->getASTContext().isAccessControlDisabled()) + return getMaximallyOpenAccessFor(VD); + if (treatUsableFromInlineAsPublic && access == AccessLevel::Internal && VD->isUsableFromInline()) { @@ -2618,7 +2623,7 @@ static AccessLevel getAdjustedFormalAccess(const ValueDecl *VD, auto *useSF = dyn_cast(useDC->getModuleScopeContext()); if (!useSF) return access; if (useSF->hasTestableOrPrivateImport(access, VD)) - return getTestableOrPrivateImportsAccess(VD); + return getMaximallyOpenAccessFor(VD); } return access; @@ -2646,16 +2651,16 @@ AccessLevel ValueDecl::getEffectiveAccess() const { case AccessLevel::Internal: if (getModuleContext()->isTestingEnabled() || getModuleContext()->arePrivateImportsEnabled()) - effectiveAccess = getTestableOrPrivateImportsAccess(this); + effectiveAccess = getMaximallyOpenAccessFor(this); break; case AccessLevel::FilePrivate: if (getModuleContext()->arePrivateImportsEnabled()) - effectiveAccess = getTestableOrPrivateImportsAccess(this); + effectiveAccess = getMaximallyOpenAccessFor(this); break; case AccessLevel::Private: effectiveAccess = AccessLevel::FilePrivate; if (getModuleContext()->arePrivateImportsEnabled()) - effectiveAccess = getTestableOrPrivateImportsAccess(this); + effectiveAccess = getMaximallyOpenAccessFor(this); break; } @@ -2851,9 +2856,7 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD, case AccessLevel::FilePrivate: if (useDC->getModuleScopeContext() != sourceDC->getModuleScopeContext()) { auto *useSF = dyn_cast(useDC->getModuleScopeContext()); - if (useSF && useSF->hasTestableOrPrivateImport(access, VD)) - return true; - return false; + return useSF && useSF->hasTestableOrPrivateImport(access, VD); } return true; case AccessLevel::Internal: { @@ -2862,10 +2865,7 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD, if (useFile->getParentModule() == sourceModule) return true; auto *useSF = dyn_cast(useFile); - if (!useSF) return false; - if (useSF->hasTestableOrPrivateImport(access, sourceModule)) - return true; - return false; + return useSF && useSF->hasTestableOrPrivateImport(access, sourceModule); } case AccessLevel::Public: case AccessLevel::Open: diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index edd1adf4a99f1..16ad3d249df91 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -1274,9 +1274,6 @@ bool WitnessChecker::checkWitnessAccess(ValueDecl *requirement, ValueDecl *witness, bool *isSetter) { *isSetter = false; - if (TC.Context.isAccessControlDisabled()) - return false; - AccessScope actualScopeToCheck = getRequiredAccessScope(); // Setting the 'forConformance' flag means that we admit witnesses in diff --git a/lib/Sema/TypeCheckProtocol.h b/lib/Sema/TypeCheckProtocol.h index 39d30a8b8572b..47266b2015d42 100644 --- a/lib/Sema/TypeCheckProtocol.h +++ b/lib/Sema/TypeCheckProtocol.h @@ -497,9 +497,6 @@ class WitnessChecker { AccessScope getRequiredAccessScope(); bool isUsableFromInlineRequired() { - if (TC.Context.isAccessControlDisabled()) - return false; - assert(RequiredAccessScopeAndUsableFromInline.hasValue() && "must check access first using getRequiredAccessScope"); return RequiredAccessScopeAndUsableFromInline.getValue().second;