Skip to content

Prefer FoundationEssentials over Foundation for the Data bridges#57

Open
lhoward wants to merge 1 commit into
apple:mainfrom
PADL:foundation-essentials
Open

Prefer FoundationEssentials over Foundation for the Data bridges#57
lhoward wants to merge 1 commit into
apple:mainfrom
PADL:foundation-essentials

Conversation

@lhoward

@lhoward lhoward commented Jun 9, 2026

Copy link
Copy Markdown

Motivation

The optional Data conveniences in ParserSource.swift and Parsers/Data.swift use public import Foundation, guarded only on canImport(Foundation). Two consequences on non-Darwin (Linux) platforms:

  1. Because these are public (re-exported) imports, every downstream consumer of BinaryParsing inherits a link dependency on full Foundation — even modules that never touch Data. The autolink propagates transitively.
  2. Full Foundation on Linux pulls in FoundationInternationalization and the ICU data library (_FoundationICU, tens of MB), even though the only symbol used from Foundation here is Data, which is available in FoundationEssentials.

For size-sensitive / embedded-adjacent Linux deployments this drags the entire ICU blob into the link closure of any executable that uses BinaryParsing but not full Foundation. (Found while shrinking a Swift networking daemon for a 64 MB target — BinaryParsing was the sole remaining anchor forcing libFoundation + ICU into an otherwise FoundationEssentials-only binary.)

Change

In both files, prefer FoundationEssentials when available, falling back to full Foundation:

#if !$Embedded && canImport(FoundationEssentials)
public import FoundationEssentials
#elseif !$Embedded && canImport(Foundation)
public import Foundation
#endif
  • The canImport(Foundation) guards around the Data extensions are widened to (canImport(FoundationEssentials) || canImport(Foundation)).
  • Foundation.Data is de-qualified to Data so it resolves from whichever module was imported.
  • $Embedded handling is unchanged.

Effect

No API change — the Data initializers (init(parsingRemainingBytes:), init(parsing:byteCount:)) and the Data: ParserSpanProvider conformance are identical. On Linux this removes libFoundation, libFoundationInternationalization, and the ICU data library from the transitive link closure for consumers that don't otherwise use full Foundation. Verified end-to-end: a dynamically-linked executable depending on BinaryParsing dropped from needing libFoundation + libFoundationInternationalization + _FoundationICU to needing only libFoundationEssentials.

🤖 Generated with Claude Code

The optional `Data` conveniences in `ParserSource.swift` and `Data.swift`
used `public import Foundation` guarded on `canImport(Foundation)`. Because
these are *public* (re-exported) imports, every downstream consumer of
BinaryParsing inherits a link dependency on full Foundation — which on
non-Darwin platforms pulls in FoundationInternationalization and the ICU
data blob — even though the only symbol used is `Data`, which is available
in FoundationEssentials.

Prefer FoundationEssentials when available, falling back to Foundation, and
de-qualify `Foundation.Data` to `Data` so it resolves from whichever module
is imported. No API change: the `Data` initializers and `ParserSpanProvider`
conformance are unchanged; this only narrows the transitive link dependency.

On Linux this removes libFoundation, libFoundationInternationalization and
the ICU data library from the link closure of any executable that uses
BinaryParsing but not full Foundation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant