successfully load package-qualified host

This commit is contained in:
Folkert 2020-12-07 23:24:06 +01:00
parent d008cc1d7b
commit 7123269f30
6 changed files with 242 additions and 122 deletions

View file

@ -14,7 +14,9 @@ use roc_constrain::module::{
};
use roc_constrain::module::{constrain_module, ExposedModuleTypes, SubsByModule};
use roc_module::ident::{Ident, Lowercase, ModuleName, QualifiedModuleName, TagName};
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, PackageModuleIds, Symbol};
use roc_module::symbol::{
IdentIds, Interns, ModuleId, ModuleIds, PQModuleName, PackageModuleIds, Symbol,
};
use roc_mono::ir::{
CapturedSymbols, ExternalSpecializations, PartialProc, PendingSpecialization, Proc, Procs,
};
@ -230,7 +232,13 @@ impl Dependencies {
self.add_dependency_help(a, b, phase, phase);
}
/// phase_a of module a is waiting for phase_b of module_b
fn add_dependency_help(&mut self, a: ModuleId, b: ModuleId, phase_a: Phase, phase_b: Phase) {
// no need to wait if the dependency is already done!
if let Some(Status::Done) = self.status.get(&(b, phase_b)) {
return;
}
let key = (a, phase_a);
let value = (b, phase_b);
match self.waiting_for.get_mut(&key) {
@ -279,7 +287,7 @@ impl Dependencies {
/// Struct storing various intermediate stages by their ModuleId
#[derive(Debug, Default)]
struct ModuleCache<'a> {
module_names: MutMap<ModuleId, ModuleName>,
module_names: MutMap<ModuleId, PQModuleName<'a>>,
/// Phases
headers: MutMap<ModuleId, ModuleHeader<'a>>,
@ -342,15 +350,16 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
let dep_name = state
.module_cache
.module_names
.remove(&module_id)
.expect("module id is present");
.get(&module_id)
.expect("module id is present")
.clone();
BuildTask::LoadModule {
module_name: dep_name,
// Provide mutexes of ModuleIds and IdentIds by module,
// so other modules can populate them as they load.
module_ids: Arc::clone(&state.arc_modules),
package_module_ids: Arc::clone(&state.arc_package_modules),
shorthands: Arc::clone(&state.arc_shorthands),
ident_ids_by_module: Arc::clone(&state.ident_ids_by_module),
mode: state.stdlib.mode,
}
@ -399,8 +408,10 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
// This should be small, and cloning it should be quick.
// We release the lock as soon as we're done cloning, so we don't have
// to lock the global module_ids while canonicalizing any given module.
let module_ids = Arc::clone(&state.arc_modules);
let module_ids = { (*module_ids).lock().clone() };
let qualified_module_ids = Arc::clone(&state.arc_modules);
let qualified_module_ids = { (*qualified_module_ids).lock().clone() };
let module_ids = qualified_module_ids.to_module_ids();
let exposed_symbols = state
.exposed_symbols_by_module
@ -411,17 +422,16 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
for imported in parsed.imported_modules.iter() {
match state.module_cache.aliases.get(imported) {
None => unreachable!(
"imported module {:?} did not register its aliases, so {:?} cannot use them",
imported,
parsed.module_id,
),
Some(new) => {
// TODO filter to only add imported aliases
aliases.extend(new.iter().map(|(s, a)| (*s, a.clone())));
None => unreachable!(
r"imported module {:?} did not register its aliases, so {:?} cannot use them",
imported, parsed.module_id,
),
Some(new) => {
// TODO filter to only add imported aliases
aliases.extend(new.iter().map(|(s, a)| (*s, a.clone())));
}
}
}
}
BuildTask::CanonicalizeAndConstrain {
parsed,
@ -544,9 +554,9 @@ struct ModuleHeader<'a> {
module_name: AppOrInterfaceName<'a>,
module_path: PathBuf,
exposed_ident_ids: IdentIds,
deps_by_name: MutMap<ModuleName, ModuleId>,
deps_by_name: MutMap<PQModuleName<'a>, ModuleId>,
packages: MutMap<&'a str, PackageOrPath<'a>>,
imported_modules: MutSet<ModuleId>,
imported_package_modules: MutSet<ModuleId>,
exposes: Vec<Symbol>,
exposed_imports: MutMap<Ident, (Symbol, Region)>,
src: &'a [u8],
@ -612,7 +622,7 @@ struct ParsedModule<'a> {
module_path: PathBuf,
src: &'a str,
module_timing: ModuleTiming,
deps_by_name: MutMap<ModuleName, ModuleId>,
deps_by_name: MutMap<PQModuleName<'a>, ModuleId>,
imported_modules: MutSet<ModuleId>,
exposed_ident_ids: IdentIds,
exposed_imports: MutMap<Ident, (Symbol, Region)>,
@ -696,8 +706,8 @@ struct State<'a> {
pub constrained_ident_ids: MutMap<ModuleId, IdentIds>,
/// From now on, these will be used by multiple threads; time to make an Arc<Mutex<_>>!
pub arc_modules: Arc<Mutex<ModuleIds>>,
pub arc_package_modules: Arc<Mutex<PackageModuleIds<'a>>>,
pub arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
pub arc_shorthands: Arc<Mutex<MutMap<&'a str, PackageOrPath<'a>>>>,
pub ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
@ -825,16 +835,15 @@ impl ModuleTiming {
#[allow(dead_code)]
enum BuildTask<'a> {
LoadModule {
module_name: ModuleName,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
module_name: PQModuleName<'a>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
shorthands: Arc<Mutex<MutMap<&'a str, PackageOrPath<'a>>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
},
LoadPkgConfig {
shorthand: &'a str,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
},
@ -888,6 +897,7 @@ pub enum LoadingProblem {
FileProblem {
filename: PathBuf,
error: io::ErrorKind,
msg: &'static str,
},
ParsingFailed {
filename: PathBuf,
@ -999,8 +1009,7 @@ pub fn load_and_monomorphize_from_str<'a>(
}
struct LoadStart<'a> {
pub arc_modules: Arc<Mutex<ModuleIds>>,
pub arc_package_modules: Arc<Mutex<PackageModuleIds<'a>>>,
pub arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
pub ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
pub root_id: ModuleId,
pub root_msg: Msg<'a>,
@ -1012,8 +1021,7 @@ impl<'a> LoadStart<'a> {
filename: PathBuf,
mode: Mode,
) -> Result<Self, LoadingProblem> {
let arc_modules = Arc::new(Mutex::new(ModuleIds::default()));
let arc_package_modules = Arc::new(Mutex::new(PackageModuleIds::default()));
let arc_modules = Arc::new(Mutex::new(PackageModuleIds::default()));
let root_exposed_ident_ids = IdentIds::exposed_builtins(0);
let ident_ids_by_module = Arc::new(Mutex::new(root_exposed_ident_ids));
@ -1024,8 +1032,8 @@ impl<'a> LoadStart<'a> {
load_filename(
arena,
filename,
None,
Arc::clone(&arc_modules),
Arc::clone(&arc_package_modules),
Arc::clone(&ident_ids_by_module),
root_start_time,
mode,
@ -1034,7 +1042,6 @@ impl<'a> LoadStart<'a> {
Ok(LoadStart {
arc_modules,
arc_package_modules,
ident_ids_by_module,
root_id,
root_msg,
@ -1047,8 +1054,7 @@ impl<'a> LoadStart<'a> {
src: &'a str,
mode: Mode,
) -> Result<Self, LoadingProblem> {
let arc_modules = Arc::new(Mutex::new(ModuleIds::default()));
let arc_package_modules = Arc::new(Mutex::new(PackageModuleIds::default()));
let arc_modules = Arc::new(Mutex::new(PackageModuleIds::default()));
let root_exposed_ident_ids = IdentIds::exposed_builtins(0);
let ident_ids_by_module = Arc::new(Mutex::new(root_exposed_ident_ids));
@ -1061,7 +1067,6 @@ impl<'a> LoadStart<'a> {
filename,
src,
Arc::clone(&arc_modules),
Arc::clone(&arc_package_modules),
Arc::clone(&ident_ids_by_module),
root_start_time,
mode,
@ -1070,7 +1075,6 @@ impl<'a> LoadStart<'a> {
Ok(LoadStart {
arc_modules,
arc_package_modules,
ident_ids_by_module,
root_id,
root_msg,
@ -1139,12 +1143,13 @@ where
{
let LoadStart {
arc_modules,
arc_package_modules,
ident_ids_by_module,
root_id,
root_msg,
} = load_start;
let arc_shorthands = Arc::new(Mutex::new(MutMap::default()));
let (msg_tx, msg_rx) = bounded(1024);
msg_tx
.send(root_msg)
@ -1276,7 +1281,7 @@ where
headers_parsed,
loading_started,
arc_modules,
arc_package_modules,
arc_shorthands,
constrained_ident_ids: IdentIds::exposed_builtins(0),
ident_ids_by_module,
declarations_by_id: MutMap::default(),
@ -1409,6 +1414,14 @@ fn update<'a>(
log!("loaded header for {:?}", header.module_id);
let home = header.module_id;
{
let mut shorthands = (*state.arc_shorthands).lock();
for (shorthand, package_or_path) in header.packages.iter() {
shorthands.insert(shorthand, package_or_path.clone());
}
}
// store an ID to name mapping, so we know the file to read when fetching dependencies' headers
for (name, id) in header.deps_by_name.iter() {
state.module_cache.module_names.insert(*id, name.clone());
@ -1786,7 +1799,8 @@ fn finish_specialization<'a>(
) -> MonomorphizedModule<'a> {
let module_ids = Arc::try_unwrap(state.arc_modules)
.unwrap_or_else(|_| panic!("There were still outstanding Arc references to module_ids"))
.into_inner();
.into_inner()
.to_module_ids();
let interns = Interns {
module_ids,
@ -1836,7 +1850,8 @@ fn finish<'a>(
) -> LoadedModule {
let module_ids = Arc::try_unwrap(state.arc_modules)
.unwrap_or_else(|_| panic!("There were still outstanding Arc references to module_ids"))
.into_inner();
.into_inner()
.to_module_ids();
let interns = Interns {
module_ids,
@ -1869,8 +1884,7 @@ fn load_pkg_config<'a>(
arena: &'a Bump,
src_dir: &Path,
shorthand: &'a str,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
) -> Result<Msg<'a>, LoadingProblem> {
@ -1912,7 +1926,6 @@ fn load_pkg_config<'a>(
arena,
shorthand,
module_ids,
package_module_ids,
ident_ids_by_module,
mode,
header,
@ -1926,6 +1939,7 @@ fn load_pkg_config<'a>(
Err(err) => Err(LoadingProblem::FileProblem {
filename,
error: err.kind(),
msg: "while reading a Pkg-Config.roc file",
}),
}
}
@ -1934,9 +1948,9 @@ fn load_pkg_config<'a>(
fn load_module<'a>(
arena: &'a Bump,
src_dir: &Path,
module_name: ModuleName,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
module_name: PQModuleName<'a>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
arc_shorthands: Arc<Mutex<MutMap<&'a str, PackageOrPath<'a>>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
@ -1945,9 +1959,35 @@ fn load_module<'a>(
filename.push(src_dir);
// Convert dots in module name to directories
for part in module_name.as_str().split(MODULE_SEPARATOR) {
filename.push(part);
let opt_shorthand;
match module_name {
PQModuleName::Unqualified(name) => {
opt_shorthand = None;
// Convert dots in module name to directories
for part in name.split(MODULE_SEPARATOR) {
filename.push(part);
}
}
PQModuleName::Qualified(shorthand, name) => {
opt_shorthand = Some(shorthand);
let shorthands = arc_shorthands.lock();
match shorthands.get(shorthand) {
Some(PackageOrPath::Path(StrLiteral::PlainLine(path))) => {
filename.push(path);
}
Some(PackageOrPath::Path(_str_liteal)) => {
unreachable!("invalid structure for path")
}
Some(PackageOrPath::Package(_name, _version)) => todo!("packages"),
None => unreachable!("there is no shorthand named {:?}", shorthand),
}
// Convert dots in module name to directories
for part in name.split(MODULE_SEPARATOR) {
filename.push(part);
}
}
}
// End with .roc
@ -1956,8 +1996,8 @@ fn load_module<'a>(
load_filename(
arena,
filename,
opt_shorthand,
module_ids,
package_module_ids,
ident_ids_by_module,
module_start_time,
mode,
@ -1995,8 +2035,8 @@ fn parse_header<'a>(
arena: &'a Bump,
read_file_duration: Duration,
filename: PathBuf,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
opt_shorthand: Option<&'a str>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
src_bytes: &'a [u8],
@ -2020,11 +2060,12 @@ fn parse_header<'a>(
value: AppOrInterfaceName::Interface(header.name.value),
},
filename,
opt_shorthand,
&[],
header.exposes.into_bump_slice(),
header.imports.into_bump_slice(),
parse_state,
module_ids,
package_module_ids,
ident_ids_by_module,
module_timing,
)),
@ -2032,24 +2073,27 @@ fn parse_header<'a>(
let mut pkg_config_dir = filename.clone();
pkg_config_dir.pop();
let packages = header.packages.into_bump_slice();
let (module_id, app_module_header_msg) = send_header(
Located {
region: header.name.region,
value: AppOrInterfaceName::App(header.name.value),
},
filename,
opt_shorthand,
packages,
header.provides.into_bump_slice(),
header.imports.into_bump_slice(),
parse_state,
module_ids.clone(),
package_module_ids.clone(),
ident_ids_by_module.clone(),
module_timing,
);
match header.to.value {
To::ExistingPackage(existing_package) => {
let opt_base_package = header.packages.iter().find(|loc_package_entry| {
let opt_base_package = packages.iter().find(|loc_package_entry| {
let Located { value, .. } = loc_package_entry;
match value {
@ -2086,7 +2130,6 @@ fn parse_header<'a>(
&pkg_config_roc,
shorthand,
module_ids,
package_module_ids,
ident_ids_by_module,
mode,
)?;
@ -2126,7 +2169,6 @@ fn parse_header<'a>(
arena,
&"",
module_ids,
package_module_ids,
ident_ids_by_module,
mode,
header,
@ -2140,8 +2182,8 @@ fn parse_header<'a>(
fn load_filename<'a>(
arena: &'a Bump,
filename: PathBuf,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
opt_shorthand: Option<&'a str>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
module_start_time: SystemTime,
mode: Mode,
@ -2155,8 +2197,8 @@ fn load_filename<'a>(
arena,
file_io_duration,
filename,
opt_shorthand,
module_ids,
package_module_ids,
ident_ids_by_module,
mode,
arena.alloc(bytes),
@ -2165,6 +2207,7 @@ fn load_filename<'a>(
Err(err) => Err(LoadingProblem::FileProblem {
filename,
error: err.kind(),
msg: "in `load_filename`",
}),
}
}
@ -2176,8 +2219,7 @@ fn load_from_str<'a>(
arena: &'a Bump,
filename: PathBuf,
src: &'a str,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
module_start_time: SystemTime,
mode: Mode,
@ -2189,8 +2231,8 @@ fn load_from_str<'a>(
arena,
file_io_duration,
filename,
None,
module_ids,
package_module_ids,
ident_ids_by_module,
mode,
src.as_bytes(),
@ -2209,11 +2251,12 @@ enum AppOrInterfaceName<'a> {
fn send_header<'a>(
loc_name: Located<AppOrInterfaceName<'a>>,
filename: PathBuf,
opt_shorthand: Option<&'a str>,
packages: &'a [Located<PackageEntry<'a>>],
exposes: &'a [Located<ExposesEntry<'a, &'a str>>],
imports: &'a [Located<ImportsEntry<'a>>],
parse_state: parser::State<'a>,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
module_timing: ModuleTiming,
) -> (ModuleId, Msg<'a>) {
@ -2232,7 +2275,6 @@ fn send_header<'a>(
let mut imported: Vec<(QualifiedModuleName, Vec<Ident>, Region)> =
Vec::with_capacity(imports.len());
let mut imported_modules: MutSet<ModuleId> = MutSet::default();
let mut imported_package_modules: MutSet<ModuleId> = MutSet::default();
let mut scope_size = 0;
for loc_entry in imports {
@ -2244,7 +2286,7 @@ fn send_header<'a>(
}
let num_exposes = exposes.len();
let mut deps_by_name: MutMap<ModuleName, ModuleId> =
let mut deps_by_name: MutMap<PQModuleName, ModuleId> =
HashMap::with_capacity_and_hasher(num_exposes, default_hasher());
let mut exposed: Vec<Symbol> = Vec::with_capacity(num_exposes);
@ -2257,10 +2299,15 @@ fn send_header<'a>(
let ident_ids = {
// Lock just long enough to perform the minimal operations necessary.
let mut module_ids = (*module_ids).lock();
let mut package_module_ids = (*package_module_ids).lock();
let mut ident_ids_by_module = (*ident_ids_by_module).lock();
home = module_ids.get_or_insert(&declared_name.as_inline_str());
let name = match opt_shorthand {
Some(shorthand) => {
PQModuleName::Qualified(&shorthand, declared_name.as_inline_str().clone())
}
None => PQModuleName::Unqualified(declared_name.as_inline_str().clone()),
};
home = module_ids.get_or_insert(&name);
// Ensure this module has an entry in the exposed_ident_ids map.
ident_ids_by_module
@ -2274,26 +2321,23 @@ fn send_header<'a>(
// Also build a list of imported_values_to_expose (like `bar` above.)
for (qualified_module_name, exposed_idents, region) in imported.into_iter() {
let cloned_module_name = qualified_module_name.module.clone();
let module_id = match qualified_module_name.opt_package {
None => {
let id = module_ids.get_or_insert(&qualified_module_name.module.into());
imported_modules.insert(id);
deps_by_name.insert(cloned_module_name, id);
id
}
let pq_module_name = match qualified_module_name.opt_package {
None => match opt_shorthand {
Some(shorthand) => {
PQModuleName::Qualified(shorthand, qualified_module_name.module.into())
}
None => PQModuleName::Unqualified(qualified_module_name.module.into()),
},
Some(package) => {
let id =
package_module_ids.get_or_insert(&(package, cloned_module_name.into()));
imported_package_modules.insert(id);
id
PQModuleName::Qualified(package, cloned_module_name.clone().into())
}
};
let module_id = module_ids.get_or_insert(&pq_module_name);
imported_modules.insert(module_id);
deps_by_name.insert(pq_module_name, module_id);
// Add the new exposed idents to the dep module's IdentIds, so
// once that module later gets loaded, its lookups will resolve
// to the same symbols as the ones we're using here.
@ -2341,6 +2385,25 @@ fn send_header<'a>(
ident_ids.clone()
};
let mut parse_entries: Vec<_> = (&packages).iter().map(|x| &x.value).collect();
let mut package_entries = MutMap::default();
while let Some(parse_entry) = parse_entries.pop() {
use PackageEntry::*;
match parse_entry {
Entry {
shorthand,
package_or_path,
..
} => {
package_entries.insert(*shorthand, package_or_path.value.clone());
}
SpaceBefore(inner, _) | SpaceAfter(inner, _) => {
parse_entries.push(inner);
}
}
}
// Send the deps to the coordinator thread for processing,
// then continue on to parsing and canonicalizing defs.
//
@ -2354,8 +2417,8 @@ fn send_header<'a>(
module_path: filename,
exposed_ident_ids: ident_ids,
module_name: loc_name.value,
packages: package_entries,
imported_modules,
imported_package_modules,
deps_by_name,
exposes: exposed,
src: parse_state.bytes,
@ -2480,8 +2543,7 @@ fn run_solve<'a>(
fn fabricate_effects_module<'a>(
arena: &'a Bump,
shorthand: &'a str,
module_ids: Arc<Mutex<ModuleIds>>,
package_module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
header: PlatformHeader<'a>,
@ -2520,7 +2582,8 @@ fn fabricate_effects_module<'a>(
let mut module_ids = (*module_ids).lock();
let mut ident_ids_by_module = (*ident_ids_by_module).lock();
module_id = module_ids.get_or_insert(&declared_name.as_inline_str());
let name = PQModuleName::Qualified(shorthand, declared_name.as_inline_str().clone());
module_id = module_ids.get_or_insert(&name);
// Ensure this module has an entry in the exposed_ident_ids map.
ident_ids_by_module
@ -2575,7 +2638,7 @@ fn fabricate_effects_module<'a>(
let mut var_store = VarStore::default();
let module_ids = { (*module_ids).lock().clone() };
let module_ids = { (*module_ids).lock().clone() }.to_module_ids();
let mut scope = roc_can::scope::Scope::new(module_id, &mut var_store);
let mut can_env = roc_can::env::Env::new(module_id, dep_idents, &module_ids, exposed_ident_ids);
@ -3207,7 +3270,7 @@ fn run_task<'a>(
LoadModule {
module_name,
module_ids,
package_module_ids,
shorthands,
ident_ids_by_module,
mode,
} => load_module(
@ -3215,7 +3278,7 @@ fn run_task<'a>(
src_dir,
module_name,
module_ids,
package_module_ids,
shorthands,
ident_ids_by_module,
mode,
)
@ -3223,7 +3286,6 @@ fn run_task<'a>(
LoadPkgConfig {
shorthand,
module_ids,
package_module_ids,
ident_ids_by_module,
mode,
} => load_pkg_config(
@ -3231,7 +3293,6 @@ fn run_task<'a>(
src_dir,
shorthand,
module_ids,
package_module_ids,
ident_ids_by_module,
mode,
),