Skip to content

0.12.0

Latest

Choose a tag to compare

@github-actions github-actions released this 12 Jul 15:33

0.12.0

Headline work since 0.11.0:

  1. swift-section diff β€” a new top-level CLI command that produces an ABI-aware, annotated Swift interface diff between two Mach-O binaries.
  2. SwiftLayout β€” a new module that computes Swift struct / class / enum stored-property field offsets statically, without loading the process or calling the runtime metadata accessor. The swift-section dump / interface offline (file) path now emits real field-offset / type-layout / expanded-tree / enum-layout comments.
  3. Reader-specialized rendering β€” FieldLayoutRenderer and the printer pipeline now dispatch on the Mach-O reader type at compile time, so the MachOImage path renders from in-process runtime metadata while the MachOFile path renders from SwiftLayout's static engine, with no runtime branch.
  4. SwiftDump β†’ leaf β€” a substantial refactor extracted SwiftDeclarationRendering so SwiftDump and SwiftInterface share one declaration-rendering layer.

Highlights

swift-section diff β€” annotated ABI diff between two Mach-O binaries

swift-section diff old.binary new.binary [--architecture arm64] [--interface]
  • Builds a full SwiftInterface for both binaries, then runs an ABI diff over the declaration model.
  • Emits a change-list report (per declaration: added / removed / modified, with an ABI-breaking verdict and a backward-compatibility verdict) and, with --interface, a full interface annotated with + / - / markers β€” a renderable artifact you can paste into reviews or save as a .diff.
  • The diff is gated on ABI-breaking changes and validates flag combinations up front.
  • Pluggable DiffFormat: inline (git-diff-style line prefixes), unified (real unified-diff, consumable by git apply / patch), and markdownFenced (```diff block).

SwiftLayout β€” offline field-offset computation engine

A new module that computes the same field-offset / type-layout information the runtime metadata accessor would produce, but directly from the Mach-O file β€” no dlopen, no _swift_getTypeByMangledNameInContext, no live process.

Coverage in this release:

  • Aggregates β€” struct / class / tuple field accumulation via an offline port of the runtime's performBasicLayout.
  • Enums β€” no-payload + single-payload (incl. Optional) layouts via the runtime getEnumTagCounts formulas; multi-payload enums via the __swift5_builtin whole-type descriptor (compiler-embedded layout) with a structural fallback that reuses EnumLayoutCalculator.
  • Existentials β€” any P, compositions, AnyObject, any Error, existential metatypes (incl. imported ObjC protocols, always class-bound).
  • Imported C value types and multi-payload enums β€” both resolved through BuiltinTypeLayoutIndex (per-image __swift5_builtin) keyed by demangled qualified name.
  • Edge function kinds β€” default-actor storage builtin, C-function-pointer / ObjC-block fields.
  • Cross-module references β€” a per-image ImageReference indexes __swift5_types, __swift5_protos, and __objc_classlist; ImageUniverse exposes single-image and dependency-closure modes that merge a root with its transitive dependencies, lazily, so a several-hundred-image OS closure is not eagerly demangled.
  • ObjC-ancestor classes β€” a Swift class deriving from NSObject et al. starts its own fields at the ObjC ancestor's instanceSize, located via the closure's libobjc and read from __objc_classlist.
  • Concrete bound-generic instantiations as fields β€” MyBox<Int> is laid out by capturing the depth-0 (depth, index) β†’ Node argument map and deep-rewriting the base type's dependentGenericParamType field nodes via Node.Rewriter (purely syntactic; no PWT). Also fixes a latent single-payload-enum bug where the payload would always read the first type argument instead of the right one.
  • Top-level concrete generic instantiations β€” fieldLayout(of:genericArguments:) and fieldLayout(forInstantiationMangledName:) lay out a concrete Foo<Int> from a binary's bound-generic mangled reference.

Per-field degradation rather than whole-type failure: an unresolvable field reports FieldResolution.unknown instead of taking down the entire layout. See StaticLayoutEngine.md and StaticLayoutDependencyClosure.md.

Reader-specialized FieldLayoutRenderer

FieldLayoutRenderer and the surrounding printer pipeline are now generic over the Mach-O reader and dispatch at compile time:

  • MachOImage path β€” renders field-offset / type-layout / expanded-tree / enum-layout comments from in-process runtime metadata (the existing behavior).
  • MachOFile (offline) path β€” renders the same comments statically through SwiftLayout's engine.

The upshot: swift-section dump / interface on a file now emit real field offsets without loading the process. See FieldLayoutRendererReaderSpecialization.md.

SwiftDump β†’ leaf: SwiftDeclarationRendering extraction

Field-metadata rendering used to live in SwiftDump. It now lives in a new SwiftDeclarationRendering module shared by SwiftDump and SwiftInterface, with SwiftDump reduced to a leaf in the dependency graph. The declaration model is now Codable end-to-end. See SwiftModularizationMigration.md.

Other notable surface

  • Diff formats: DiffFormat.inline / unified / markdownFenced (pluggable). The inline / markdown forms now insert a one-space gutter so the + / - / marker stays in column 0 and content always starts at column 2; the real-unified-diff path keeps an empty gutter to remain consumable by git apply / patch.
  • Per-member comment rows: offset / vtable / address comments now render on their own rows instead of fusing with the declaration line (made possible by the new Rows component in swift-semantic-string 0.1.5).
  • Generic argument rendering: value and pack generic arguments now appear in nested field-offset comments; non-type generic params are correctly skipped during nested field-offset substitution.
  • Codable declaration model β€” SwiftDeclaration model types are now end-to-end Codable, enabling snapshot pipelines and out-of-process tooling.

Bug Fixes

  • MachOExtensions β€” cache-resident MachOFiles are now keyed by LC_UUID (preferred) with LC_BUILD_VERSION as a fallback. The previous build-version-only key collided across dyld cache images that ship the same build version.
  • SwiftPrinting β€” the static-layout provider is now memoized atomically, and the cached provider is invalidated on updateConfiguration. Without this, a configuration change could leave stale rendered offsets.
  • SwiftLayout β€” corrected the 4-byte tag extra-inhabitant count; keyed BuiltinTypeLayoutIndex by demangled qualified name (the descriptor's typeName is a symbolic reference whose raw string is empty).
  • SwiftDump β€” specialized metadata is now resolved through its own reading context, not the indexer's.
  • SwiftDeclarationRendering β€” non-type generic params are skipped during nested field-offset substitution; previously they could surface as broken offset tags.
  • MachOSwiftSection β€” GenericParamDescriptor.kind is now total over the documented kinds.
  • SwiftDeclaration β€” model member ordering is now deterministic across snapshots.

Testing

  • A new MachOTestingSupport.TestActor global actor lets cross-suite fixtures share serial execution without ad-hoc isolation tags.
  • Integration SwiftInterfaceBuilder fixtures retargeted to SwiftUICore so they survive the SwiftUI module split.
  • macOS dyld shared cache paths (macOS_26_5_1, macOS_27_0_beta_1) added to DyldSharedCachePath.
  • SwiftLayout ships its own coverage for ObjC-ancestor layouts, builtin whole-type layouts, edge function kinds + ObjC-protocol existentials, structural multi-payload enum layout, concrete bound-generic field substitution, and top-level generic instantiation cross-checked against the runtime.
  • Tests for the new diff fixtures emit both inline and unified outputs for review.

Documentation

All docs are now consolidated under Documentations/, split into:

  • External / public (top level) β€” currently SwiftEnumLayout.md (+ SwiftEnumLayout_zh.md).
  • Internal / maintainer (Documentations/Internal/) β€” design notes, migration guides, per-phase write-ups for SwiftLayout, and dated per-task reports under Internal/TaskReports/.

The KNOWN_ISSUES.md file was removed β€” both documented concurrency issues are fixed in the current release.

Dependencies

  • swift-demangling bumped to 0.4.3 (requires Codable Node).
  • swift-semantic-string bumped to 0.1.5 (adds the Rows component used by the printer's per-member comment rows). The remote pin is now from: "0.1.5" rather than an exact version.

Requirements

  • Swift 6.2+
  • Xcode 26.0+ (CI validates on Xcode 26.4 / macOS 26)