<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Jun 29, 2016, at 7:07 PM, Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">[Resending with fewer recipients]<br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Jun 29, 2016 at 8:55 PM, Jordan Rose <span dir="ltr" class=""><<a href="mailto:jordan_rose@apple.com" target="_blank" class="">jordan_rose@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">Updated in <a href="https://github.com/apple/swift-evolution/pull/396" target="_blank" class="">https://github.com/apple/swift-evolution/pull/396</a>. Thanks again, everyone!</div></div></blockquote><div class=""> </div><span style="font-size:12.8px" class="">As usual, a thoughtful result from the core team. Curious, though, where does the following statement come into play?</span><br class=""><span style="font-size:12.8px" class=""><br class=""></span><div style="word-wrap:break-word" class=""><span class=""><font color="#888888" class=""><div style="color:rgb(34,34,34);font-size:12.8px" class="">"The access level of a conformance concerning a `private` type or protocol is considered to be `fileprivate` rather than `private`."</div></font></span></div></div></div></div></div></blockquote><div><br class=""></div>I think the internal representation may be leaking out. I believe this is the right basic approach for formalizing the language rules here:</div><div><br class=""></div><div>1. A scope S has access to a declaration D if S has access to the scope S_D in which D is declared and:</div><div> - if D is explicitly declared 'private', S is equal to S_D or lexically nested within S_D,</div><div> - if D is explicitly declared 'fileprivate', S appears within the same file as S_D,</div><div> - if D is explicitly declared 'internal', S appears within the same module as S_D, or</div><div> - if D lacks an explicit access specifier, S appears within the same module as S_D or S_D is a public extension (*).</div><div>(*) I believe this special case rule about public extensions is correct for the current model. I'm not sure it's a good idea, though.</div><div><br class=""></div><div>2. A scope S has access to a scope T if:</div><div> - S is equal to T or is lexically nested within it,</div><div> - T is a declaration D and S has access to D, or</div><div> - T is a file scope.</div><div><br class=""></div><div>3. A declaration D shall not use in its signature any declaration D_sig for which there potentially exists a scope S such that S has access to D but not D_sig. The signature of a declaration includes:</div><div> - the explicit type of a function, initializer, variable, or constant declaration; or its inferred type (fully "desugared", e.g. ignoring all type aliases) if an explicit type is not given</div><div> - the underlying type of a typealias or associatedtype declaration</div><div> - the superclass type of a class declaration</div><div><div> - the conformance list of a class, struct, enum, protocol, or extension declaration</div><div> - the generic parameters and constraints of a generic declaration</div><div></div><div> - etc.</div><div><br class=""></div><div>Formally, there's no need to decide the "real" or "effective" access modifier for a declaration. Conveniently (and not coincidentally), these rules do end up being equivalent to computing an effective access level by just merging information down from the lexical container, but that's emergent, not fundamental, so don't put too much energy into whether the emergent access level "makes sense" as a description.</div><div><br class=""></div><div>John.</div><div><br class=""></div></div><div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><span class=""><font color="#888888" class=""><div class="">Jordan</div></font></span><div class=""><div class="h5"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 29, 2016, at 16:51, Jordan Rose <<a href="mailto:jordan_rose@apple.com" target="_blank" class="">jordan_rose@apple.com</a>> wrote:</div><br class=""><div class=""><div style="word-wrap:break-word" class="">I just attended a core team meeting where this whole thing was discussed, and will update our <a href="https://github.com/apple/swift-evolution/pull/383" target="_blank" class="">amendment</a> tonight. But in short:<div class=""><br class=""></div><div class="">- The default access level will be 'internal' everywhere*. The compiler will not warn if the access-as-written is broader than necessary. <i class="">Motivation: it should be possible to design a type's API as if it had more access than it currently does.</i></div><div class=""><br class=""></div><div class="">* except in extensions, see below</div><div class=""><br class=""></div><div class="">- The complicated "rule 2" from the amendment stands, but possibly in a form that isn't specific to 'fileprivate':</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><blockquote type="cite" class="">A non-private method, initializer, subscript, property, or typealias may still have a type that references `private` declarations if (1) the non-private declaration is a member of a private type, and (2) all referenced `private` declarations are defined within an enclosing lexical scope. That is, it is legal for a non-private member within a `private` type to have a type that is formally `private` if it would be legal for a `private` declaration in the parent scope to have that type.</blockquote></div></blockquote><div class=""><br class=""></div><div class="">As Xiaodi pointed out, this could be even broader, to say that an internal member may reference a fileprivate type if the member is itself defined within a fileprivate type, because it's still safe. That would look like this:</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><blockquote type="cite" class="">A member may not have a type that references any declarations that aren't accessible wherever the member is accessible.</blockquote></blockquote><br class=""><div class="">I'm concerned about that being <i class="">too</i> permissive, though. I still want this to be considered an error:</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class="">fileprivate struct Foo {</div><div class=""> fileprivate typealias Bar = Int</div><div class=""> internal func baz() -> Bar { … }</div><div class="">}</div></blockquote><div class=""><br class=""></div>- An access modifier on an extension has been ruled to indicate the desired <i class="">scope,</i> not the desired <i class="">access.</i> Therefore, members within a `private extension` will be `fileprivate`. (We're only really getting away with this because we don't allow extensions anywhere but at the top level, though if we had nested extensions we'd probably consider them scoped anyway.)<div class=""><br class=""></div><div class="">- We are not looking at renaming either 'fileprivate' or 'private' for Swift 3.<br class=""><div class=""><br class=""></div><div class="">- All this has been ruled not to need a formal review.</div><div class=""><br class=""></div><div class="">Thanks everyone for getting us to this point. It's definitely different from what I would have come up with on my own or just collaborating with Robert, so you can all count yourselves as contributors to this one. :-)</div><div class=""><br class=""></div><div class="">Jordan<br class=""><br class=""><div class="">P.S. If you see further issues here I'd still like to hear them; if you're unclear on any points after I've updated the <a href="https://github.com/apple/swift-evolution/pull/383" target="_blank" class="">pull request</a>, I'm happy to go over them again.</div></div></div></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>