> On Jun 15, 2016, at 2:34 PM, Adrian Zubarev via swift-evolution > <[email protected]> wrote: > > Ok I already see side effects in my idea which breaks the entire scoped > access level thing :/ > > class A { > // incrementTwice() is not visible here > } > > extension A { > private func incrementTwice() { > > } > } > In my model incrementTwice would be visible in A which it shouldn’t (I agree > to that). > > That seem like a nasty bug that we missed during review. > >
You are correct that `incrementTwice` is not visible inside `class A`. What seems like a nasty bug missed during review? I don’t follow you there. This proposal was specifically designed to follow Swift’s design of a scope-based access control mechanism rather than a type-based access control mechanism that is common in other languages. > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 15. Juni 2016 um 21:30:20, Robert Widmann via swift-evolution > ([email protected] <mailto:[email protected]>) schrieb: > >> 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] >> <mailto:[email protected]>> のメッセージ: >> >>> >>>> On Jun 15, 2016, at 2:19 PM, Robert Widmann <[email protected] >>>> <mailto:[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] >>>> <mailto:[email protected]>> のメッセージ: >>>> >>>>> >>>>>> On Jun 15, 2016, at 2:04 PM, Robert Widmann <[email protected] >>>>>> <mailto:[email protected]>> wrote: >>>>>> >>>>>> >>>>>> >>>>>> 2016/06/15 11:47、Matthew Johnson <[email protected] >>>>>> <mailto:[email protected]>> のメッセージ: >>>>>> >>>>>>> >>>>>>>> On Jun 15, 2016, at 1:37 PM, Robert Widmann <[email protected] >>>>>>>> <mailto:[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] >>>>>>>> <mailto:[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] <mailto:[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] <mailto:[email protected]> >>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> > > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
