16.9 · What really crosses a module boundary: inlinable bodies and imports
Q364 covers access levels between modules. This section is about two things that cross a boundary without being public API: function bodies copied into clients, and the members a client can see through someone else’s import.
Mental model. A module boundary is not a wall: inlinable code and transitive imports leak through it, and each leak turns an implementation detail into something clients depend on.
Leaks and how to read them
What the compiler copies to clients, and what a client sees through an import.
- What does @inlinable change in a module’s .swiftinterface and in a client binary, and when is it worth the commitment?
Q45 explains the rule; here is the observable effect. A library built with library evolution (the setup for binary frameworks, Q366) emits a .swiftinterface… - What do public, package and internal imports change, and why can a client use members of a module it never imported?
Historically import Dep in a module was effectively public: its types could appear in your API, and, through a long-standing lookup quirk, extension members of…
More in Modularization & SPM
- 16.1 · Targets, products, modules, and access across module boundaries
- 16.2 · SPM, CocoaPods, Carthage and XCFrameworks, and shipping binaries
- 16.3 · Static and dynamic linking, duplicate symbols, and the dependency graph
- 16.4 · Build settings, configurations, xcconfig, and compile times
- 16.5 · Resource bundles, localisation in modules, and feature flags
- 16.6 · Multi-hour CI, affected-module builds, caching, and Tuist and Bazel
- 16.7 · Version rules, pins, conflicts, unsafe flags, mirrors and inspecting the graph
- 16.8 · Conditional settings, platform minimums, language modes, traits and plugins