New Access Modifier: package

The package modifier does behave a lot like a special case of the @_spi attribute, so I think it's reasonable to wonder about the relationship between the features. One way to approximate the functionality of this modifier today would be to write the package decls as @_spi(Package) public func foo() { ... } and then in all of the modules in your package prepend @_spi(Package) to every import <Foo>. However, @_spi is really meant to be a tool for curating the external interface of a module for consumption by separate levels of external audiences. In the live at head environments I described earlier, @_spi decls have the same source stability requirements as standard public decls; it's just a bit easier to track down and coordinate with the users of @_spi.

To illustrate why I think package and @_spi serve different purposes I'll again make an analogy with Obj-C/C framework headers:

Swift modifier Obj-C/C header visibility Intended audience
public Public all modules
@_spi(...) public Private authorized external modules
package Project modules in the same project

I think that each of these distinct levels of visibility is important to have as a library owner and therefore I wouldn't want to see @_spi and package combined into a single feature. Could you establish a convention where @_spi(Package) declarations are understood to be only for use in the same package? Yes, but unless the tooling also understands the convention many of the potential benefits of the proposed feature are lost. If you want to be really sure no external parties are using your package interfaces, then the compiler should prevent use of @_spi(Package) decls outside the package. And something like "whole package optimization" is only possible if the compiler and other tools know which declarations are used outside of the package and which are not. Since the main benefits require that these declarations be treated differently than normal @_spi declarations, I think it's better to just have a distinct spelling that makes the difference clear.

2 Likes