Skip to content

Commit 58e1cd5

Browse files
authored
SE-0409: Document the behavior of @usableFromInline on imports (#2181)
* [SE-0409] Add @usableFromInline behavior description * [SE-0409] Rename upcoming feature flag
1 parent 128c549 commit 58e1cd5

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

proposals/0409-access-level-on-imports.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Review Manager: [Frederick Kellison-Linn](https://github.com/Jumhyn)
66
* Status: **Accepted with modifications**
77
* Implementation: On main and release/5.9 gated behind the frontend flag `-enable-experimental-feature AccessLevelOnImport`
8-
* Upcoming Feature Flag: `InternalImports` (Enables Swift 6 behavior with imports defaulting to internal. Soon on main only.)
8+
* Upcoming Feature Flag: `InternalImportsByDefault` (Enables Swift 6 behavior with imports defaulting to internal. Soon on main only.)
99
* Review: ([pitch](https://forums.swift.org/t/pitch-access-level-on-import-statements/66657)) ([review](https://forums.swift.org/t/se-0409-access-level-modifiers-on-import-declarations/67290)) ([acceptance](https://forums.swift.org/t/accepted-with-modifications-se-0409-access-level-modifiers-on-import-declarations/67666))
1010

1111
## Introduction
@@ -47,6 +47,7 @@ public func publicFunc() -> DatabaseAdapter.Entry {...} // error: function canno
4747

4848
Additionally, this proposal uses the access level declared on each import declaration in all source files composing a module to determine when clients of a library need to load the library's dependencies or when they can be skipped.
4949
To balance source compatibility and best practices, the proposed default import has an implicit access level of public in Swift 5 and of internal in Swift 6 mode.
50+
The attribute `@usableFromInline` on an import allows references from inlinable code.
5051

5152
## Detailed design
5253

@@ -95,6 +96,15 @@ private import OtherDependencyPrivateToThisFile
9596

9697
The `open` access-level modifier is rejected on import declarations.
9798

99+
The `@usableFromInline` attribute can be applied to an import declaration to allow referencing a dependency from inlinable code
100+
while limiting which declarations signatures can reference it.
101+
The attribute `@usableFromInline` can be used only on `package` and `internal` imports.
102+
It marks the dependency as visible to clients.
103+
```swift
104+
@usableFromInline package import UsableFromInlinePackageDependency
105+
@usableFromInline internal import UsableFromInlineInternalDependency
106+
```
107+
98108
### Type-checking references to imported modules
99109

100110
Current type-checking enforces that declaration respect their respective access levels.
@@ -112,6 +122,11 @@ We apply the same logic for `package`, `fileprivate` and `private` import declar
112122
In the case of a `public` import, there is no restriction on how the imported declarations can be referenced
113123
beyond the existing restrictions on imported `package` declarations which cannot be referenced from public declaration signatures.
114124

125+
The attribute `@usableFromInline` on an import takes effect for inlinable code:
126+
`@inlinable` and `@backDeployed` function bodies, default initializers of arguments, and properties of `@frozen` structs.
127+
The `@usableFromInline` imported dependency can be referenced from inliable code
128+
but doesn't affect type-checking of declaration signatures where only the access level is taken into account.
129+
115130
Here is an example of the approximate diagnostics produced from type-checking in a typical case with a `fileprivate` import.
116131
```swift
117132
fileprivate import DatabaseAdapter
@@ -164,7 +179,7 @@ the transitive client may need to load it at compile time or not.
164179
There are four factors requiring a transitive dependency to be loaded,
165180
if none of these apply the dependency can be hidden.
166181

167-
1. Public dependencies must always be loaded by transitive clients.
182+
1. Public or `@usableFromInline` dependencies must always be loaded by transitive clients.
168183

169184
2. All dependencies of a non-resilient module must be loaded by transitive clients.
170185

@@ -206,7 +221,7 @@ The Swift 6 change will likely break source compatibility for libraries.
206221
A migration tool could automatically insert the `public` modifier where required.
207222
Where the tool is unavailable, a simple script can insert a `public` modifier in front of all imports to preserve the Swift 5 behavior.
208223

209-
The upcoming feature flag `InternalImports` will enable the Swift 6 behavior even when using Swift 5.
224+
The upcoming feature flag `InternalImportsByDefault` will enable the Swift 6 behavior even when using Swift 5.
210225

211226
### Relation with other attributes on imports
212227

0 commit comments

Comments
 (0)