|
3 | 3 | * Proposal: [SE-NNNN](NNNN-inline-always.md) |
4 | 4 | * Authors: [Arnold Schwaighofer](https://github.com/aschwaighofer) |
5 | 5 | * Implementation: [swiftlang/swift#84178](https://github.com/swiftlang/swift/pull/84178) |
| 6 | +* Pitch thread: https://forums.swift.org/t/pitch-inline-always-attribute/82040 |
6 | 7 |
|
7 | 8 | ## Introduction |
8 | 9 |
|
@@ -149,18 +150,55 @@ be possible? |
149 | 150 |
|
150 | 151 | ### Interaction with `@inlinable` |
151 | 152 |
|
152 | | -Function bodies of functions referenceable outside of the defining module are |
153 | | -only available to the outside module if the definition is marked `@inlinable`. |
154 | | - |
155 | | -Therefore, a function marked with `@inline(always)` must be marked `@inlinable` |
156 | | -if it has `open`, `public`, or `package` level access. |
| 153 | +`@inlinable` and `@_alwaysEmitIntoClient` make the function body available to |
| 154 | +clients (callers in other modules) in library evolution mode. `@inlinable` makes |
| 155 | +the body of the function available to the client and causes an ABI entry point |
| 156 | +in the vending module to vended. `@_alwaysEmitIntoClient` makes the body of the |
| 157 | +function available for clients but does not cause emission of an ABI entry |
| 158 | +point. Functions with `open`, `public`, or `package` level access cause emission |
| 159 | +of an ABI entry point for clients to call but in the absence of aforementioned |
| 160 | +attributes do not make the body available to the client. |
| 161 | + |
| 162 | +`@inline(always)` intention is to be able to guarantee that inlining will happen |
| 163 | +for any caller inside or outside the defining module therefore it makes sense to |
| 164 | +require the use some form of "inline-ability" attribute with them. This |
| 165 | +attribute could be required to be explicitly stated. And for it to be an error |
| 166 | +when the attribute is omitted. |
157 | 167 |
|
158 | 168 | ```swift |
| 169 | +@inline(always) |
| 170 | +@inlinable // or @_alwaysEmitIntoClient |
| 171 | +public func caller() { ... } |
| 172 | + |
159 | 173 | @inline(always) // error: a public function marked @inline(always) must be marked @inlinable |
160 | 174 | public func callee() { |
161 | 175 | } |
162 | 176 | ``` |
163 | 177 |
|
| 178 | +Alternatively, the attribute could be implicitly implied by the usage of |
| 179 | +`@inline(always)`. In this proposal, we take the position that it should be |
| 180 | +implied to avoid the redundancy of spelling this out. The intention of |
| 181 | +`@inline(always)` is for it to inline in all contexts. Instead of an error in the |
| 182 | +absence of the attribute we should imply "inline-ability". The question is what |
| 183 | +should we default to? |
| 184 | + |
| 185 | +`@_alwaysEmitIntoClient`'s semantics seems preferable for new functions. We |
| 186 | +intend for the function to be always inlined, why should there be an ABI entry |
| 187 | +point? |
| 188 | + |
| 189 | +`@inlinable` semantics allows for annotating existing functions with |
| 190 | +`@inline(always)` without breaking ABI compatibility. `@inlinable` keeps an |
| 191 | +entry point in the vending module for older code that assumed the existence of |
| 192 | +an entry point. |
| 193 | + |
| 194 | +This proposals takes the position to give `@inline(always)` the semantics of |
| 195 | +`@inlineable` and provide an alternative spelling for the case when we desire |
| 196 | +`@_alwaysEmitIntoClient` semantics: `@inline(only)`. |
| 197 | + |
| 198 | +For access levels equal and lower than `internal` `@inlinable` should not be |
| 199 | +implied. |
| 200 | + |
| 201 | + |
164 | 202 | ### Interaction with `@usableFromInline` |
165 | 203 |
|
166 | 204 | A `public` `@inlinable` function can reference a function with `internal` access |
@@ -297,7 +335,9 @@ changes to inlining heuristic). |
297 | 335 |
|
298 | 336 | ## ABI compatibility |
299 | 337 |
|
300 | | -The addition of the attribute has no effect on ABI compatibility. |
| 338 | +The addition of the attribute has no effect on ABI compatibility. We chose to |
| 339 | +imply `@inlinable` for `public` (et al.) declarations which will continue to |
| 340 | +emit an entry point for existing binary clients. |
301 | 341 |
|
302 | 342 | ## Implications on adoption |
303 | 343 |
|
@@ -342,6 +382,11 @@ This would deliver less predictable optimization behavior in cases where authors |
342 | 382 | overlooked requirements for inlining to happen such as not marking a public |
343 | 383 | function as `@inlinable`. |
344 | 384 |
|
| 385 | +With respect to `@inlinable` an initial draft of the proposal suggested to |
| 386 | +require spelling the `@inlinable` attribute on `public` declarations or an error |
| 387 | +would be displayed. The argument was that this would ensure that authors would |
| 388 | +be aware of the additional semantics implied by the attribute: the body is |
| 389 | +exposed. |
345 | 390 |
|
346 | 391 | ## Acknowledgments |
347 | 392 |
|
|
0 commit comments