`@inlinable` and `@frozen` (SE-0193 and SE-0260)

Although the Elements Swift Evolution page claims that SE-0193 and SE-0260 are not applicable to Elements, I believe this judgement to be in error.

In particular, even though, as evident, the Elements compiler does not intend to utilize the information in these Aspects, it should still allow these Aspects to be provided, perhaps with warnings, to improve interoperability with the (Apple) Swift compiler.

On the specific Aspects, based on my reading:

  • @inlinable:
    I believe that minimal support would only require treating as equivalent to @usableFromInline.

  • @usableFromInline:
    I believe this should be treated as "conditionally @Published", that is it is @Published if it is in a @Published or public, namespace. Or just treat it as @Published directly, though that sacrifices potential code size.

    • Aside: I think that if “published” were proposed as an alternative to “usableFromInline” during SE-0193, it would have had a decent chance at being the name.
  • @frozen:
    I think that, for minimal support, this can just be ignored.

Thanks, logged as bugs://83069

As I understand this, this is pretty drastically different from our @Published aspect (and Oxygene keyword). @usableFromInline allows code that is not publicly callable (ie is private, conceptually) to be accessed from inlined code (which runs outside of the type (or possibly even module), and thus constitutes a public access to the member.

I can see the benefit for this, but I’m unsure what its side effects would be for all platforms.

By contrast, our @Published affects linking, on Cocoa and Island

what exactly does this (compared to the badly named @inine(never) and @inline(__always)? wouldn’t the lack of either of these already imply “inlineable”? I’ll read up more.

Note that (linker smarts aside), right now we only support always inlining or never. IE a method marked with @inline(__always), will always be inlined; any other method will not be (afaik).

That’s part of the library evolution thing, right? I’ll need to read up more on what this does, exactly, irc it’s just metadata and doesn’t;t affect the actual compile, but I could be misremembering.


  • @inlinable:
    This declares that the function will never change in a way that is incompatible with coexisting with versions after @inlinable is added.
    Lacking this attribute doesn’t mean the function can’t be inlined, just that any functions which inline this function must be recompiled if this function changes.

  • @usableFromInline :
    I do not know what @Published is used for, but the docs say
    “it will be used indirectly, and should not be eliminated by the linker”,
    @usableFromInline (and @inlinable) essentially mean:
    It may be used by inlined code, and should not be eliminated, if it has been used in inlined code, either in the current compile or in code not being recompiled.
    It seems to me that the latter guarantees are conserved by the former, but IDK.

  • @frozen:
    It is indeed just metadata.
    Whether or not @frozen affects the compile is wholly dependent on the compiler. It asserts that the affected type’s stored properties (fields) will never change, and that the compiler may optimize based on that, even if the module is otherwise “resilient”.

Apple really has a crack naming team on call the Swift. Could these be named any more misleading/confusing? :wink:

Well, in this case, the naming team is mostly SE volunteers.

However, I do think that these names make sense, from the POV of what effects the programmer is allowing.
e.g. the effect of inlining is that there may be multiple versions of a function in a binary. @inlinable shifts the burden of proof that all of these versions are semantically equivalent, and that, therefore, inlining is a safe optimization, to the programmer.

Well, my “problem:” with them is that they seem to focus on one side effect of the actual meaning.

So @inlineable really means “this method won’t change in the future”. one sideefect of that is that it’d ben safe to inline, sure, but it seems too bury the lede a bit.

No, these are really very distinct things.

@usableFromInline means “this is really a private API. but we make it sorta-public so that inlined code of the same class may use it, even when said code becomes part of an external codebase, dent being inlined.”

@Published means “it might look like no-one uses this member, but include it anyways — it’ll be accessed dynamically thru means you, the linker, cannot understand”.

Sorry, I’m an enthusiast, but not an expert.