Skip to content

Release 0.19.0 - #124

Merged
Mx-Iris merged 29 commits into
mainfrom
next
Sep 7, 2026
Merged

Release 0.19.0#124
Mx-Iris merged 29 commits into
mainfrom
next

Conversation

@Mx-Iris

@Mx-Iris Mx-Iris commented Sep 7, 2026

Copy link
Copy Markdown
Member

Merges next into main for the 0.19.0 release. 27 commits, covering two unreleased versions since the 0.17.1 tag.

0.18.0 — self-contained ABI layer (proposal 0018)

MachOSwiftSection no longer depends on the symbol index or the demangler. Descriptors expose an implementation's offset/address; symbol attribution moved up to SwiftInspection; the symbol value types moved down to MachOResolving. New MachOBase umbrella. Source-breaking — see Changelogs/0.18.0.md for the migration table.

No 0.18.0 tag is planned; its changelog stays as the historical record and its contents ship inside this release.

0.19.0 — large-stack executor, cross-version parallelism, vtable slot attribution

Two output-neutral performance changes (proposal 0019):

  • Async entry points run on swift-demangling 0.6.3's 16 MB large-stack task executor, removing a thread round trip per printed symbol. SwiftUICore dump 48.8 s → 40.6 s, SwiftUI interface 87.5 s → 71.2 s.
  • Cross-version preparation (diff / evolution) is parallel, with --jobs N. Byte-identical to serial.

And one correctness fix that does change rendered output (proposal 0020):

  • A class vtable slot is attributed by its method descriptor's own Tq symbol rather than by the symbols at its implementation address, which identical code folding makes ambiguous — SwiftUICore's empty-ret address carries 2878 symbols, and SwiftUI.GraphHost's folded methods printed as coroutine resume functions of a nested struct. 828 declaration lines change on SwiftUICore; all 7 nested-type bleeds are gone with none introduced; Symbol not found 358 → 0.

Known rough edges shipping with this release

The vtable work was reviewed after implementation and four defects in its two new comments are not yet fixed — the null-implementation comment's wording overstates the cause, the ambiguity comment counts raw folded symbols rather than matching candidates, three code paths render a null implementation three different ways, and neither comment has a configuration switch. They are recorded with reproduction detail in Roadmaps/2026-09-06-pr123-review-findings.md and flagged in the 0.19.0 changelog's compatibility section. Merging with these known is a deliberate call.

Release checklist

  • Sources/swift-section/Version.swift = 0.19.0
  • Changelogs/0.19.0.md present (required by both the version-check and release workflows)
  • Proposals 0019 and 0020 numbered and marked Implemented
  • Tag 0.19.0 after merge to trigger the release workflow

Mx-Iris added 27 commits August 31, 2026 21:30
…/0014

Both proposals were set to `Implemented` (2026-08-25 and 2026-08-26) but
their landing commits skipped the numbering step Evolutions/README.md
requires — "assign the number in the commit that lands on a shared
branch" — so they kept `draft-` filenames and a `draft` entry in the
status table.

Numbers follow landing order: SwiftEvolutionInterfaceBuilder (08-25)
takes 0013, the renderer unification that builds on it (08-26) takes
0014. Global max was 0012, checked across every remote branch.

Cross-references updated everywhere they appear (no code or fixture
comment references either proposal, so the "slug only, never a number"
rule for those is unaffected): AGENTS.md, Glossary, ProjectEvolutionLog
sections 47 and 49, ABIEvolutionDesign, ReviewAdjudications A20, both
task reports, and 0014's related-proposal link. Each proposal records
the numbering in its own decision log, and 0012's decision log — which
cited these two as unnumbered at the time — is reworded so it no longer
contradicts itself.
The 17 superpowers-era plans/specs/reviews (2026-03..05) predate the
Documentations/ system and were only reachable through ProjectEvolutionLog
links. Keep what still earns its place, drop the rest (git history keeps
the originals):

- The GenericSpecializer bug review moves verbatim to Internal/Reviews/
  (its dated-review convention and content fit exactly).
- The four testing-infrastructure specs (CI snapshot testing, CI test
  filter, fixture ABI coverage, coverage tightening) plus the CI plan's
  post-landing fix table distill into the new
  Internal/FixtureTestingAndContinuousIntegration.md — design rationale
  and pitfalls only; AGENTS.md stays the operational authority.
- The ReadingContext coverage-completion spec's unique content (the
  runtimePointer(at:) extension-not-requirement decision, substitution
  rules) folds into ReadingContextAbstraction.md as a new section.
- The specializer-cleanup spec and all step-by-step plans are dropped:
  their durable content now lives in code comments, the review, or the
  consolidated doc.

ProjectEvolutionLog §5-§8 links repoint to the new homes.
New Documentations/Internal/Modules/ hosts one authoritative reference
doc per library module (positioning, subsystem map, cross-file
contracts, pointers to the detail docs); its README tracks coverage so
the remaining modules can be filled in over time.

The first entry covers SwiftInterface: the orchestrator role and its
three output products (single-version interface, two-sided diff,
N-way evolution), the five subsystems (core builder, opaque return
resolution, shared union walk, diff rendering, evolution rendering),
and a consumer-entry quick reference.
Index the Modules/ series and FixtureTestingAndContinuousIntegration.md
in Documentations/README.md, and update the ReadingContextAbstraction
row for its new completion-pass section.

AGENTS.md: drop the stale SwiftInterface bullet naming
SwiftInterfaceFile/SwiftInterfaceParser (both types left the tree long
ago), link the module reference doc from the SwiftInterface entry, and
link the fixture/CI design history from the fixture-coverage section.
…ocols

The registration protocol for the printer's external query resolvers
violated ISP and OCP: no real provider implemented all three methods
(each leaned on the default nil implementations, which also turn a
conformer signature drift into a silent unhook instead of a compile
error), and every new query capability had to widen the shared contract.

- Replace it with an empty registrable marker (TypeNameResolving) plus
  three single-method role protocols with no default implementations:
  ModuleNameResolving, CImportedNameResolving, OpaqueTypeResolving.
- SwiftDeclarationPrinter bins resolvers per role at registration time,
  so each delegate query walks only the resolvers that can answer it
  and the print path never runs a conformance cast.
- SwiftInterfaceBuilderExtraDataProvider decouples from the resolver
  concept entirely (Sendable + a setup() lifecycle hook); the builder
  forwards a provider to the printer only when it conforms to a role,
  making setup-only providers legitimate.
- TypeNameResolvable is removed with no compatibility alias on purpose:
  an alias would let an old conformer compile silently while never
  being consulted - the exact failure mode this change eliminates.

Output is byte-identical: the interface snapshot suite stays green,
131 + 97 tests across SwiftInterfaceTests, SwiftDumpTests and
SwiftSectionCommandTests pass.

Lands evolution proposal 0015 (Implemented) with the Evolutions index,
the SwiftInterface module reference, and ProjectEvolutionLog section 53
in the same batch.
… 0016)

Add `SwiftDeclarationPrintConfiguration.printExportedDeclarationsOnly` and
`swift-section interface --exported-only`: print only the declarations the
image exports. The filtering counterpart of proposal 0008's `// not exported`
annotation, print-time only (the indexed model stays complete; dump, diff and
evolution are untouched), default off with default output byte-identical.

Verdicts are export-trie facts, never access-level guesses: a declaration is
dropped only on a definitive negative and every `nil` keeps it. Types and
protocols are ruled by their descriptor symbol (`Mn` / `Mp`) — first the
symbol found at the descriptor's offset (the compiler's own spelling; a public
type nested in a constrained extension mangles only the extension's own
requirement, so the remangle-only first cut dropped an exported type), then a
remangled name against the trie that refuses `.extension` contexts. Members
reuse the derived-form verdict with the `override` / `@objc` exemptions,
stored fields their accessor group, enum cases are never filtered. Extensions
drop when their target or conforming protocol is an in-image non-exported
declaration per `ExportFilterScope`, which `printRoot()` builds from the
indexer's tables (a stripped image has no symbol for a non-exported type);
an emptied plain extension is dropped, an emptied conformance extension keeps
its clause as `{}`.

The three print entries split into a filter shell plus a `printIncluded…`
builder body; filtered definitions emit no print events, an emptied extension
emits a paired start/completion. `renderModelFields` pre-selects rendered
fields so survivors keep their original record index.

Tests: SymbolTestsCore end-to-end (private types / protocols / extensions,
constrained-extension regression, exemptions, emptied conformance, zero
annotations under both flags), a compile-on-the-fly library-evolution fixture
for the `internal` shapes, and the CLI flag. Docs: proposal 0016,
implementation note, README, glossary, evolution log, module reference,
task report, AGENTS.md.
…MachODependencies (proposal draft-macho-dependencies-module)

Extract the two independent "find the linked images" implementations into one
bottom-level target, MachODependencies (MachOKit + MachOKitExtensions only,
re-exported by MachOFoundation):

- DependencySearchPath, DependencyLoadName.bareImageName(of:) (the exact rule
  MachOImage(name:) matches on), DependencyLocating with an in-process and a
  file locator, and DependencyClosure with .direct / .transitive traversal.
  Resolution order is part of the contract (breadth-first, so a lazily
  indexing consumer meets the root's direct dependencies first); misses land
  in unresolvedLoadNames and unopenable search paths in
  searchPathLoadFailures instead of being dropped or thrown.
- FileDependencyLocator matches the exact install path first and falls back
  to a ranked bare-name match (DyldCacheImageSearchMode.matchRank), so a
  macOS cache's /System/iOSSupport Catalyst build can no longer shadow the
  native framework the way the old first-writer-wins index allowed. Each
  cache is indexed once, lazily; fat explicit files contribute the root's
  architecture.
- SwiftLayout's ImageUniverse.dependencyClosure factories become thin
  wrappers and gain dependencyClosure(_ closure:) for hosts that resolve once
  and share; LayoutDependencySearchPath is a deprecated typealias.
- SwiftInterfaceBuilderDependencies becomes a thin wrapper that keeps its
  direct-only semantics (TypeIndexing generates one SourceKit interface per
  dependency module), exposes unresolvedLoadNames and init(closure:), and
  deprecates DependencyPath + init(machO:paths:eventHandlers:). Its
  MachOImage initializer handed raw load paths to MachOImage(name:), which
  compares bare names, so it had resolved nothing since it was written; the
  shared normalization fixes it, pinned by a regression test.
- swift-section interface --resolve-c-module-names names the dependencies it
  could not resolve instead of only warning on an empty set.

Verification: 26 targeted tests green (new MachODependenciesTests +
SwiftInterfaceBuilderDependenciesTests + existing closure/layout suites);
full suite 1612 tests with only the two known-flaky SharedCache concurrency
cases failing (green in isolation); layout-flag dump/interface output over
SwiftUI, SwiftUICore, SwiftData and Combine byte-identical against next on
equal dependency versions, with equal timing.

Docs in the same batch: the proposal (Implemented; numbered at landing),
Internal/Modules/MachODependencies.md, AGENTS.md module graph and entries,
glossary terms, evolution log section, task report, and a pointer in
StaticLayoutDependencyClosure.md.
origin/next's Evolutions/ tops out at 0016, so this line takes 0017: rename
draft-macho-dependencies-module.md, update the title line, the status table,
and every same-repo link. Code comments keep citing the slug, as the
numbering rule requires.
Pinning swift-demangling alone to 0.6.1 (FrameworkToolbox held at 0.10.0)
reproduces the regression seen during the A/B: SwiftUICore layout dump
77-92 s -> 321-430 s, and the DEFAULT dump / interface paths 50-65 s ->
150-210 s, outputs identical. The only code change in 0.6.0..0.6.1 is
StackSafeExecutor re-ranking the large-stack worker's QoS per hop and
parking idle workers at background; every demangle / print / remangle call
is one hop. Recorded in AGENTS.md's drift note, the task report, and the
evolution log so the dependency is not bumped past 0.6.0 before upstream
addresses it.
…atch, CI coverage, slug citations

Code-review follow-ups on the MachODependencies extraction (proposal 0017):

- DependencyClosure also deduplicates by image identity
  (MachORepresentableWithCache.identifier, LC_UUID-keyed for a file). The
  file locator registers an explicit file under its on-disk path, its
  install name and its bare name, so a root linking the same binary under
  two load names reached one image twice and collected it twice — new in
  this branch, since the old locator never registered install names.
  Pinned by sameImageReachedUnderTwoLoadNamesIsCollectedOnce (images.count
  was 2 before the fix).
- FileDependencyLocator's slice choice compares CPU type plus the masked
  subtype instead of CPU type alone, so arm64 and arm64e are told apart.
  Not `CPU ==`: the synthesized equality includes the raw subtype's
  capability bits, so a versioned-ABI arm64e slice would compare unequal
  to a plain arm64e root and silently fall through to the type-only match.
- The four new suites join the CI test filter; the image-initializer
  regression test is what keeps InProcessDependencyLocator from being
  handed raw load paths again, and it has to run in CI to do that.
- SwiftInterfaceBuilderDependenciesTests declares
  ExclusiveImageAccess(.SymbolTestsHelper) like its sibling suite: the
  image initializer resolves the fixture's @rpath sibling through
  MachOImage(name:).
- Code comments cite the proposal by its slug (macho-dependencies-module),
  per the Evolutions rule; `draft-` was the in-flight filename prefix, not
  the slug.

Verified: the six affected suites (27 tests) green.
…self-contained-abi-layer)

The ABI model reached the symbol index two ways: five descriptors carried
`RelativeDirectPointer<Symbols?>` fields whose Resolvable implementation
built the whole image's demangled symbol index on first touch, and
SymbolOrElementPointer carried MachOSymbols.Symbol into every context
pointer. The ReadingContext leg of those accessors had no symbol service
at all and read the implementation's machine code as a Symbols value
(red test: offset -2999674702252736512 on the context leg vs 5624 on the
MachO leg).

- Descriptors expose implementationOffset / implementationAddress(in:)
  (defaultImplementation... on ProtocolRequirement); implementationSymbols
  moves to SwiftInspection as extensions, non-throwing, MachO-backed only.
- Symbol / Symbols / SymbolOrElement move to MachOResolving; Symbols is
  no longer Resolvable; SymbolOrElementPointer moves to MachOPointers and
  the MachOSymbolPointers target is removed; the index-backed lookups
  (symbols(offset:), Symbol.resolve(from:in:), the index-store switch)
  stay in MachOSymbols.
- New MachOBase umbrella (MachOKitExtensions + reading + resolving +
  pointers + Utilities) is all MachOSwiftSection depends on and re-exports;
  MachOFoundation = MachOBase + MachOSymbols + MachODependencies. The
  Demangling dependency goes too: the mangling-prefix helpers and the
  __C / __C_Synthesized module names are local copies, pinned equal to
  the demangler by ManglingPrefixTests.
- symbols(offset:) async removed rather than deprecated: an async caller
  binds to it and demands await, so the pair cannot coexist.
- 16 targets declare the MachOFoundation dependency they only reached
  through MachOSwiftSection's re-export; explicit imports added likewise.
- Fixture suites pin implementationOffset literals and the context-leg
  address equality; five baselines regenerated; the CI filter gains the
  five suites that pin this change.
- Docs: proposal (In Progress; numbered at landing), Internal/
  SelfContainedABILayer.md, AGENTS.md module graph and entries, doc
  indexes, evolution log, task report; Changelogs/0.18.0.md and
  Version.swift 0.17.1 -> 0.18.0.

Verification: MachOSwiftSectionTests 723 tests / 161 suites green; full
suite 1617 / 302 green apart from the two known wall-clock parallelism
flakes (green in isolation); rendering A/B over the system dyld cache,
four simulator runtimes and in-process MachOImage: 78 pairs byte-identical.
…allelism proposal

Companion of swift-demangling proposal 0014 (shipped in 0.6.3). Status
Draft, awaiting acceptance; records why whole-library async adoption was
rejected and what the executor-preference integration will look like.
…e-stack-executor-and-cross-version-parallelism)

0.6.1 re-ranked the hop pool's QoS per call and slowed dump/interface 3-4x;
0.6.2 partitioned the pool by class and restored the speed; 0.6.3 ships the
large-stack TaskExecutor the proposal adopts. The floor skips 0.6.1.

The proposal moves to In Progress: the user asked for the implementation on
top of the self-contained ABI branch.
…cutor and prepare versions in parallel (proposal draft-large-stack-executor-and-cross-version-parallelism)

swift-demangling's StackSafeExecutor decides per demangle / print / remangle
whether to hop to its 8 MB pool by probing the calling thread's remaining
stack; cooperative threads carry 512 KB, so an async print loop paid one
thread round trip and a semaphore wait per printed symbol. The new
MachOSymbols.LargeStackTaskExecution.run sets swift-demangling 0.6.3's 16 MB
LargeStackTaskExecutor as the task executor preference around every library
entry point (indexer prepare, interface builder prepare/printRoot, diffable
builder prepare, evolution builder prepare/render, diff renderer, the
printer's per-definition entries, the six Dumpable.dump conformers), so the
whole pipeline runs inline. Nesting is a no-op, no unstructured Task exists
in the library, and below macOS 15 / iOS 18 the body runs unchanged;
isEnabled (seeded by MACHO_SWIFT_SECTION_LARGE_STACK_EXECUTOR=0) turns it off.

Multi-version preparation is parallel: AnySwiftEvolutionInterfaceBuilder
.prepare(maximumConcurrentPreparations:) (default = processor count, 1 = the
old serial order), swift-section diff / evolution --jobs N, all through a
windowed Collection.concurrentMap(maximumConcurrency:_:) in Utilities.

Verified: 1637 tests pass; rendering A/B 78 pairs byte-identical with the
executor on and off; SwiftUICore/SwiftUI dump+interface 16-23% faster, a
three-version SwiftUI evolution 2.0x faster. Bumps to 0.19.0.
…log, test pinning, target deps (proposal self-contained-abi-layer)

Twelve review findings on PR #121, all confirmed (Roadmaps/2026-09-04-pr121-
review-findings.md):

- Package.swift exposes MachOBase and MachOFoundation as library products: the
  ABI model no longer re-exports the symbol index, so a downstream target had
  no product to declare for the `import MachOFoundation` the changelog asked
  for. The changelog's Compatibility section now says so.
- The changelog's "byte-identical" claim is qualified to the default flags:
  under --emit-member-addresses a resilient witness whose implementation
  pointer is null no longer prints an address comment (the old line was the
  pointer field's own position). An 8-pair comparison with the flag over
  SwiftUICore/SwiftUI/SwiftData/Combine is identical — none carries such a
  witness.
- ManglingPrefixTests pins CImportedModuleNames to the demangler's constants,
  which the docs already claimed.
- ProtocolRequirementTests exercises a requirement WITH a default
  implementation (new picker protocol_BasicDefaultProtocol, baseline entry
  firstDefaultedRequirement), and MethodOverrideDescriptor's baseline emits
  implementationOffset as a literal; both go red under a mutated accessor.
- SwiftLayout / SwiftDeclarationRendering / SwiftInterface declare
  MachOFoundation, MachOSwiftSectionTests declares SwiftInspection,
  MachOSwiftSection gets back the Utilities dependency the umbrella switch
  dropped; the CI filter gains MethodDefaultOverrideDescriptorTests.
- ProtocolConformanceDumper uses the new offset accessors throughout;
  MethodDescriptorTests' image leg asserts on its own offset; the prefix
  strip scans once.

Deferred with adjudication entries A23 (pre-existing undeclared imports) and
A24 (repo-wide migration of the remaining raw resolveDirectOffset sites).
origin/next's Evolutions/ tops out at 0017, so this line takes 0018: rename
draft-self-contained-abi-layer.md, update the title line, the status table
(Implemented), the evolution-log section number (56) and every same-repo
link. Code comments keep citing the slug, as the numbering rule requires.
Also records the review batch in the proposal's decision log and the task
report.
…ack-executor-and-cross-version-parallelism

# Conflicts:
#	.github/workflows/macOS.yml
#	Documentations/Evolutions/README.md
#	Documentations/Evolutions/draft-large-stack-executor-and-cross-version-parallelism.md
…p, serialized event delivery, labeled diagnostics (proposal large-stack-executor-and-cross-version-parallelism)

Fifteen review findings on PR #122 (Roadmaps/2026-09-04-pr122-review-
findings.md): five defects, one false positive, nine design/style calls.

- concurrentMap(maximumConcurrency:) submits through addTaskUnlessCancelled
  and fails with CancellationError once the calling task is cancelled; the
  first version used addTask, which a cancelled group still accepts, so a
  cancelled multi-version preparation indexed every remaining version to the
  end (reproduced independently by the reviewer). Never a partial array —
  the unwrap below would trap.
- LargeStackTaskExecutionTests guard isEnabled as well as isSupported: under
  MACHO_SWIFT_SECTION_LARGE_STACK_EXECUTOR=0 (the A/B configuration) the
  executor-thread assertions went red for a reason the tests do not control.
- That variable now accepts 0 / false / no / off (case-insensitive) as off;
  the literal-"0" comparison let =false measure the executor twice.
- parallelPreparationMatchesSerialPreparation prepares the parallel builder
  FIRST, so it meets cold caches; a three-way barrier pins that a window of
  three admits three.
- SwiftIndexEvents.Dispatcher serializes handler invocation process-wide
  with a recursive lock: Handler has no Sendable requirement and parallel
  preparation shares one host handler across N dispatchers on N tasks.
- ConsoleEventHandler(label:) prefixes [label]; diff tags old / new,
  evolution tags each version (AnySwiftEvolutionInterfaceBuilder gained
  eventHandlersPerVersion:), snapshot inputs use their label or file name.
- The redundant import Utilities is gone.

Every behavioral fix verified red under a mutated build. Adjudicated as
A25–A33: the import MachOFoundation false positive, per-entry wraps, the
concurrentMap name, #isolation forwarding, .serialized vs the process
switch, the executor-off window, the default lineage window (kept, user's
call), the unavoidable dual availability gate, and TypeDatabase's
same-shaped addTask (deferred: no injection seam for a red test).
…ols (proposal vtable-slot-attribution-via-method-descriptor-symbols)

Which member a vtable slot belongs to came from the symbols at its
implementation address — a mapping identical code folding leaves without an
inverse. SwiftUICore's empty-`ret` address carries 2878 symbols, and
SwiftUI.GraphHost's four folded vtable methods printed as one correct name
plus three coroutine resume functions of its NESTED GraphHost.Data struct:
slots 26-29 were all wrong, and the real instantiateOutputs /
uninstantiateOutputs / timeDidChange never appeared in the listing at all.
Reported from Hopper, confirmed against the binary (class descriptor
0x98c9c8, vTableOffset 20, vTableSize 10, Tq symbols at 0x98c9fc-0x98ca44).

A `Tq` method-descriptor symbol is a per-member data symbol at the
descriptor's own address, so folding cannot reach it; proposal 0006 already
relied on that as negative evidence for `final`, and this is the same fact
used positively. Attribution now reads the descriptor's own `Tq` first and
falls back to the implementation address only when there is none (~28% of
slots), annotating that fallback when it lands on a folded address instead
of presenting a guess as fact. The dump path and TypeDefinition.index share
the evidence order.

Only the class's own MethodDescriptor. An override descriptor has no `Tq`
and the one it points at belongs to the PARENT, which answers a different
question than either consumer asks — attributing through it made `override`
vanish from interface output entirely and renamed dump lines to the
overridden member. Protocol-side attribution is likewise untouched:
requirement descriptors such as `base conformance descriptor` carry no
entity node, so a declaration-context match dropped 1033 lines of
SwiftUICore protocol output to `[Stripped Symbol]`.

A null implementation is an ABI tombstone — member deleted, slot retained,
metadata bound to swift_deletedMethodError — and now renders as such above
the name the `Tq` symbol still supplies, replacing a bare `Symbol not found`.
Fallback candidate matching goes through the member's DIRECT declaration
context instead of `first(of: .class)`, which accepted a nested type's
member as the enclosing class's own.

Verified on SwiftUICore (iOS 18.5 arm64): 828 declaration lines change, all
7 nested-type bleeds gone with zero new ones, `Symbol not found` 358 -> 0
(195 recovered a real name, 163 became annotated tombstones), zero lines
regressed from a name to a `sub_` address. Cross-checked 1199 `Tq` symbols
in address order against the dumped slot order — 54 of 55 comparable classes
match exactly, 0 order mismatches. Snapshot baselines updated after
reviewing every hunk; two pre-existing defects fell out of the same change:
FinalMembersTest's kind comments were systematically paired with the wrong
names, and `classMethod` printed as `static func` where the fixture declares
`public class func`.

Pinned by VTableSlotAttributionTests (fixture forced to fold with
`-Xlinker -deduplicate`) and GraphHostVTableAttributionTests (the reported
binary, simulator-runtime-gated); reverting the source changes turns 3 of
the 5 red. Full suite green: 1654 tests in 309 suites.
`/code-review xhigh` over PR #123 produced 15 findings, each answered
against the four questions (reproduce / baseline / worth fixing / prior
fix): 4 real defects, 3 worth fixing in the same batch, 3 low priority,
3 false positives or already adjudicated, 2 process.

No code changed — this commit lands the record only; the fix batch is
separate.

The top finding invalidates a premise this proposal already recorded.
The new `deleted method — slot retained for ABI` comment asserts a cause
for every null implementation pointer, but every non-async
`__allocating_init` in the fixture is labelled that way, including
`public final class TestsObjects {}`, whose implicit `init()` plainly
exists. A null implementation pointer is a pre-existing observation on
`next` (it rendered as `Symbol not found` there); the causal reading is
new and does not hold, and the 33% tombstone rate the docs now record for
SwiftUICore is not credible on its face.

- `Roadmaps/2026-09-06-pr123-review-findings.md` — the findings list with
  per-finding four-question reasoning and the resulting to-do list.
- `ReviewAdjudications.md` A34–A39 — the won't-fix / false-positive /
  deferred verdicts. `class func static` was already adjudicated by
  `ClassMemberKeywordRecovery.md` when issue #99 was fixed and is not a
  defect this PR introduced; the `.boundGenericFunction` claim is refuted
  by the node's child layout (its first child is the function node, not a
  declaration context, so walking through it is what yields the right
  context); the fixture's Intel-host failure cannot occur because swiftc
  emits a thin host-architecture library.
- Proposal decision log — two rows: the review itself, and the tombstone
  premise now pending re-adjudication.
…rding does not

A peer review of the PR #123 findings overturned two of them, and an
independent probe confirmed the correction, so the record is rewritten
rather than appended to.

Finding 1 was recorded as "the comment asserts a cause that does not
hold". It does hold. IRGen's `buildMethodDescriptorFields` has exactly
two branches — write the relative address when the SIL vtable has an
entry, write null when it does not — and the null branch's own comment
reads "The method is removed by dead method elimination." The null is the
compiler's marker, not this library's inference. The original reading
mistook "the declaration exists" for "the implementation exists": what
dead-method elimination removes is the body, and the declaration, the
`Tq` symbol and the descriptor all survive it.

The real cause is access level, not `async`. A public type's undecorated
`init()` is internal, and under whole-module optimization an internal
member is not a dead-function-elimination anchor, so an uncalled one
loses its body. Every marked slot in the fixture is internal or a member
of a function-local class; every unmarked one is an explicit `public
init`. `AsyncInitializerActorTest` was spared for being public, which the
first pass misread as being async.

Probe (`swiftc -O -wmo -enable-library-evolution`): an internal implicit
`init()` and internal accessors emit a `Tq` symbol and no function
symbol, while an explicit `public init()` emits both a function symbol
and a dispatch thunk; `dyld_info -fixups` counts exactly the expected
five `_swift_deletedMethodError` binds. The 33% figure measured on
SwiftUICore is therefore credible, and the docs keep it.

What remains to fix is the wording — "deleted method" reads as "the API
was deleted" — plus a caveat the docs never carried: `swift_deletedMethodError`
is only filled into *static* metadata, while runtime-instantiated
metadata (generic classes, resilient-superclass relocation) copies the
descriptor's null through `initClassVTable` unchanged.

Finding 5 is upgraded rather than corrected: the un-deduplicated walk is
also a correctness defect, because it descends through any wrapper node
and so reports the host of a closure, a default argument or a variable
initialization expression as a declaration context. Descending only a
whitelist of wrappers fixes that and removes the DAG blow-up at once.

A34–A36 were re-confirmed. A38 gains a unit-level test path, so "no
reproduction available" no longer justifies deferring it.

Still record-only; no product code changed. The comment wording, the
switches (ambiguity on by default, tombstone following
`--emit-vtable-offsets`) and the test-side assertions belong to the fix
batch.
Second-round peer review corrected the whitelist its own first round had
supplied from memory, and the three node kinds involved were re-checked
against swift-demangling before this commit.

- `vTableThunk` must be in the whitelist. `vtable thunk for Base.f()
  dispatching to Sub.f()` is a legitimate implementation symbol for an
  override slot (the ResilientClasses snapshot carries one), so omitting
  it degrades the override fallback to `override <unnamed vtable slot>`.
  `Demangler.swift:1744` builds `children: [derived, base]` and
  `printVTableThunk` prints `children[1]` after "vtable thunk for" and
  `children[0]` after "dispatching to" — the wanted child is `children[0]`.
  The current breadth-first walk only gets this right by accident, because
  `children[0]` happens to be enqueued first.
- The accessor kinds are `modifyAccessor` / `modify2Accessor` /
  `readAccessor` / `read2Accessor` / `unsafeAddressor` /
  `unsafeMutableAddressor` alongside `getter` / `setter`. The `modify` and
  `read` spellings recorded last round do not exist.
- `mergedFunction`, `asyncFunctionPointer`, `coroFunctionPointer` and
  `objCAttribute` are childless singletons from `NodeFactory`, emitted as
  siblings under `global`. Walking `global`'s children already covers
  them; they are not wrappers to descend through.
- `methodDescriptor` is dropped: both callers feed the walk symbols found
  at an implementation address, and a `Tq` is a data symbol that never
  appears there. Dropping it narrows the contract to "implementation
  symbol tree".

AGENTS.md overstated three things. Membership is `internal` and narrower
(`package` is still an anchor), and only under whole-module optimization
— elsewhere `internal` stays an anchor, making this a Release-build
phenomenon. The 341 / 11680 figures count bind SITES, which exceed
deleted methods because a subclass's metadata re-emits inherited slots.
And the static-versus-runtime split is decided by
`ClassLayoutFlags::HasStaticVTable`, which IRGen sets for Singleton /
Update / FixedOrUpdate alike, so only generic classes and the Resilient
strategy rebuild a vtable at runtime.

Both comment literals are restored to what the code emits today, each
with a note that the wording is due to change in the fix batch — docs
must not describe output that does not exist yet.

The glossary gains the same `HasStaticVTable` distinction plus the reason
it matters offline: a Resilient-strategy class read from a `MachOFile`
exposes only a metadata pattern, with no vtable word to read, so the
verdict has to come from the descriptor's null.
…ork in 0.19.0

Release preparation for 0.19.0, which ships two independent pieces of
work rather than the one its changelog described.

- Both proposals get their number at landing, in landing order: the
  large-stack executor work (already on `next`) becomes 0019, the vtable
  slot attribution work becomes 0020. Both move to `Implemented`, and
  every cross-reference, the evolutions index and the docs index follow.
- `Changelogs/0.19.0.md` gains the vtable attribution entry, and its
  headline claim is corrected: the release is no longer "two related
  changes, both output-neutral". The attribution fix changes rendered
  output on purpose — 828 declaration lines on SwiftUICore, where slot
  names that identical code folding had made wrong are now right — so the
  compatibility section says which half is byte-identical and which half
  is not, and warns anyone diffing against 0.18.0.
- The compatibility section also records the two comment defects the
  review found and the missing configuration switch, pointing at the
  findings file, so they ship as known rough edges rather than as
  surprises.
…e-slot-attribution

Attribute vtable slots by method descriptor symbols
Copilot AI lite review requested due to automatic review settings September 7, 2026 08:48

Copilot AI 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.

🟡 Changes recommended

There are unused imports introduced in changed files that can trigger build warnings (and may fail CI if warnings are treated as errors).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Release-merge PR for 0.19.0, bringing the new module layering (self-contained ABI layer via MachOBase), large-stack executor adoption for async entry points, cross-version preparation parallelism, and updated output/snapshots for vtable-slot attribution and related rendering changes.

Changes:

  • Introduce/propagate the MachOBase umbrella and update MachOSwiftSection to depend on it (and re-export it) instead of MachOFoundation.
  • Wrap SwiftDump dump entry points in LargeStackTaskExecution.run { … } and update extra-data provider plumbing to use role-based resolver protocols (TypeNameResolving + sub-roles).
  • Bump bundled version to 0.19.0, refresh fixture baselines/snapshots, and expand CI test filters.
File summaries
File Description
Tests/SwiftInterfaceTests/Snapshots/Snapshots/SymbolTestsCoreInterfaceSnapshotTests/interfaceSnapshot.1.txt Snapshot update reflecting class vs static member rendering.
Tests/SwiftIndexingTests/OverrideRecoveryPredicateTests.swift Test import adjustment for moved Symbol type usage.
Tests/SwiftDumpTests/Snapshots/Snapshots/SymbolTestsCoreDumpSnapshotTests/basicTypesSnapshot.1.txt Snapshot update for new vtable/implementation attribution output.
Tests/SwiftDiffingTests/ABIExtensionAttributionTests.swift Import update to use umbrella exports after layering changes.
Tests/SwiftDiffingTests/ABIDifferTests.swift Import update to use umbrella exports after layering changes.
Tests/SwiftAttributeInferenceTests/TypeAttributeInferrerTests.swift Import update to use umbrella exports after layering changes.
Tests/MachOSymbolsTests/SymbolIndexStoreFixtureTests.swift Import update for moved symbol value types.
Tests/MachOSymbolsTests/PackedNameReferenceBudgetTests.swift Import update for moved symbol value types.
Tests/MachOSwiftSectionTests/Fixtures/Type/Class/Method/MethodDefaultOverrideDescriptorTests.swift Update fixture invariants to new implementation-pointer API (implementationOffset / implementationAddress).
Tests/MachOSwiftSectionTests/Fixtures/Baseline/MethodDefaultOverrideDescriptorBaseline.swift Baseline registered-method list updated to new API surface.
Tests/IntegrationTests/TypeIndexing/TypeNameProviderTests.swift Update dependencies initializer API (searchPaths:) and search-path enum case rename.
Tests/IntegrationTests/MachOSwiftSection/OpaqueTypeTests.swift Update symbol lookup API usage (machO.symbols(offset:)) and imports.
Sources/TypeIndexing/SwiftInterfaceBuilderTypeNameProvider.swift Provider now conforms to role protocols (ModuleNameResolving, CImportedNameResolving).
Sources/SwiftLayout/ImageUniverse.swift (Added import) now pulls in MachOFoundation (but appears unused).
Sources/SwiftInterface/SwiftInterfaceBuilderOpaqueTypeProvider.swift Provider now conforms to OpaqueTypeResolving role protocol.
Sources/SwiftInterface/SwiftInterfaceBuilderExtraDataProvider.swift Provider protocol simplified to lifecycle hook + role-based resolver forwarding.
Sources/SwiftInterface/SwiftEvolutionInterfaceBuilder.swift Pack facade prepare signature aligned with erased builder’s concurrency parameter.
Sources/SwiftDump/Dumpable/Struct+Dumpable.swift Wrap dump entry in LargeStackTaskExecution.run.
Sources/SwiftDump/Dumpable/ProtocolConformance+Dumpable.swift Wrap dump entry in LargeStackTaskExecution.run.
Sources/SwiftDump/Dumpable/Protocol+Dumpable.swift Wrap dump entry in LargeStackTaskExecution.run.
Sources/SwiftDump/Dumpable/Enum+Dumpable.swift Wrap dump entry in LargeStackTaskExecution.run.
Sources/SwiftDump/Dumpable/Class+Dumpable.swift Wrap dump entry in LargeStackTaskExecution.run.
Sources/SwiftDump/Dumpable/AssociatedType+Dumpable.swift Wrap dump entry in LargeStackTaskExecution.run.
Sources/SwiftDeclarationRendering/StaticFieldLayoutProvider.swift Dependency search-path type updated to DependencySearchPath (but MachOFoundation import appears unused).
Sources/SwiftDeclaration/Components/Definitions/FunctionDefinition.swift Import update to align with symbol/type relocation via umbrellas.
Sources/swift-section/Version.swift Bump bundled version string to 0.19.0.
Sources/MachOSymbols/SymbolTable.swift Import update for symbol value types now in MachOResolving.
Sources/MachOSymbols/SymbolIndexStore.swift Import update for symbol value types now in MachOResolving.
Sources/MachOSymbols/DemangledSymbol.swift Import update for symbol value types now in MachOResolving.
Sources/MachOSwiftSection/Utils/ResolvableLocatableLayoutWrapper.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Utils/MachOSwiftSectionError.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Utils/AnyLocatableLayoutWrapper.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Runtime/RuntimeFunctions.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Pointer/RelativeProtocolDescriptorPointer.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Pointer/RelativePointers.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Pointer/ContextPointer.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ValueWitnessTable/ValueWitnessTable.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ValueWitnessTable/TypeLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/ValueMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/ValueMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/TypeReference.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/TypeMetadataRecord.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/TypeContextWrapper.swift Remove MachOSymbols dependency from ABI layer type wrapper.
Sources/MachOSwiftSection/Models/Type/TypeContextDescriptorWrapper.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/TypeContextDescriptorProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/TypeContextDescriptorLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/TypeContextDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Struct/StructMetadataProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Struct/StructMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Struct/StructMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Struct/StructDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Struct/Struct.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Enum/MultiPayloadEnumDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Enum/Metadata/EnumMetadataProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Enum/Metadata/EnumMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Enum/Metadata/EnumMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Enum/EnumDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Enum/Enum.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Resilient/ResilientSuperclass.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Resilient/ObjCResilientClassStubInfo.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Method/VTableDescriptorHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Method/OverrideTableHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Method/MethodImplementationPointer.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Method/MethodDefaultOverrideTableHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/ObjCClassWrapperMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/FinalClassMetadataProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/FinalClassMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/ClassMetadataObjCInterop/ClassMetadataObjCInteropProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/ClassMetadataObjCInterop/ClassMetadataObjCInteropLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/ClassMetadataObjCInterop/ClassMetadataObjCInterop.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/ClassMetadata/ClassMetadataProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/ClassMetadata/ClassMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/ClassMetadata/ClassMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/Bounds/StoredClassMetadataBounds.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/AnyClassMetadataObjCInterop/AnyClassMetadataObjCInteropProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/AnyClassMetadataObjCInterop/AnyClassMetadataObjCInteropLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/AnyClassMetadataObjCInterop/AnyClassMetadataObjCInterop.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/AnyClassMetadata/AnyClassMetadataProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/AnyClassMetadata/AnyClassMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Metadata/AnyClassMetadata/AnyClassMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/ClassDescriptorLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/ClassDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Type/Class/Class.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/TupleType/TupleTypeMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/TupleType/TupleTypeMetadataElementLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/TupleType/TupleTypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ProtocolConformance/ProtocolConformanceDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ProtocolConformance/ProtocolConformance.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ProtocolConformance/GlobalActorReference.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ResilientWitnessesHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ProtocolWitnessTable.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ProtocolRecord.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ProtocolDescriptorWithObjCInterop.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ProtocolDescriptorRef.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ProtocolDescriptorLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ProtocolDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/Protocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ObjC/RelativeObjCProtocolPrefix.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Protocol/ObjC/ObjCProtocolPrefix.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/OpaqueType/OpaqueTypeDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/OpaqueType/OpaqueType.swift Remove demangler/symbol-layer dependency from ABI-layer opaque type model.
Sources/MachOSwiftSection/Models/OpaqueType/OpaqueMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Module/ModuleContextDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Module/ModuleContext.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/SingletonMetadataPointer.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetatypeMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetatypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetadataWrapper.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetadataResponse.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetadataInitialization/SingletonMetadataInitialization.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetadataInitialization/ForeignMetadataInitialization.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetadataBoundsLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/MetadataAccessorFunction.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataLayoutPrefixProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataLayoutPrefixLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataLayoutPrefix.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataHeaderProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataHeaderLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataHeaderBaseProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataHeaderBaseLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataHeaderBase.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/TypeMetadataHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/HeapMetadataHeaderProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/HeapMetadataHeaderPrefixProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/HeapMetadataHeaderPrefixLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/HeapMetadataHeaderPrefix.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/HeapMetadataHeaderLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/Headers/HeapMetadataHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/FullMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/FixedArrayTypeMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/FixedArrayTypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/CanonicalSpecializedMetadatasListEntry.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/CanonicalSpecializedMetadatasCachingOnceToken.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Metadata/CanonicalSpecializedMetadataAccessorsListEntry.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Heap/HeapLocalVariableMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Heap/GenericBoxHeapMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/TypeGenericContextDescriptorHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericWitnessTable.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericValueHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericValueDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericRequirementDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericRequirementContent.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericRequirement.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericParamDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericPackShapeHeader.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericPackShapeDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericEnvironment.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Generic/GenericContext.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Function/FunctionTypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ForeignType/ForeignReferenceTypeMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ForeignType/ForeignReferenceTypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ForeignType/ForeignClassMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ForeignType/ForeignClassMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/FieldRecord/FieldRecord.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/FieldDescriptor/FieldDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Extension/ExtensionContextDescriptorLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Extension/ExtensionContextDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Extension/ExtensionContext.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ExistentialType/NonUniqueExtendedExistentialTypeShape.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ExistentialType/ExtendedExistentialTypeShape.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ExistentialType/ExtendedExistentialTypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ExistentialType/ExistentialTypeMetadataLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ExistentialType/ExistentialTypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ExistentialType/ExistentialTypeFlags.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ExistentialType/ExistentialMetatypeMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/DispatchClass/DispatchClassMetadata.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ContextDescriptor/NamedContextDescriptorProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ContextDescriptor/NamedContextDescriptorLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ContextDescriptor/ContextWrapper.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ContextDescriptor/ContextProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ContextDescriptor/ContextDescriptorWrapper.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ContextDescriptor/ContextDescriptorLayout.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/ContextDescriptor/ContextDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/BuiltinType/BuiltinTypeDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/BuiltinType/BuiltinType.swift Remove MachOSymbols/MachOFoundation dependency in ABI layer.
Sources/MachOSwiftSection/Models/AssociatedType/AssociatedTypeRecord.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/AssociatedType/AssociatedTypeDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/AssociatedType/AssociatedType.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Anonymous/AnonymousContextDescriptorProtocol.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Anonymous/AnonymousContextDescriptor.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Models/Anonymous/AnonymousContext.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/MachOImage+Swift.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/MachOFile+Swift.swift Swap MachOFoundation import to MachOBase.
Sources/MachOSwiftSection/Exported.swift Re-export MachOBase from ABI layer instead of MachOFoundation.
Sources/MachOResolving/SymbolOrElement.swift Remove self-import cleanup after module reshuffle.
Sources/MachOPointers/SymbolOrElementPointer.swift Remove higher-layer imports after symbol/type relocation.
Sources/MachOFoundation/Exported.swift Adjust umbrella exports to re-export MachOBase + MachODependencies + MachOSymbols.
Sources/MachOFixtureSupport/Baseline/Generators/Class/MethodDefaultOverrideDescriptorBaselineGenerator.swift Update baseline generator list for new implementation-pointer API names.
Sources/MachOFixtureSupport/Baseline/BaselineEmitter.swift Add optionalHex(_:) for optional pointer/offset baselines.
Sources/MachOBase/Exported.swift New MachOBase umbrella module exporting reader/resolver/pointer layer.
Documentations/Internal/TaskReports/2026-08-26-unify-interface-renderers.md Update proposal link to numbered evolution doc.
Documentations/Internal/TaskReports/2026-08-25-swift-evolution-interface-builder.md Update proposal link to numbered evolution doc.
Documentations/Internal/ABIEvolutionDesign.md Update proposal reference to numbered evolution doc.
.github/workflows/macOS.yml Expand CI test filter list to include newly relevant suites.
Review details
  • Files reviewed: 299/344 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 1 to 7
import Foundation
import MachOKit
import MachODependencies
import MachOSwiftSection
import MachOFoundation
import SwiftLayout
@_spi(Internals) import SwiftInspection
Comment on lines 1 to +2
import MachOSwiftSection
import MachOFoundation
The 0.19.0 release PR was the first time these suites met CI, and four of
them failed with every implementation offset shifted by exactly +16
(`MethodDescriptorTests` 5624 → 5640, `MethodOverrideDescriptorTests`
16404 → 16420, `ResilientWitnessTests` 9100 → 9116,
`ProtocolRequirementTests` 45256 → 45272). The code is correct: rebuilding
the fixture without `CODE_SIGNING_ALLOWED=NO` and re-running the same five
suites passes 28/28.

Bisected one variable at a time against the same sources:

- `CODE_SIGNING_ALLOWED=NO` alone → red, offsets +16.
- `ARCHS=arm64` alone → green.
- `-derivedDataPath` length (hence the absolute path) → no effect; a short
  path with the setting is red, a long path without it is green.

So the setting, added in PR #65, is what moved the offsets, while the
baselines were generated with the command AGENTS.md documents, which does
not carry it. The name is misleading too: the product carries an
`LC_CODE_SIGNATURE` with or without it, so it was never suppressing
signing here — only changing layout.

`DependencyClosureTests` failed for an unrelated reason in the same run:
the normalize step linked only `SymbolTestsCore` into the path the tests
read from, so resolving `SymbolTestsHelper` raised "The file
SymbolTestsHelper doesn't exist". It now links every framework the tests
need; verified locally, where the four failing cases pass once the helper
is linked.

The DerivedData cache key gains the workflow file, without which this
change would be masked: the key covers only fixture sources and the
pbxproj, so a settings change restores a cache built under the old
settings. That is exactly what issue #66 asked for; it was closed as
completed in June but the key no longer carried it, so this is a
regression being re-fixed rather than a new idea.

Why it stayed hidden: this workflow triggers on `branches: [main]` for
both `push` and `pull_request`, so no `→ next` PR ever runs it. The
mismatch accumulated across 27 commits and surfaced all at once on the
release PR.

AGENTS.md gains the drift note, next to the two it already documents,
with the measured offsets and the rule that CI's fixture build command
and the baseline regeneration command must stay identical.
Copilot AI review requested due to automatic review settings September 7, 2026 09:35

Copilot AI 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.

🔵 Needs a closer look

This is a large release merge with widespread module-boundary/public API changes and snapshot churn, which warrants final human review before approval.

Review details
  • Files reviewed: 299/344 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Fixes the build failure the previous commit introduced. Dropping
`CODE_SIGNING_ALLOWED=NO` made Xcode fall back to a real signing identity,
which a GitHub runner does not have:

    error: No signing certificate "Mac Development" found (in target
    'SymbolTestsCore' from project 'SymbolTests')

That setting was there for a reason; the mistake was removing it rather
than replacing it. `CODE_SIGN_IDENTITY=-` with `CODE_SIGNING_REQUIRED=NO`
needs no certificate and reproduces the signed layout exactly, which is
what the baselines require.

The mechanism, now that it is pinned down: the two products have identical
headers (35 load commands, 5000 bytes) and both carry an
`LC_CODE_SIGNATURE`. What differs is the alignment padding between the load
commands and `__text` — 64 bytes when signed, 80 when built with
`CODE_SIGNING_ALLOWED=NO` — so `__text` starts at `0x13e8` versus `0x13f8`
and every implementation offset shifts by 16. An ad-hoc build lands at
`0x13e8`, and the five suites pass 28/28 against it locally.

So the baselines stay untouched and no one has to remember special
settings when regenerating them: an ordinary locally-signed build and CI's
ad-hoc build produce the same layout.
Copilot AI review requested due to automatic review settings September 7, 2026 09:40

Copilot AI 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.

🔵 Needs a closer look

This is a large release merge with broad module-boundary and public-API surface changes that require a full human pass over compatibility, docs, and downstream impact.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

Sources/SwiftInterface/SwiftEvolutionInterfaceBuilder.swift:63

  • prepare(maximumConcurrentPreparations:) adds a defaulted parameter, which can be a source-breaking change for callers that pass prepare as a function value (the method reference type becomes (Int) async throws -> Void). Consider keeping an explicit prepare() overload that forwards to the new API to preserve the previous method-reference shape.
  • Files reviewed: 299/344 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@Mx-Iris
Mx-Iris merged commit 61f0628 into main Sep 7, 2026
4 checks passed
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.

2 participants