-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix non-public imported declaration diagnostic bug + Favor private imports during name lookup #33864
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
Fix non-public imported declaration diagnostic bug + Favor private imports during name lookup #33864
Conversation
(#33716 will conflict with this as soon as it lands, but the changes to resolve that are trivial.) |
9c2a26c
to
437e487
Compare
Build failed |
Build failed |
@swift-ci please test |
Build failed |
437e487
to
2950f2d
Compare
Force-push to fix some case-sensitivity and path-separator issues in one of the tests. |
@swift-ci please test |
Build failed |
Build failed |
When DiagnosticEngine needs to diagnose something about an imported declaration, it uses ASTPrinter to print the declaration’s interface into a source buffer and then diagnoses it there. However, this code only printed public declarations, so it failed to account for features like `@testable import` which allow less-than-public declarations to be imported. Errors involving these declarations would therefore be diagnosed at <unknown>:0. This commit changes DiagnosticEngine to determine the access level of the declaration it needs to print and, if it is below `Public`, instead prints a separate interface whose minimum access level is low enough to include the desired declaration.
Private imports are intended to make the file performing the import more or less source-compatible with the file being imported from, so that code from the original file can be modified by relatively simple syntactic transformations. However, their name shadowing behavior was very different from the original file. In the original file, other declarations in the same module would have shadowed declarations imported from any other module; in a file using a @_private import, they would all be considered imports, and thus all would be preferred equally. This could cause ambiguity in a file using a @_private import that was not present in the original file. This commit changes that behavior by favoring @_private imports over other imports, so that if a name is visible through both a private and a non-private import, the one visible through the private import will shadow the other. This shadowing takes a higher priority than a scoped import, but a lower priority than the check for whether one of the modules is only visible through the other. Fixes rdar://68312053.
2950f2d
to
806125d
Compare
Rebased onto @swift-ci please smoke test |
@swift-ci please smoke test |
Seems to have missed Windows. Trying again: @swift-ci please smoke test |
This PR contains two changes; the first fixes a bug discovered while writing the tests for the second.
@_private(sourceFile:) import
should, to the extent practicable, preserve source compatibility with the original file. However, name lookup ended up working very differently. In the original file, declarations in the same module would shadow declarations from any other module; in the file importing it, the declarations from the original file's module would be considered just as imported as any other module's, so there would be new name lookup ambiguities. To address this, we add a shadowing rule which favors modules with a private import in the DeclContext's file over other modules visible from that file.The first change is a pure bug fix. The second is a behavior change, but in a compiler-internal feature.