> On Jun 15, 2016, at 2:04 PM, Robert Widmann <[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]>
>>> 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