Skip to content
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

[SR-13196] Implicit access level for private type disagrees with TSPL #55636

Open
swift-ci opened this issue Jul 10, 2020 · 7 comments
Open

[SR-13196] Implicit access level for private type disagrees with TSPL #55636

swift-ci opened this issue Jul 10, 2020 · 7 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. documentation

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-13196
Radar rdar://problem/70215175
Original Reporter jumhyn (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s
Labels Bug, Documentation
Assignee None
Priority Medium

md5: 68f121b5cd3344a28e179217c9db1081

Issue Description:

The Swift Programming Language, it its access control section, makes the following claim:

The access control level of a type also affects the default access level of that type’s members(its properties, methods, initializers, and subscripts). If you define a type’s access level as private or file private, the default access level of its members will also be private or file private.

The associated example reads (in part):

fileprivate class SomeFilePrivateClass { // explicitly file-private class
    func someFilePrivateMethod() {}      // implicitly file-private class member
    private func somePrivateMethod() {}  // explicitly private class member
}

private class SomePrivateClass { // explicitly private class
    func somePrivateMethod() {}  // implicitly private class member
}

However, the "implicitly private" part doesn't seem to pan out in actuality. E.g., `A.x` in the following example appears to have `fileprivate` access (at least):

private struct A {
  var x = 0
  private var y = 0
}

fileprivate struct B {
  var x = 0
}

print(A().x) // Ok! (I.e., x is not actually private)
print(A().y) // Error
print(B().x)
@swift-ci
Copy link
Collaborator Author

Comment by Connor Hanley (JIRA)

Would be nice to have a built-in function called accessControl(of: ), similar to type(of: ), to better understand what's going on with these types of examples.

@xwu
Copy link
Collaborator

xwu commented Jul 11, 2020

This is an error in TSPL: what it claims is not what was approved during the Swift Evolution process and subsequently implemented. The members are bounded by, and have the same effective visibility as, that of the containing type; they explicitly do not have the same access level. Otherwise, a nested private type could never have members that have the same visibility as itself.

@swift-ci
Copy link
Collaborator Author

Comment by Frederick Kellison-Linn (JIRA)

Right, I should have been clearer—this is a "bug" in TSPL.

@swift-ci
Copy link
Collaborator Author

Comment by Connor Hanley (JIRA)

@xwu thanks for pointing this out. This issue came from a Swift.org post where I was trying to understand the language better.

Would it be fair to say that Swift and its compiler generally try to direct the programmer to write things out explicitly, rather than rely on implicit behavior? It seems like confusion would inevitably arise, were the behavior cited in TSPL actually implemented.

Just to make sure I'm understanding your example correctly, a private nested type is a perfectly natural thing, but a developer wouldn't expect the parent type to not have access to members of the nested type, right? If I'm writing a nested type, I would expect the parent type to have full access to what's within it, unless I explicitly set the nested type's members to private.

Do you happen to have a link to the discussion on the Swift Evolution that led to this conclusion? I would love to read it.

@swift-ci
Copy link
Collaborator Author

Comment by Connor Hanley (JIRA)

Also, how much of TSPL is out of date here? Do any of the other access control levels on types result in implicit levels for the type's members?

I remember that a public type will implicitly make its members internal, which makes sense, but does a file-private type imply that its members file-private?

@xwu
Copy link
Collaborator

xwu commented Jul 15, 2020

The implicit access level is always 'internal', but no member can be more visible than the type it's declared in.

@hborla
Copy link
Member

hborla commented Oct 12, 2020

@swift-ci create

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. documentation
Projects
None yet
Development

No branches or pull requests

3 participants