Undiagnosed private structs/classes with public members?

Internal/private structs/classes with public members are not diagnosed:

// foo.swift
private struct Struct {
  public var x: Int
}

private class Class {
  public var x: Int = 0
}

They're also synthesized with an internal memberwise initializer:

$ swiftc -print-ast foo.swift

private struct Struct {
  public var x: Int
  internal init(x: Int)
}

private class Class {
  @_hasInitialValue public var x: Int
  @objc deinit
  internal init()
}

Is this intentional? Is there value in supporting nominal type declarations with members of a higher access level?

I feel this is super old and by design to make the transition to a higher access level more easier. I hope other folks can confirm this as well.

1 Like

Yes, this is intentional and was heavily discussed during the access-control proposals.

The purpose is to allow a developer to prepare for making a type more visible, by marking all the members with the visibility that they would eventually like them to have, and then when they are ready to make the type visible, that can be done with a single change to the type’s access level.

Got it, thanks! The rationale makes sense.

1 Like

Interestingly, I found that it's significant for memberwise initializers of private nominal types to have internal (not private) access.

func foo() {
  struct Private {}
  // Call the internal memberwise initializer: okay.
  _ = Private()
}
func foo() {
  struct Private {
    private init() {}
  }
  // Call the private memberwise initializer: not okay.
  _ = Private()
}
// private.swift:6:7: error: 'Private' initializer is inaccessible due to 'private' protection level
//   _ = Private()
//       ^
// private.swift:3:13: note: 'init()' declared here
//     private init() {}
//             ^

For context, I discovered this in [AutoDiff] Change `TangentVector` memberwise initializer access level. by dan-zheng · Pull Request #28908 · apple/swift · GitHub, the motivation for this question: memberwise initializer access level for TangentVector member structs synthesized during Differentiable protocol derived conformances.