We have diagnostics specifically to prohibit this case. You cannot raise the access level of members.
private struct Foo { internal var x : String = "" } warning: declaring an internal var for a private struct. Hence, the highest allowable level of access for x is private and it becomes invisible. I would not like the compiler to synthesize this in my code, and if it did I would like the proposal to say it will raise access levels of members as you would like it to. ~Robert Widmann 2016/06/15 12:14、Matthew Johnson <matt...@anandabits.com> のメッセージ: > >> On Jun 15, 2016, at 2:04 PM, Robert Widmann <devteam.cod...@gmail.com> wrote: >> >> >> >> 2016/06/15 11:47、Matthew Johnson <matt...@anandabits.com> のメッセージ: >> >>> >>>> On Jun 15, 2016, at 1:37 PM, Robert Widmann <devteam.cod...@gmail.com> >>>> wrote: >>>> >>>> The scope of the *declaration* is not the issue. The scope of its >>>> *members* is. >>> >>> Let’s consider an example: >>> >>> private struct Foo { >>> var bar: Int >>> } >>> >>> // elsewhere in the same file: >>> var foo = Foo(bar: 42) >>> foo.bar = 44 >>> >>> `Foo` is declared private. Private for this declaration is at the file >>> scope. The `bar` member has no access modifier so it has the same >>> visibility as the struct itself, which is file scope. This will also be >>> true of the implicitly synthesized memberwise initializer. >> >> No, it is also private. It does not inherit its parent scope because, >> following the letter of the proposal, that symbol will only be visible >> within the current declaration. We cannot arbitrarily break access control >> rules because it is convenient in one special case. >> >>> >>> This means that it is possible to initialize `foo` with a newly constructed >>> instance of `Foo` and to modify the `bar` member anywhere else in the same >>> file. >> >> bar is not visible here. If it were you could break access control rules. >> >>> >>> If `bar` was also declared `private` this would not be possible as its >>> visibility would be restricted to the surrounding scope of the initial >>> declaration of `Foo`. This means `Foo` would need to provide an explicit >>> initializer or factory method with `fileprivate` visibility in order to be >>> usable. >> >> bar is private. Declarations within Foo cannot decide to raise that access >> level to make themselves more visible. If this should be the case, the >> proposal must be amended as much. >> >>> >>> Members with no explicit access modifier should have the same *visibility* >>> as their containing type (with a maximum implicit visibility of internal), >>> not the same *modifier* as their containing type. The only case where >>> there is a distinction is the new `private` visibility. Maybe that is what >>> is causing the confusion? >> >> That is not what the proposal says. The proposal says it is invisible >> outside the current decl, which is the containing structure here. > > The access modifier is applied to `Foo`, not `bar`. `Foo` is visible in the > scope of the “current declaration” (this is badly worded - it should say > current scope, which is the file). Because `Foo` has a visibility lower than > `internal` the default visibility of its members match the visibility of > `Foo`, which again is the current scope: the file. The detailed design > section of the proposal is sparse, but it correctly uses the phrase "visible > only within that lexical scope” rather than the less precise (in the case of > top-level code) “current declaration”. > > I didn’t write the proposal but I was very heavily involved in the > discussions and IIRC I provided the original suggestion for introducing a > scoped access modifier. > > If my example was the following: > > private struct Foo { > private var bar: Int > } > > Then what you are saying would be correct. However, The example I showed did > not provide an access modifier for `bar`. > > You cannot just apply the same *access modifier* to members of the type that > do not contain an access modifier. You have to apply the same *visibility* > (limited to internal). When a type is marked as `private` in the lexical > scope of the file, its unmodified members will be visible in the same lexical > scope as the type itself (which is the file in the current example). > > -Matthew > >> >>> >>> Does this help? >>> >>> -Matthew >>> >>>> >>>> ~Robert Widmann >>>> >>>> 2016/06/15 11:36、Matthew Johnson <matt...@anandabits.com> のメッセージ: >>>> >>>>> The scope for a top-level declaration is the file itself. This means >>>>> that top-level declarations with `private` and `fileprivate` should have >>>>> the same behavior. They should not be uninstantiable or unusable. >>>>> >>>>> -Matthew >>>>> >>>>>> On Jun 15, 2016, at 1:31 PM, Robert Widmann via swift-evolution >>>>>> <swift-evolution@swift.org> wrote: >>>>>> >>>>>> While implementing SE-0025 (fileprivate), I noticed an interesting bug >>>>>> in the proposal. Under the implementation outlined there, any top-level >>>>>> structure, class, or enum declared private cannot possibly be >>>>>> instantiated and so cannot be used in any way. Because of this, private >>>>>> top-level declarations are more often than not blown away entirely by >>>>>> the compiler for being unused. It seems strange to me to allow a key >>>>>> language feature to act solely as a hint to the optimizer to reduce the >>>>>> size of your binary. Perhaps the restrictions around private needs to >>>>>> be relaxed or the line between fileprivate and private needs to be >>>>>> investigated again by the community before inclusion in the language. >>>>>> >>>>>> Thoughts? >>>>>> >>>>>> ~Robert Widmann >>>>>> _______________________________________________ >>>>>> swift-evolution mailing list >>>>>> swift-evolution@swift.org >>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution