Private utilities from @inlinable methods

Since ABI-stability, is there any way to have private always-inline helper functions to be used from within @inlinable code without adding them to the ABI, as that (correct me if I'm wrong) would mean they could never be removed since that would break binary compatibility?

This is by definition impossible, as using it from an inline function make it referenced directly by the client code, and so make it part of the ABI.

If you want to make ABI stable library, you should definitively read this Swift.org - Library Evolution in Swift. The inline case is details here.

1 Like

At least theoretically, it should be possible in the sense that if you have a non-public function that must be inlined (a guarantee which @inline(__always) atm doesn't provide), then removing or renaming it would be fine since it effectively doesn't exist in any compiled client code.

1 Like

There is an @_alwaysEmitIntoClient attribute, but it's not officially supported. Defining an internal @_alwaysEmitIntoClient function will accomplish what you want:

  • Function can be referenced from @inlinable functions
  • Function is not visible across module boundaries in the source language

The usual caveats with using underscored language features applies (it might not work at all, might change in a future release, etc).

3 Likes

Thank you, that's exactly what I meant.

A related question, what happens to local functions (i.e. functions defined inside a function body)? If the outer function is @inlinable, are they ABI-public, or always inlined, or are they always emitted into the client (inlined or not) if the outer function is inlined?

Actually found the answer in the full library evolution doc:

Any local functions or closures within an inlinable function are treated as @_alwaysEmitIntoClient (see below). A client that inlines the containing function must emit its own copy of the local functions or closures. This is important in case it is necessary to change the inlinable function later.

1 Like