-
Notifications
You must be signed in to change notification settings - Fork 10.5k
SE-0169: Add support for shared private #9098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…d extensions in Swift 4
lib/AST/DeclContext.cpp
Outdated
lastExtension = ED; | ||
|
||
// If there's no last extension, return the supplied context. | ||
return lastExtension ?: DC; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We try not to use GNU extensions like ?:, please just write lastExtension ? DC : nullptr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean lastExtension ? lastExtension : DC
.
I have a cosmetic nitpick -- the name 'shared private' is not great. How about we talk about 'private', 'fileprivate', and 'swift 3 private'. |
At this rate, might as well future-proof and call these things "Swift 4 private", "Swift 2 private", and "Swift 3 private" :P |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this, Brian! (And Xiaodi.)
Hm. I'm not comfortable with this solution as is because it only changes isChildOf
, and not ==
or intersectWith
. Won't that lead to troubles down the line?
lib/AST/DeclContext.cpp
Outdated
// sourceDC does not represent a type. | ||
auto sourceNTD = sourceDC->getAsNominalTypeOrNominalTypeExtensionContext(); | ||
auto useSF = useDC->getParentSourceFile(); | ||
if (useSF != sourceDC->getParentSourceFile() || !sourceNTD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Please don't try to combine these checks because it means wasting effort (either looking up the base nominal, or looking for the useDC's parent file).
|
@KingOfBrian You might want to try enabling this unconditionally, and building the standard library and overlays, just to get a bit of additional testing -- if you hit a crash, add some new tests. |
… equality support
Good thought -- I rebuilt everything with the swift 3 guard commented out and no crashes. How would I just rebuild the stdlib and overlays btw? |
If you build with ninja, you can cd into the Swift build directory and just call $ ninja swift-stdlib I'm not sure the overlays have a target, but you can try to find it by grepping the output of $ ninja -t targets all |
@swift-ci please smoke test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm definitely happier with this. Nice work, Brian! I still have several small comments here but they're all things that could be addressed post-commit.
@@ -48,7 +53,7 @@ class AccessScope { | |||
/// \see DeclContext::isChildContextOf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: This doc comment \see
should probably be dropped or changed to \sa
.
@@ -48,7 +53,7 @@ class AccessScope { | |||
/// \see DeclContext::isChildContextOf | |||
bool isChildOf(AccessScope AS) const { | |||
if (!isPublic() && !AS.isPublic()) | |||
return getDeclContext()->isChildContextOf(AS.getDeclContext()); | |||
return allowsPrivateAccess(getDeclContext(), AS.getDeclContext()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: This case also handles internal
, so maybe just make this allowsAccess
? Or make it a method like isChildSlowPath
, which would help preserve the distinction at the call site between the useDC and the sourceDC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Ah, I see now that NameLookup.cpp tries to access this logic directly. It might just make sense to change that checkAccessibility
over to using access scopes explicitly instead of trying to be clever and do everything with DeclContexts.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update it to allowsAccess
at the very least and will try to update checkAccessibility
. I didn't like how there were multiple methods of doing this, but I was trying not to disturb too much. Let me see how it goes!
_ = PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}} | ||
_ = Container.PrivateInner() // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}} | ||
_ = PrivateInner() | ||
_ = Container.PrivateInner() | ||
} | ||
|
||
// FIXME: Why do these errors happen twice? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the FIXME no longer applies.
@@ -0,0 +1,76 @@ | |||
// RUN: rm -rf %t && mkdir -p %t | |||
// RUN: %utils/split_file.py -o %t %s | |||
// RUN: %target-swift-frontend -swift-version 4 -typecheck %t/declarations.swift %t/other_file_extensions.swift -verify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also run this test in multi-file mode, using -primary-file
before each file in turn? Sometimes that behaves differently from whole-module mode (which is the default when invoking %target-swift-frontend
directly).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm struggling to find a clean way to do this. it looks like there's a @-1
style syntax, that changes which run of FileCheck it matches, but I can't get it to work right or find any documentation on it. Any documentation other than the lit source?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like that @-1
syntax just changes the line, so I'm out of ideas how to make this test valid without 3 copies of this test =/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like VerifyDiagnosticConsumer
defines the expected-[]
behavior. It would be great if that syntax supported the idea of a prefix like FileCheck
, then this would be pretty trivial. Any other ideas on how to update this test @jrose-apple ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using FileCheck instead of / in addition to -verify is probably the best way to go.I wouldn't worry about the notes, just the main errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, thanks!
sourceDC = getPrivateDeclContext(sourceDC, useSF); | ||
while (!useDC->isModuleContext()) { | ||
useDC = getPrivateDeclContext(useDC, useSF); | ||
if (useDC == sourceDC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically an access scope is not a child access scope if it's the same access scope.
@KingOfBrian Please open a pull request with the Changelog updated as well if you haven't already. |
This PR implements SE-0169 and allows the private scope to be shared between types and extensions inside of a file. This follows the approach Jordan spelled out in SR-4616.
The one slight deviation is that I didn't change the way the private
AccessScope
is constructed, but changed theisChildOf
check to also use the private scope check. Doing both didn't seem to make sense and I believeisChildOf
needs to use the private scope check.For testing I added a test
Sema/accessibility_shared_private.swift
with explicit checks for multi-file shared private behavior. I also copied the existingSema/accessibility_private.swift
to the Compatibility directory, and updated the test for Swift 4 behavior. I think the test coverage is pretty good, but any ideas for additional testing would be great.Resolves SR-4616.