Skip to content

[AST] Allow access-scope based access check inside inaccessible members #23341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2824,6 +2824,13 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD,
auto access = getAccessLevel();
auto *sourceDC = VD->getDeclContext();

// Preserve "fast path" behavior for everything inside
// protocol extensions and operators, otherwise allow access
// check declarations inside inaccessible members via slower
// access scope based check, which is helpful for diagnostics.
if (!(sourceDC->getSelfProtocolDecl() || VD->isOperator()))
return checkAccessUsingAccessScopes(useDC, VD, access);

if (!forConformance) {
if (auto *proto = sourceDC->getSelfProtocolDecl()) {
// FIXME: Swift 4.1 allowed accessing protocol extension methods that were
Expand Down Expand Up @@ -2878,21 +2885,8 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD,

bool ValueDecl::isAccessibleFrom(const DeclContext *useDC,
bool forConformance) const {
bool result = checkAccess(useDC, this, forConformance,
[&]() { return getFormalAccess(); });

// For everything outside of protocols and operators, we should get the same
// result using either implementation of checkAccess, because useDC must
// already have access to this declaration's DeclContext.
// FIXME: Arguably, we're doing the wrong thing for operators here too,
// because we're finding internal operators within private types. Fortunately
// we have a requirement that a member operator take the enclosing type as an
// argument, so it won't ever match.
assert(getDeclContext()->getSelfProtocolDecl() || isOperator() ||
result ==
checkAccessUsingAccessScopes(useDC, this, getFormalAccess()));

return result;
return checkAccess(useDC, this, forConformance,
[&]() { return getFormalAccess(); });
}

bool AbstractStorageDecl::isSetterAccessibleFrom(const DeclContext *DC,
Expand Down