Private (not Protected)

Why swift language still not allow private extension to be deployed on a separate file?

I would like to ear some opinions about why that feature should not be available to developers. I know this is not a technical question, but in my heart I think most of you has felt same frustration of not having such a feature still today.

Example (not exhaustive of any possible cases)

MyView.swift:

struct MyView: View {
  var body: some View {
    _main_
  }
}

MyView+Extension.swift

private extension MyView {
  ///
  @ViewBuilder
  var _main_: some View {
    Text("Hellworld!")
  }
}

Can you specify an example you want to work which does not work today?

i’ve updated topic with an example.

I am not able to reproduce this with Swift 6.2 (from Xcode 26.0):

% cat Sources/test/test.swift
struct Foo {
}

% cat Sources/test/extension.swift 
private extension Foo {
    var bar: String { "hello" }
}

% xcrun swift build
Building for debugging...
[5/5] Compiling test extension.swift
Build complete! (0.31s)

% xcrun swift --version      
swift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)
Target: arm64-apple-macosx26.0

It was pointed out to me that the actual error occurs when you try to access the member declared in the extension:

struct Foo {
    func f () {
        self.bar // 'bar' is inaccessible due to 'fileprivate' protection level
    }

This is because on top-level declarations, private as an alias for fileprivate. I’ve seen it explained that the access modifier before extension is a shorthand for repeating that access modifier on all declarations within the extension, but this behavior is not consistent with that rule. But changing this behavior would risk reopening the private/fileprivate can of worms.

I'm not sure what you mean, your explanation is correct. private extension is equivalent to fileprivate extension, which is then applied to all the items in the extension, making it fileprivate var bar.

But I also agree, there should be a typeprivate equivalent. Or, to be consistent with many of my other suggestions private(type). Which should also be enhanced for testing control with something like private(type, test), and extended to other ACLs, like package(type, test).

2 Likes

As Jon later say, this is often called typeprivate, there are a few threads about this, eg:

which links to formal proposal:

And yes I’ve been missing this feature since Swift was created…

2 Likes

The mental model for public extension is that you can cut the public from before extension and paste it before every declaration within the extension:

/*public*/ extension Foo {
  public var bar: String { "hello" }
  public func baz() { print("hello") }
}

That mental model is broken with private extension.

This is exactly the can of worms I was referring to.

1 Like

I don’t know which is the problem behind the scene u exactly refer with this phrase.

The SE-0025 proposal his pre-history in the language evolution, the benefit of a typeprivate or typeinternal or protected swift keyword that apply access control at type level not file level meet the large demanding need of making order into massive chunks of code without loose the ability to hide properties and functions dev want to keep undisclosed.

But if the problem is clear the solution isn’t near, is there a way to put a petition in favor a new Access Level proposal that include type level protection like suggested by Gonvalo_Alvarez

1 Like

@John_McCall I read some of your tech answers and in my opinion you are a ā€œBig Whaleā€ in Swift. I’m interested in your opinion about the chance to have a type level private access control that overtake file scope limitations of current private.

I’d love to see a typeprivate keyword

I'd love to see that typeprivate keyword to be spelled private.

2 Likes

I absolutely agree, it make sense. For me it can be called 30 chars long keyword if that goal can be reached as fast as possible.