mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
Correct imports of Encode and abilities across modules
This commit is contained in:
parent
47c9959786
commit
312cdd0b70
15 changed files with 375 additions and 214 deletions
|
@ -127,6 +127,7 @@ struct ModuleCache<'a> {
|
|||
headers: MutMap<ModuleId, ModuleHeader<'a>>,
|
||||
parsed: MutMap<ModuleId, ParsedModule<'a>>,
|
||||
aliases: MutMap<ModuleId, MutMap<Symbol, (bool, Alias)>>,
|
||||
abilities: MutMap<ModuleId, AbilitiesStore>,
|
||||
constrained: MutMap<ModuleId, ConstrainedModule>,
|
||||
typechecked: MutMap<ModuleId, TypeCheckedModule<'a>>,
|
||||
found_specializations: MutMap<ModuleId, FoundSpecializationsModule<'a>>,
|
||||
|
@ -146,51 +147,33 @@ impl Default for ModuleCache<'_> {
|
|||
fn default() -> Self {
|
||||
let mut module_names = MutMap::default();
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::RESULT,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::RESULT)),
|
||||
);
|
||||
macro_rules! insert_builtins {
|
||||
($($name:ident,)*) => {$(
|
||||
module_names.insert(
|
||||
ModuleId::$name,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::$name)),
|
||||
);
|
||||
)*}
|
||||
}
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::LIST,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::LIST)),
|
||||
);
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::STR,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::STR)),
|
||||
);
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::DICT,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::DICT)),
|
||||
);
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::SET,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::SET)),
|
||||
);
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::BOOL,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::BOOL)),
|
||||
);
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::NUM,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::NUM)),
|
||||
);
|
||||
|
||||
module_names.insert(
|
||||
ModuleId::BOX,
|
||||
PQModuleName::Unqualified(ModuleName::from(ModuleName::BOX)),
|
||||
);
|
||||
insert_builtins! {
|
||||
RESULT,
|
||||
LIST,
|
||||
STR,
|
||||
DICT,
|
||||
SET,
|
||||
BOOL,
|
||||
NUM,
|
||||
BOX,
|
||||
ENCODE,
|
||||
}
|
||||
|
||||
Self {
|
||||
module_names,
|
||||
headers: Default::default(),
|
||||
parsed: Default::default(),
|
||||
aliases: Default::default(),
|
||||
abilities: Default::default(),
|
||||
constrained: Default::default(),
|
||||
typechecked: Default::default(),
|
||||
found_specializations: Default::default(),
|
||||
|
@ -305,10 +288,12 @@ fn start_phase<'a>(
|
|||
|
||||
let exposed_symbols = state
|
||||
.exposed_symbols_by_module
|
||||
.remove(&module_id)
|
||||
.expect("Could not find listener ID in exposed_symbols_by_module");
|
||||
.get(&module_id)
|
||||
.expect("Could not find listener ID in exposed_symbols_by_module")
|
||||
.clone();
|
||||
|
||||
let mut aliases = MutMap::default();
|
||||
let mut abilities_store = AbilitiesStore::default();
|
||||
|
||||
for imported in parsed.imported_modules.keys() {
|
||||
match state.module_cache.aliases.get(imported) {
|
||||
|
@ -327,6 +312,27 @@ fn start_phase<'a>(
|
|||
}));
|
||||
}
|
||||
}
|
||||
|
||||
match state.module_cache.abilities.get(imported) {
|
||||
None => unreachable!(
|
||||
r"imported module {:?} did not register its abilities, so {:?} cannot use them",
|
||||
imported, parsed.module_id,
|
||||
),
|
||||
Some(import_store) => {
|
||||
let exposed_symbols = state
|
||||
.exposed_symbols_by_module
|
||||
.get(imported)
|
||||
.unwrap_or_else(|| {
|
||||
internal_error!(
|
||||
"Could not find exposed symbols of imported {:?}",
|
||||
imported
|
||||
)
|
||||
});
|
||||
|
||||
abilities_store
|
||||
.union(import_store.closure_from_imported(exposed_symbols));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let skip_constraint_gen = {
|
||||
|
@ -341,6 +347,7 @@ fn start_phase<'a>(
|
|||
exposed_symbols,
|
||||
module_ids,
|
||||
aliases,
|
||||
abilities_store,
|
||||
skip_constraint_gen,
|
||||
}
|
||||
}
|
||||
|
@ -866,6 +873,7 @@ enum BuildTask<'a> {
|
|||
dep_idents: IdentIdsByModule,
|
||||
exposed_symbols: VecSet<Symbol>,
|
||||
aliases: MutMap<Symbol, Alias>,
|
||||
abilities_store: AbilitiesStore,
|
||||
skip_constraint_gen: bool,
|
||||
},
|
||||
Solve {
|
||||
|
@ -2028,6 +2036,11 @@ fn update<'a>(
|
|||
.aliases
|
||||
.insert(module_id, constrained_module.module.aliases.clone());
|
||||
|
||||
state
|
||||
.module_cache
|
||||
.abilities
|
||||
.insert(module_id, constrained_module.module.abilities_store.clone());
|
||||
|
||||
state
|
||||
.module_cache
|
||||
.constrained
|
||||
|
@ -2644,90 +2657,36 @@ fn load_module<'a>(
|
|||
|
||||
module_timing.read_roc_file = Default::default();
|
||||
module_timing.parse_header = parse_header_duration;
|
||||
match module_name.as_inner().as_str() {
|
||||
"Result" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::RESULT,
|
||||
"Result.roc",
|
||||
));
|
||||
}
|
||||
"List" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::LIST,
|
||||
"List.roc",
|
||||
));
|
||||
}
|
||||
"Str" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::STR,
|
||||
"Str.roc",
|
||||
));
|
||||
}
|
||||
"Dict" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::DICT,
|
||||
"Dict.roc",
|
||||
));
|
||||
}
|
||||
"Set" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::SET,
|
||||
"Set.roc",
|
||||
));
|
||||
}
|
||||
"Num" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::NUM,
|
||||
"Num.roc",
|
||||
));
|
||||
}
|
||||
"Bool" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::BOOL,
|
||||
"Bool.roc",
|
||||
));
|
||||
}
|
||||
"Box" => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
ModuleId::BOX,
|
||||
"Box.roc",
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
// fall through
|
||||
}
|
||||
|
||||
macro_rules! load_builtins {
|
||||
($($name:literal, $module_id:path)*) => {
|
||||
match module_name.as_inner().as_str() {
|
||||
$(
|
||||
$name => {
|
||||
return Ok(load_builtin_module(
|
||||
arena,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
module_timing,
|
||||
$module_id,
|
||||
concat!($name, ".roc")
|
||||
));
|
||||
}
|
||||
)*
|
||||
_ => { /* fall through */ }
|
||||
}}
|
||||
}
|
||||
|
||||
load_builtins! {
|
||||
"Result", ModuleId::RESULT
|
||||
"List", ModuleId::LIST
|
||||
"Str", ModuleId::STR
|
||||
"Dict", ModuleId::DICT
|
||||
"Set", ModuleId::SET
|
||||
"Num", ModuleId::NUM
|
||||
"Bool", ModuleId::BOOL
|
||||
"Box", ModuleId::BOX
|
||||
"Encode", ModuleId::ENCODE
|
||||
}
|
||||
|
||||
let (filename, opt_shorthand) = module_name_to_path(src_dir, module_name, arc_shorthands);
|
||||
|
@ -3569,6 +3528,7 @@ impl<'a> BuildTask<'a> {
|
|||
|
||||
fn add_imports(
|
||||
subs: &mut Subs,
|
||||
abilities_store: &mut AbilitiesStore,
|
||||
mut exposed_for_module: ExposedForModule,
|
||||
def_types: &mut Vec<(Symbol, Loc<roc_types::types::Type>)>,
|
||||
rigid_vars: &mut Vec<Variable>,
|
||||
|
@ -3610,6 +3570,10 @@ fn add_imports(
|
|||
rigid_vars.extend(copied_import.flex_able);
|
||||
|
||||
import_variables.extend(copied_import.registered);
|
||||
|
||||
if abilities_store.is_ability_member_name(symbol) {
|
||||
abilities_store.resolved_imported_member_var(symbol, copied_import.variable);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
internal_error!("Imported module {:?} is not available", module_id)
|
||||
|
@ -3638,7 +3602,7 @@ fn run_solve_solve(
|
|||
exposed_symbols,
|
||||
aliases,
|
||||
rigid_variables,
|
||||
abilities_store,
|
||||
mut abilities_store,
|
||||
..
|
||||
} = module;
|
||||
|
||||
|
@ -3649,6 +3613,7 @@ fn run_solve_solve(
|
|||
|
||||
let import_variables = add_imports(
|
||||
&mut subs,
|
||||
&mut abilities_store,
|
||||
exposed_for_module,
|
||||
&mut def_types,
|
||||
&mut rigid_vars,
|
||||
|
@ -3835,6 +3800,7 @@ fn canonicalize_and_constrain<'a>(
|
|||
dep_idents: IdentIdsByModule,
|
||||
exposed_symbols: VecSet<Symbol>,
|
||||
aliases: MutMap<Symbol, Alias>,
|
||||
imported_abilities_state: AbilitiesStore,
|
||||
parsed: ParsedModule<'a>,
|
||||
skip_constraint_gen: bool,
|
||||
) -> CanAndCon {
|
||||
|
@ -3866,6 +3832,7 @@ fn canonicalize_and_constrain<'a>(
|
|||
exposed_ident_ids,
|
||||
&dep_idents,
|
||||
aliases,
|
||||
imported_abilities_state,
|
||||
exposed_imports,
|
||||
&exposed_symbols,
|
||||
&symbols_from_requires,
|
||||
|
@ -3944,7 +3911,7 @@ fn canonicalize_and_constrain<'a>(
|
|||
// do nothing
|
||||
}
|
||||
Vacant(vacant) => {
|
||||
if !name.is_builtin() {
|
||||
if !name.is_builtin() || name.module_id() == ModuleId::ENCODE {
|
||||
vacant.insert((false, alias));
|
||||
}
|
||||
}
|
||||
|
@ -4438,6 +4405,7 @@ fn run_task<'a>(
|
|||
dep_idents,
|
||||
exposed_symbols,
|
||||
aliases,
|
||||
abilities_store,
|
||||
skip_constraint_gen,
|
||||
} => {
|
||||
let can_and_con = canonicalize_and_constrain(
|
||||
|
@ -4446,6 +4414,7 @@ fn run_task<'a>(
|
|||
dep_idents,
|
||||
exposed_symbols,
|
||||
aliases,
|
||||
abilities_store,
|
||||
parsed,
|
||||
skip_constraint_gen,
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue