Skip to content

Fix Swift 6.2 library evolution build failures caused by @inlinable initializer restrictions - #122

Open
JHeisecke wants to merge 4 commits into
apple:mainfrom
JHeisecke:main
Open

Fix Swift 6.2 library evolution build failures caused by @inlinable initializer restrictions#122
JHeisecke wants to merge 4 commits into
apple:mainfrom
JHeisecke:main

Conversation

@JHeisecke

Copy link
Copy Markdown

Motivation:

Swift 6.2 enforces stricter definite initialization rules for @inlinable initializers under library evolution mode (BUILD_LIBRARY_FOR_DISTRIBUTION=YES). Two distinct violations occur across swift-asn1:

  1. Designated inits that assign stored properties directly, the compiler rejects these as @inlinable because the definite initialization proof cannot be verified across module boundaries without self = .init(...) syntax.
  2. Throwing designated inits that reach a success path without assigning self (for example: ASN1Null.init(derEncoded:withIdentifier:)) returns normally after validation but never explicitly sets self, which Swift 6.2 now flags as an error.

This prevents swift-asn1 from compiling as a distributed binary framework (XCFramework or any library evolution target) under Swift 6.2.

Modifications:

  • @inlinable → @usableFromInline (or removed) on designated initializers across ASN1.swift, ASN1BitString.swift, ASN1Identifier.swift, ASN1Integer.swift, ASN1OctetString.swift, ASN1Strings.swift, GeneralizedTime.swift, ObjectIdentifier.swift, UTCTime.swift, and DER.swift; these inits assign stored
    properties directly and cannot satisfy @inlinable definite initialization requirements.

  • ASN1Null.init(derEncoded:withIdentifier:), added self = .init() at end of success path, keeping the init @inlinable.

  • ASN1Any, extracted a @usableFromInline designated init(_serializedBytes:), then converted the two throwing @inlinable public inits to delegate via self.init(_serializedBytes:...) instead of assigning the stored property directly. Removed @inlinable from init(derEncoded:) (non-throwing, directly assigns a computed property).

Result:

swift-asn1 compiles cleanly under Swift 6.2 with library evolution enabled. No behavior change, all public APIs remain callable from inlinable client code via @usableFromInline internal inits.

…olution

Swift 6.2 with SWIFT_ENABLE_LIBRARY_EVOLUTION=YES rejects @inlinable
  designated initializers that directly assign stored properties
  (self.foo = ...). The compiler cannot guarantee binary compatibility
  if stored property layout changes after clients have inlined the body.

  Fix: remove @inlinable from all affected designated initializers
across
  11 files. Inits called from @inlinable functions are annotated
  @usableFromInline instead of being left internal (which would cause a
  separate "cannot be referenced from @inlinable function" error).

  Affected types:
  - ASN1.ParserNode, ASN1.ParseResult (→ @usableFromInline)
  - ASN1Node, ASN1NodeCollection, ASN1NodeCollection.Iterator (→
@usableFromInline)
  - ASN1.LazySetOfSequence.Iterator (→ @usableFromInline)
  - ASN1Identifier (shortIdentifier init → @usableFromInline;
tagWithNumber → public only)
  - IntegerBytesCollection.Index (→ @usableFromInline)
  - DER.Serializer, ASN1OctetString, ASN1BitString, ObjectIdentifier,
    ASN1Any, UTCTime, GeneralizedTime, all ASN1String variants
    (→ public, no inlining attribute)

@Lukasa Lukasa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this patch!

SwiftASN1 does not support BUILD_LIBRARY_FOR_DISTRIBUTION. Specifically, we do not provide a stable ABI, and at this time have no intention of doing so. To that end we do not recommend using SwiftASN1 in this way.

We would be willing to accept a patch that fixes the build in that environment, but we would not be willing to do so at the cost of performance without that flag. This change removes some @inlinable flags, which will harm the performance of the stack. If you can provide a version of this patch that meets your use-case and doesn't regress your stack, I'll happily accept it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants