The meaning of private according to the proposal is not scope-dependent, it is decl-dependent. The mental gymnastics we are both going through right now are not in the proposal. I would like them to be.
~Robert Widmann 2016/06/15 12:26、Matthew Johnson <[email protected]> のメッセージ: > >> On Jun 15, 2016, at 2:19 PM, Robert Widmann <[email protected]> wrote: >> >> 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. > > That diagnostic is a good thing. I am not suggesting that you to disregard > it. > > What you are missing is that the meaning of `private` is scope-dependent. > The following example is perfectly valid: > > private struct Foo { > fileprivate var x : String = “” > } > > `fileprivate` inside `Foo` specifies the same visibility as `private` at the > top level, thus we are not “raising" the visibility of the member. If no > modifier is provided for `x` it receives the same visibility as its > containing type (up to `internal`). > > Consider another example: > > struct Foo { > private struct Bar { > var x : String = “” > } > } > > In this example we *cannot* mark `x` as `fileprivate` because that *would* > raise the visibility of `x` beyond that of `Bar`. `Bar` is only visible > inside `Foo`, not at file scope. This means that `x` also has visibility > throughout the lexical scope of `Foo`, but not outside of it. > > -Matthew > > >> >> ~Robert Widmann >> >> 2016/06/15 12:14、Matthew Johnson <[email protected]> のメッセージ: >> >>> >>>> On Jun 15, 2016, at 2:04 PM, Robert Widmann <[email protected]> >>>> wrote: >>>> >>>> >>>> >>>> 2016/06/15 11:47、Matthew Johnson <[email protected]> のメッセージ: >>>> >>>>> >>>>>> On Jun 15, 2016, at 1:37 PM, Robert Widmann <[email protected]> >>>>>> 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 <[email protected]> のメッセージ: >>>>>> >>>>>>> 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 >>>>>>>> <[email protected]> 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 >>>>>>>> [email protected] >>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
