Skip to content

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

Merged

Conversation

beccadax
Copy link
Contributor

@beccadax beccadax commented Sep 9, 2020

This PR contains two changes; the first fixes a bug discovered while writing the tests for the second.

  1. Previously, diagnostics emitted on a non-public imported declaration (via e.g. testable or private import) would show as being at an invalid source location. Now they are emitted in a version of the generated interface which includes declarations of their access level.
  2. @_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.

@beccadax
Copy link
Contributor Author

beccadax commented Sep 9, 2020

(#33716 will conflict with this as soon as it lands, but the changes to resolve that are trivial.)

@beccadax beccadax requested a review from slavapestov September 9, 2020 01:45
@beccadax beccadax force-pushed the imported-by-the-east-aldenard-trading-company branch from 9c2a26c to 437e487 Compare September 11, 2020 02:33
@beccadax
Copy link
Contributor Author

With #33864

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 9c2a26ce583ae048a9fc4e2e80173bf475f10c52

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 9c2a26ce583ae048a9fc4e2e80173bf475f10c52

@beccadax
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 437e4870ec76892e53962eba14eea55634c11786

@beccadax beccadax force-pushed the imported-by-the-east-aldenard-trading-company branch from 437e487 to 2950f2d Compare September 11, 2020 18:44
@beccadax
Copy link
Contributor Author

Force-push to fix some case-sensitivity and path-separator issues in one of the tests.

@beccadax
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 437e4870ec76892e53962eba14eea55634c11786

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 437e4870ec76892e53962eba14eea55634c11786

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.
@beccadax beccadax force-pushed the imported-by-the-east-aldenard-trading-company branch from 2950f2d to 806125d Compare September 23, 2020 21:04
@beccadax
Copy link
Contributor Author

Rebased onto main instead of master; no other changes.

@swift-ci please smoke test

@beccadax beccadax changed the base branch from master to main September 23, 2020 21:05
@beccadax
Copy link
Contributor Author

@swift-ci please smoke test

@beccadax
Copy link
Contributor Author

Seems to have missed Windows. Trying again:

@swift-ci please smoke test

@beccadax beccadax merged commit 4aabd27 into swiftlang:main Sep 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants