pub fn load_package(
entries: &[PathBuf],
root: &Path,
namespace: &str,
) -> Result<LoadedPackage, LoadError>Expand description
Load a whole package as one program: every file gets its path-derived mangling prefix (no file is the unmangled “entry”), and each file’s declarations appear exactly once however many other files import it.
load_program and load_program_with_root flatten each entry’s
whole local-import closure into that entry’s program, so a caller
holding N top-level files gets every shared dependency back N times —
once per importer. The real 21-file lex-schema package, whose
error.lex is imported by 17 of its files, yielded 2,239 FnDecls
for 693 distinct names that way, and a server that canonicalizes,
type-checks, diffs and publishes each copy paid for all 2,239 (#828).
One shared pass yields 447 — one per declaration.
Because no file is the entry, no declaration keeps its bare
source-level name: fn validate in src/field.lex is
field_<hash>.validate, not validate. That is what makes one
program safe to type-check as a unit — two files may each declare
their own local validate, and the checker’s global scope is a map
keyed by name, so bare names from different files would silently
overwrite each other and check bodies against the wrong signature.
namespace is mixed into every mangling key ahead of the relative
path, so the same internal layout in two different packages does not
collapse onto one set of names. Callers publishing into a shared
branch should pass the package name: a tenant hosting both
lex-schema and lex-ocpi has two src/error.lex files, and a
purely path-derived key gives both the same error_<hash>.format.
Stdlib imports are deduped by (reference, alias). An alias bound to
two different references inside one package is rejected with
LoadError::ConflictingAlias rather than merged: the checker’s
alias scope is also name-keyed, so merging would silently resolve one
file’s calls against the other file’s module.