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

Reply via email to