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

Top level private is understood as fileprivate #112

Open
mateo8a opened this issue Jan 5, 2023 · 4 comments
Open

Top level private is understood as fileprivate #112

mateo8a opened this issue Jan 5, 2023 · 4 comments
Labels
Content issue A problem in with the book's prose, code, or figures Good first issue Work that's well-suited for new contributors

Comments

@mateo8a
Copy link

mateo8a commented Jan 5, 2023

Description
A class extension that is declared as private automatically turns all methods and types declared in the extension as private. This gets rid of the need to explicitly declare each method and type declared in the extension as private. However, if a type (say, an enum) declared in the extension is explicitly declared as private (which would be unnecessary but seems to be legal), and if one of the methods in the extension takes this enum as a parameter, then the compiler requires that the method be explicitly declared as private as well.

Steps to reproduce

class Foo {}

private extension Foo {  // The extension is declared as private, so everything in it will be private as well
    private enum Bar {  // This is unnecessarily declared as private, but it seems like a legal move
        case FirstCase
    }

    // The following method takes as a parameter a type that is explicitly declared as private
    func testFunction(case: Bar) {}  // The compiler complains that this method should be declared as private, when it is already private in virtue of being inside an extension that is declared as private
}

The compiler stops complaining if the enum Bar isn't explicitly declared as private anymore. However, whether the enum Bar is explicitly declared as private or not, it will be private by virtue of being inside a private extension.

Is this a bug? To me it seems so, but if others have different opinions I'd like to hear them as well.

Environment

  • Swift compiler version info
    swift-driver version: 1.62.15 Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)
    Target: x86_64-apple-macosx12.0
  • Xcode version info
    Xcode 14.2
    Build version 14C18
  • Deployment target:
    macOS 12.0
@AnthonyLatsis
Copy link

This is expected as far as I am concerned: at the top level, private is always synonymous to fileprivate. We should hand it over to the swift-book folks.

cc @amartini51


Whether we still have room for the now source-breaking (albeit reasonable) behavioural exception you expected is worth discussing on the Swift forums, unless it already was.

@AnthonyLatsis
Copy link

@amartini51 ping

@amartini51
Copy link
Member

I'm not entirely clear what the documentation issue is here. It seems like it might be related to top-level private being understood by the compiler as fileprivate — so the inferred access level of testFunction(case:) is actually fileprivate, even though the extension is marked private. Is that correct and expected behavior by the compiler? I don't see that behavior described in SE-0025 or SE-0169.

@AnthonyLatsis
Copy link

Is that correct and expected behavior by the compiler?

Yes, top-level private is an alias for fileprivate; they are semantically equivalent. I believe this is worth clarifying here. So the members of a private extension are fileprivate by default, not private. I think we should document this even if it happens to be an oversight (cc @DougGregor), because it has been the status quo since at least Swift 3, and would take a source-breaking evolution proposal to fix.

The book also states that the members of a private class, structure, or enumeration will have an effective access level of private, when the actual effective access level is fileprivate.

@amartini51 amartini51 transferred this issue from swiftlang/swift Mar 8, 2023
@amartini51 amartini51 added the Content issue A problem in with the book's prose, code, or figures label Mar 8, 2023
@amartini51 amartini51 changed the title Method in private class extension that takes a private type as a parameter is (mistakenly?) required to be declared as private Top level private is understood as fileprivate Mar 8, 2023
@amartini51 amartini51 added the Good first issue Work that's well-suited for new contributors label Mar 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content issue A problem in with the book's prose, code, or figures Good first issue Work that's well-suited for new contributors
Projects
None yet
Development

No branches or pull requests

3 participants