Skip to content

Commit ca06ee3

Browse files
committed
Update proposal to state that @inline(always) should imply @inlinable on
public'ish declarations
1 parent 8149f46 commit ca06ee3

File tree

1 file changed

+51
-6
lines changed

1 file changed

+51
-6
lines changed

proposals/NNNN-inline-always.md

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Proposal: [SE-NNNN](NNNN-inline-always.md)
44
* Authors: [Arnold Schwaighofer](https://github.com/aschwaighofer)
55
* Implementation: [swiftlang/swift#84178](https://github.com/swiftlang/swift/pull/84178)
6+
* Pitch thread: https://forums.swift.org/t/pitch-inline-always-attribute/82040
67

78
## Introduction
89

@@ -149,18 +150,55 @@ be possible?
149150

150151
### Interaction with `@inlinable`
151152

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.
157167

158168
```swift
169+
@inline(always)
170+
@inlinable // or @_alwaysEmitIntoClient
171+
public func caller() { ... }
172+
159173
@inline(always) // error: a public function marked @inline(always) must be marked @inlinable
160174
public func callee() {
161175
}
162176
```
163177

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+
164202
### Interaction with `@usableFromInline`
165203

166204
A `public` `@inlinable` function can reference a function with `internal` access
@@ -297,7 +335,9 @@ changes to inlining heuristic).
297335

298336
## ABI compatibility
299337

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.
301341

302342
## Implications on adoption
303343

@@ -342,6 +382,11 @@ This would deliver less predictable optimization behavior in cases where authors
342382
overlooked requirements for inlining to happen such as not marking a public
343383
function as `@inlinable`.
344384

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.
345390

346391
## Acknowledgments
347392

0 commit comments

Comments
 (0)