0.12.0
Headline work since 0.11.0:
swift-section diffβ a new top-level CLI command that produces an ABI-aware, annotated Swift interface diff between two Mach-O binaries.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. Theswift-section dump/interfaceoffline (file) path now emits real field-offset / type-layout / expanded-tree / enum-layout comments.- Reader-specialized rendering β
FieldLayoutRendererand the printer pipeline now dispatch on the Mach-O reader type at compile time, so theMachOImagepath renders from in-process runtime metadata while theMachOFilepath renders fromSwiftLayout's static engine, with no runtime branch. SwiftDump β leafβ a substantial refactor extractedSwiftDeclarationRenderingsoSwiftDumpandSwiftInterfaceshare 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
SwiftInterfacefor 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 bygit apply/patch), andmarkdownFenced(```diffblock).
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 runtimegetEnumTagCountsformulas; multi-payload enums via the__swift5_builtinwhole-type descriptor (compiler-embedded layout) with a structural fallback that reusesEnumLayoutCalculator. - 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
ImageReferenceindexes__swift5_types,__swift5_protos, and__objc_classlist;ImageUniverseexposes 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
NSObjectet al. starts its own fields at the ObjC ancestor'sinstanceSize, 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) β Nodeargument map and deep-rewriting the base type'sdependentGenericParamTypefield nodes viaNode.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:)andfieldLayout(forInstantiationMangledName:)lay out a concreteFoo<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:
MachOImagepath β 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 throughSwiftLayout'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 bygit 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
Rowscomponent inswift-semantic-string0.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 β
SwiftDeclarationmodel types are now end-to-endCodable, enabling snapshot pipelines and out-of-process tooling.
Bug Fixes
MachOExtensionsβ cache-residentMachOFiles are now keyed byLC_UUID(preferred) withLC_BUILD_VERSIONas 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 onupdateConfiguration. Without this, a configuration change could leave stale rendered offsets.SwiftLayoutβ corrected the 4-byte tag extra-inhabitant count; keyedBuiltinTypeLayoutIndexby demangled qualified name (the descriptor'stypeNameis 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.kindis now total over the documented kinds.SwiftDeclarationβ model member ordering is now deterministic across snapshots.
Testing
- A new
MachOTestingSupport.TestActorglobal actor lets cross-suite fixtures share serial execution without ad-hoc isolation tags. - Integration
SwiftInterfaceBuilderfixtures 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 toDyldSharedCachePath. SwiftLayoutships 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 underInternal/TaskReports/.
The KNOWN_ISSUES.md file was removed β both documented concurrency issues are fixed in the current release.
Dependencies
swift-demanglingbumped to0.4.3(requiresCodableNode).swift-semantic-stringbumped to0.1.5(adds theRowscomponent used by the printer's per-member comment rows). The remote pin is nowfrom: "0.1.5"rather than an exact version.
Requirements
- Swift 6.2+
- Xcode 26.0+ (CI validates on Xcode 26.4 / macOS 26)