# SE-0386: \`package\` access modifier

**URL:** <https://forums.swift.org/t/se-0386-package-access-modifier/62808>\
**Category:** Proposal Reviews\
**Tags:** access-control, packagemanager\
**Created:** [January 26, 2023, 11:09pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808 "2023-01-26T23:09:06Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![tshortli](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tshortli/32/15850_2.png) [@tshortli](https://forums.swift.org/u/tshortli)\
**Post date:** [January 29, 2023, 5:56pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/41 "2023-01-29T17:56:28Z")

</div>

> [@AlexisQapa](#):
>
> Il not sure if the following was considered or not, could we stop modules from "leaking" their dependencies and then just reexport manually what you want to export ?

This idea has been discussed [before](https://forums.swift.org/t/pre-pitch-import-access-control-a-modest-proposal/50087) and I agree it's important. It's actually already implemented as an underscored attribute (`@_implementationOnly import`).

> [@AlexisQapa](#):
>
> This would mean that we could keep access control as it is. Imported public symbols would become internals symbols in the parent module. We would get the package scope for free by always re-exporting very sub module unless in the top module.

I don't think that package private modules can address the same needs as the `package` modifier. Being required to group every interface that ought to be private to the package into separate modules is an awkward restriction on the organization of code and it doesn't work for a common case like this:

```swift
// PublicType is declared in a "public" module in your package
public struct PublicType {
  // This field is an implementation detail needed by other modules in the
  // package but is not meant for use outside the package
  package var x: Int 

  // ...
}

```

An `extension` in a package-private module is not a substitute for this since the `extension` cannot declare storage or implement a wrapper for `x` without `x` being `public`.

---

<div class="post-metadata">

**Author:** ![tshortli](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tshortli/32/15850_2.png) [@tshortli](https://forums.swift.org/u/tshortli)\
**Post date:** [January 29, 2023, 7:39pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/42 "2023-01-29T19:39:09Z")

</div>

Since a lot of the discussion is revolving around whether we should consider solving these problems with `@_spi` instead, I'd like to elaborate on one of my [posts](https://forums.swift.org/t/new-access-modifier-package/61459/63) from the pitch thread:

> [@New Access Modifier: package](https://forums.swift.org/t/new-access-modifier-package/61459/63):
>
> 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 |

It is an important goal for me and many others in this discussion that the second and third rows be addressed distinctly. For package implementers there's an important advantage to being confident that you are free to evolve `package` visibility declarations as needed, without having to worry about outside dependencies you have little control over. When refactoring code in a package, encountering the `package` access modifier should give you a warm fuzzy feeling: "phew, this declaration is probably not going to be a straight jacket that limits my ability to make necessary changes." Encountering declarations with `@_spi`, on the other hand, yields a different kind of reaction: "Darn, I'm going to need to do research to figure out how complicated it is to change this and who I need to coordinate with in order to do so."

Folks have rightfully pointed out that we could design an official version of `@_spi` that is a tool for both jobs either by teaching the tooling which SPI groups are package private or by adding extra arguments to the attribute. I do understand the sentiment that these concepts are close enough to each other that maybe we could get a two-for-one by designing a shared solution, but I haven't seen an argument that convinces me that combining them is a superior design for the specific need addressed by `package`. One thing in particular that bothers me about reusing the `@_spi` approach is that I think the ceremony of declaring named groupings does not pull its weight for package private declarations because most of the time you're just going to declare one name for them. I think that if you address all the problems with reusing `@_spi` (tooling needs to be aware what's package private, group names are superfluous, naming `@_spi` at the import declaration is questionable ceremony for this purpose) then you wind up back where we started with a different spelling of the same thing that is being proposed.

> [@ensan-hcl](#):
>
> It can be because I'm not a native English speaker, but I don't think `package` naming makes sense.

I'm coming around to this perspective. Although it's a mouthful I do wonder if we should name this access level something like `packageprivate` since a `package` declaration does look like it is declaring an object which is a package.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [January 29, 2023, 9:04pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/43 "2023-01-29T21:04:15Z")

</div>

> [@New Access Modifier: package](https://forums.swift.org/t/new-access-modifier-package/61459/63):
>
> 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 don’t think that “modules in the same project” is a useful intended audience, because i often have example targets (or, for packages that require 5.7+, snippet targets) that i _don’t want_ to be included in that audience.

i wouldn’t want code in an example target or an integration test target that compiles in the CI pipeline, but fails to compile when used in an actual project.

---

<div class="post-metadata">

**Author:** ![frozendevil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/frozendevil/32/872_2.png) [@frozendevil](https://forums.swift.org/u/frozendevil)\
**Post date:** [January 30, 2023, 12:47am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/44 "2023-01-30T00:47:01Z")

</div>

> [@tshortli](#):
>
> "phew, this declaration is probably not going to be a straight jacket that limits my ability to make necessary changes."

My argument is that for a large/and or old enough project (or any number of other cases, as @taylorswift points out) this will not be true—to the point I would say that `package` is the thing that's too permissive, in contrast to a formalized `@spi` mechanism.

* * *

An addendum to my earlier thoughts: Part of my concern is that in the proposal as stated `import MyModule` and `import MyModule` mean two different things based on criteria that aren't visible at the call site. I don't see how this is meaningfully different from async without the `await` keyword, or Swift's error model without `try`—in fact it's worse, because with those at least I can "jump to definition" to immediately understand the context. With `package` I have to read and internalize the on-disk structure of the project (which will be changing over time) in order to understand the consequences of _any_ `import` in the project (or read the entirety of the documentation? This is maybe beyond the scope of this particular thread, but "interaction with DocC" seems like it should be added as a bullet to proposals in the future).

I would move from a strong -1 to an "indifferent" if the proposal were amended to require some explicit indication of intent at the use site, but at that point it seems pretty clear this is "just" a special form of `@spi`.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [January 30, 2023, 1:06am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/45 "2023-01-30T01:06:16Z")

</div>

> [@tshortli](#):
>
> One thing in particular that bothers me about reusing the `@_spi` approach is that I think the ceremony of declaring named groupings does not pull its weight for package private declarations because most of the time you're just going to declare one name for them. I think that if you address all the problems with reusing `@_spi` (tooling needs to be aware what's package private, group names are superfluous, naming `@_spi` at the import declaration is questionable ceremony for this purpose) then you wind up back where we started with a different spelling of the same thing that is being proposed.

This seems pretty easily solved simply by including some premade SPIs, as I mentioned up thread. Not only would it provide uniformity among all packages for certain levels of visibility, but the SPI approach is far more flexible, as it already allows custom naming. Continually customizing Swift's ACLs for this sort of visibility doesn't seem to scale. A full SPI solution not only provides more flexibility immediately, but more room to grow premade identifiers if additional scopes become common. To me, providing a premade `Package` SPI, as well as things like `Testing` or custom identifiers with custom visibility, all seem like distinct advantages for the SPI approach that ACLs really can't match.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [January 30, 2023, 2:04am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/46 "2023-01-30T02:04:07Z")

</div>

> [@taylorswift](#):
>
> i often have example targets (or, for packages that require 5.7+, snippet targets) that i _don’t want_ to be included in that audience.
> 
> i wouldn’t want code in an example target or an integration test target that compiles in the CI pipeline, but fails to compile when used in an actual project.

This is an interesting point I hadn't considered that's worth spelling out in the proposal, I think:

Currently, code in a separate `Example` module within the same package is _guaranteed_ to work in the same way when someone else copies the examples into their standalone, separate package. The `@testable` attribute allows the _importing code_ to poke a hole into this invariant, not from within the library itself.

With the proposed `package` attribute, this invariant will no longer hold: @taylorswift would have to move his examples into a separate package to be assured of this.

Mind you, when it comes to the issue of "work[s] the same way" that I mention above, it's more than just that some code might no longer _compile_ when moved outside the package because it calls some package-internal API. There is also the much more difficult-to-reason-about scenario where the code continues to compile but ends up calling a _different overload_.

Consider also that library authors who avoid exposing public extensions of standard library or Foundation types will (correctly) feel that it's fine to write package-internal extensions, and think of the head scratching that would ensue when an end user copies some example code from that library into their own code only to find a difference in the behavior of a _standard library type_ due to overload resolution discrepancies.

---

<div class="post-metadata">

**Author:** ![tgoyne](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@tgoyne](https://forums.swift.org/u/tgoyne)\
**Post date:** [January 30, 2023, 2:17am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/47 "2023-01-30T02:17:19Z")

</div>

-1

I hadn't previously looked into what exactly `@_spi` does, but based on the description of it here in the alternatives considered section it's exactly the tool I've wanted for providing a private API to other modules, while `package` is a significantly less flexible tool that requires contorting your packaging to do things like _not_ have access to privates from another module. Having to explicitly request the SPI by name is basically the same thing as having to use `@testable import`, and I'm a fan of that as well as it's good to have some indication when reading some code that an import isn't doing the normal thing. It sounds like Apple internally uses `@_spi` for only very specific and limited scenarios, but that doesn't mean that the feature itself is only suitable for that.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [January 30, 2023, 3:11am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/48 "2023-01-30T03:11:00Z")

</div>

Another idea just had is the SPIs could be expanded with a list of allowed target names at declaration time. This would allow even more granular control than `package`.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [January 30, 2023, 4:24am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/49 "2023-01-30T04:24:48Z")

</div>

i think we need a place to put the `@spi` definition, and this is something `Package.swift` should handle. because we already have to edit `Package.swift` when you rename a module.

---

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [January 30, 2023, 6:01am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/50 "2023-01-30T06:01:46Z")

</div>

> [@taylorswift](#):
>
> i wouldn’t want code in an example target or an integration test target that compiles in the CI pipeline, but fails to compile when used in an actual project.

For a long time I thought I wanted a `package` ACL. But then I read this little gem of a sentence.

I have a lot of code in many packages whose sole purpose is to exercise the API _as though from the outside_ to prove as a compilation test that no `public` modifiers are missing and any future refactors do not lose them. (This is a lesson learned from depending on other packages such as SwiftPM itself who often refactor and release an update that cannot be used without a patch to re‐expose the shuffled pieces.)

If I had not read @taylorswift’s comment, I suspect I would have jumped on using the `package` ACL for a few months, eventually run into trouble and then realized that I had undermined all my related tests. At that point I would likely abandon the `package` ACL again in favour of an equivalent `@spi` (if it weren’t underscored) for the sake of the notation at the import site. With the help of foresight I think I will avoid that churn.

To convince me to use it now, the proposal would have to add some way of carving out part of the package from participating in the ACL so as to make that portion compile as though it were a client.

---

<div class="post-metadata">

**Author:** ![hassila](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hassila/32/22647_2.png) [@hassila](https://forums.swift.org/u/hassila)\
**Post date:** [January 30, 2023, 7:18am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/51 "2023-01-30T07:18:31Z")

</div>

> [@SDGGiesbrecht](#):
>
> To convince me to use it now, the proposal would have to add some way of carving out part of the package from participating in the ACL so as to make that portion compile as though it were a client.

Perhaps swift pm could allow one to explicitly override the package-name for a given target - then it would fundamentally solve this.

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [January 30, 2023, 2:33pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/52 "2023-01-30T14:33:45Z")

</div>

> [@John\_McCall](#):
>
> - What is your evaluation of the proposal?

Strong +1. Too many times I had to use `@_spi` as a workaround, and I consider it inadequate in most use cases it had to be applied. I also find that suggestions to continue using `@_spi` miss the point that it's an underscored attribute that can go away in the next release of the compiler with no warning. Its behavior is clearly different from the proposed `package` modifier. Suggesting that `@_spi` should be formalized and introduced separately is totally fair, but the lack of non-underscored `@spi` in the language shouldn't block the introduction of `package`.

> [@John\_McCall](#):
>
> - Is the problem being addressed significant enough to warrant a change to Swift?

Yes, it resolves a long-standing issue, which led to leaking certain symbols in a package that previously had to be made `public` or use underscored attributes.

> [@John\_McCall](#):
>
> - Does this proposal fit well with the feel and direction of Swift?

Yes, it's consistent with most of the existing access modifiers (except `fileprivate`) in naming and fits quite nicely. I don't find `packageprivate` alternative to be appealing, as it is too verbose. I'd rather see `fileprivate` being renamed to something shorter than have one more inconsistent access modifier introduced.

If `private` were `declarationprivate` and `public` were `modulepublic`, then certainly `packageprivate` would make sense. Otherwise, when compared to simple `package` it adds verbosity with little to no benefit.

> [@John\_McCall](#):
>
> - If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I have only used languages with much more simpler sets of access modifiers, and I'm glad that what Swift has is more advanced and flexible. With addition of `package` it becomes even more polished.

> [@John\_McCall](#):
>
> - How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I followed development of `package` access modifier from the pitch phase and had a look at implementation PRs on the SwiftPM repository.

---

<div class="post-metadata">

**Author:** ![ExFalsoQuodlibet](https://avatars.discourse-cdn.com/v4/letter/e/bbce88/32.png) [@ExFalsoQuodlibet](https://forums.swift.org/u/ExFalsoQuodlibet)\
**Post date:** [January 30, 2023, 2:41pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/53 "2023-01-30T14:41:15Z")

</div>

> [@John\_McCall](#):
>
> So it is useful to explore what sub-modules would actually be like in order to understand their implications for the language and their suitability for solving this language problem.

In our case we define feature modules, that is, targets that contain the code for a feature of the app, but in several case we would like to split that target into separate "sub-targets", one for each screen of the feature for example, for namespacing and visibility purposes within the target itself. Currently, we use caseless `enum`-based namespaces for that, but it's not great.

If this proposal is approved, we could hypothetically move the grouping one level higher and define "feature packages" that contain modules that pertain to specific aspects of the feature, but adding lots of packages for that would probably me hard to manage and unproductive.

---

<div class="post-metadata">

**Author:** ![dreampiggy](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dreampiggy/32/9245_2.png) [@dreampiggy](https://forums.swift.org/u/dreampiggy)\
**Post date:** [January 30, 2023, 3:09pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/54 "2023-01-30T15:09:18Z")

</div>

+0

From the example in proposal, most of them can use `swiftmoule.private` to solve. Different module in the same package can search the private swiftmodule and import the types which don't want to expose. And it works just like C-language which use private headers to seperate the caller from outside(means caller we don't know) or "Package"(means, our frameworks)

More about that the "Subclassing and Overrides" part. The matrix list there, makes me a little hard to remember and realize for the massive combination. Is "Subclassable" and "Accessible/Callable" the same semantic and we have to treat it as top level control ? Because previous is Nx2, now is Nx3 (N means accessible level). Only one `package` keyword can not hold these extra control information.

Seems from your site, "Subclassble" should be a additive standalone attribute on "public/internal" or "package". Any real world use case to make some APIs "Accessible outside package but subclassable inside package" and can not use the workaround we have...

* * *

I mean, if we really want this precise control mentioned above, things will become much more complicated...

A little joke, if we can re-design Swift's language at the beginning (I know it's impossible...Just a joke 🙂

Seperate the "access level" and "subclass level".

```swift
// 1. Defaults non-subclassing for class. Remove "final" and introduce "subclassing" keyword (or "nonfinal" keyword, whatever
// 2. Remove "open" keyword, which act the same as "public subclassing(public)" or just "public subclassing"
// 3. "package/public/internal/fileprivate subclassing" without brackets means "package/public/internal/fileprivate subclassing(package/public/internal/fileprivate)". The private does not support subclassing combination. The first attribute must be higher than or equal to the attribute inside subclassing brackets.

public subclassing class Foobar {} // Same as below
public subclassing(public) class Foobar {} // access in anyone, subclassable anyone
public subclassing(package) class Foobar {} // access in anyone, only subclassable inside package
public subclassing(internal) class Foobar {} // access in anyone, only subclassable inside module
public subclassing(fileprivate) class Foobar {} // access in anyone, only subclassable inside same file

package subclassing class Foobar {} // Same as below
package subclassing(package) class Foobar {} // access in package, subclassable inside package
package subclassing(internal) class Foobar {} // access in package, only subclassable inside module
package subclassing(fileprivate) class Foobar {} // access in package, only subclassable inside same file

internal subclassing class Foobar {} // Same as below
internal subclassing(internal) class Foobar {} // access in module, subclassable inside module
internal subclassing(fileprivate) class Foobar {} // access in module, only subclassable inside same file

fileprivate subclassing class Foobar {} // Same as below
fileprivate subclassing(fileprivate) class Foobar {} // access in same file, subclassable inside same file

```

---

<div class="post-metadata">

**Author:** ![dreampiggy](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dreampiggy/32/9245_2.png) [@dreampiggy](https://forums.swift.org/u/dreampiggy)\
**Post date:** [January 30, 2023, 4:46pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/55 "2023-01-30T16:46:36Z")

</div>

About the proposal's Future Discussion which can not use private swiftmodule:

> reducing the need for [explicit module aliases](https://github.com/apple/swift-evolution/blob/main/proposals/0339-module-aliasing-for-disambiguation.md) when utility modules of different packages share a name (such as `Utility`) or when multiple versions of a package need to be built into the same program.

Is this private swiftmodule naming do cause conflict ? For example, `Vapor.Utility` is not even visible to your `MyLib` package or "MyLib.Utility" module. The issue only happends if you explicit access their private module in swift compiler options.

I don't think it's good usage of this feature to access others' private swiftmodule. For this case, `@spi` is better way to workaround.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [January 30, 2023, 6:06pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/56 "2023-01-30T18:06:29Z")

</div>

I'm having trouble understanding your argument across these two posts, because you're talking about this `Private` module in packages as if it were an existing feature of the language and SwiftPM. Is the right way to understand you that you're describing how you'd like that feature to work and that you think it would be a better alternative to what's in the proposal?

---

<div class="post-metadata">

**Author:** ![frozendevil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/frozendevil/32/872_2.png) [@frozendevil](https://forums.swift.org/u/frozendevil)\
**Post date:** [January 30, 2023, 10:36pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/57 "2023-01-30T22:36:33Z")

</div>

> [@Max\_Desiatov](#):
>
> I also find that suggestions to continue using `@_spi`

I don't think anyone is suggesting this

---

<div class="post-metadata">

**Author:** ![dreampiggy](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dreampiggy/32/9245_2.png) [@dreampiggy](https://forums.swift.org/u/dreampiggy)\
**Post date:** [January 31, 2023, 9:28am UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/58 "2023-01-31T09:28:18Z")

</div>

My fault. I used to think that `private.swiftinterface` is another feature, after checking the compiler guide I found it's current `@_spi` usage

But anyway, can we put this `public/private` swiftinterface/swiftmodule design more further ? Like a standard to use this to distribute different interfaces to differfent consumer (Package level or Anyone)

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [February 1, 2023, 10:23pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/59 "2023-02-01T22:23:35Z")

</div>

I'd like to both bump this review thread — I'm sure more people have thoughts on this — and specifically ask for feedback about `@usableFromPackageInline`. There was a suggestion earlier to rename this to `@usableFromInline(package)`. If we did accept the `package` modifier in general, what do people think about these two spellings, or is there an alternative that you would prefer?

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [February 1, 2023, 10:37pm UTC](https://forums.swift.org/t/se-0386-package-access-modifier/62808/60 "2023-02-01T22:37:59Z")

</div>

i do not like the existing `@usableFromInline`, because i feel like it should not really be an attribute, it is closer to being an access level, because i often fall into the following pattern of encapsulation:

```swift
public > @usableFromInline > internal, fileprivate, private, etc.

```

so in everyday programming `@usableFromInline` is a weird kind of “`halfpublic`” that exists to make `@inlinable` and `@frozen` errors go away. but that is not really what `@usableFromInline` actually does, because `@usableFromInline` API is actually `public` API, with the restriction that only the swift compiler is able to call that API.

so from a package author standpoint, `@usableFromInline` is effectively `public` and we have to treat those declarations as if they are public, because anyone can call them, we are only guaranteed that no _humans_ will be calling them.

and if you really think about it, all roads here lead back to `@_spi`, because i think the best way of understanding `@usableFromInline` is to imagine it as

```swift
@_spi(compiler) public

```

where `compiler` is an SPI that only the swift compiler can import.

so this hypothetical `@usableFromPackageInline` is really just a product of two SPIs, like

```swift
@_spi(compiler, packagelocal) public

```

where the caller has to be eligible to import both SPIs in order to use the declaration.

so i am -1 on `@usableFromPackageInline`.

[Previous page](https://forums.swift.org/t/se-0386-package-access-modifier/62808.md?page=2)

[Next page](https://forums.swift.org/t/se-0386-package-access-modifier/62808.md?page=4)
