What's the impact of `private import` vs. `import`

I was reading a work-in-progress pull request in swift-testing, and noticed that some of the imports are listed as private, for example:

private import Foundation

I think what this means is that the import is available for the local module, but not re-exported with the module.

Is that the correct interpretation, or is there additional subtlety or a different meaning in that usage?

Are other access modifiers also possible (such as fileprivate or the new-ish package?) And is the default assumed isolation version public, implying re-export of the module?

2 Likes

This is SE-0409; here's a link to the relevant section of the proposal.

Essentially, private import (and fileprivate import, they're equivalent) means that the imported symbols can only be used in private/fileprivate declarations in that file. It would be an error to write an internal, package, or public declaration that referenced a symbol imported with private import. Likewise, similar behavior happens for the other access levels.

In pre-SE-0409 Swift, import is equivalent to the new public import, because there are no restrictions on where an imported symbol can be used.

I would avoid the term "re-export", because it has a somewhat loaded meaning; in terms of @_exported import (which SE-0409 does not address), a symbol being re-exported means specifically that it can be used by importing the re-exporting module instead of the module where it is actually defined. public/package/internal/private import don't affect that—they simply control what kind of declarations can reference the symbols being imported.

11 Likes

Thanks @allevato!