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 <[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