Which module cache invalidation signal does Swift use for private implementation changes?
0 reputation · 24 Jul 2020, 12:42 UTC
Swift's incremental build system caches compiled modules as .swiftmodule files to avoid recompiling unchanged dependencies. In recent Swift toolchains, the compiler evaluates file timestamps and dependency hashes to decide whether a cached module remains valid. A known area of uncertainty involves changes confined to a module's private implementation—such as adding an internal function—where the public interface hash stays identical. If that internal code is exposed through inlineable declarations, clients may embed the old implementation while the library binary expects new behavior, creating a potential correctness gap. The Swift project has not settled whether any source-level modification should force cache invalidation or whether interface-level hashes alone are sufficient, balancing build speed against safety.
Which invalidation heuristic does the Swift compiler apply when a dependency's private source changes but its public interface hash does not? Under what conditions does the module cache reuse a .swiftmodule despite modifications to non-public implementation that affect inlineable code? Is there a documented distinction between timestamp-based and hash-based staleness checks for this scenario?