mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Save ability specializations
Unfortunately not enough...
This commit is contained in:
parent
f8cf18b10e
commit
3f4336d15a
2 changed files with 55 additions and 18 deletions
|
@ -136,6 +136,7 @@ struct ModuleCache<'a> {
|
||||||
/// Various information
|
/// Various information
|
||||||
imports: MutMap<ModuleId, MutSet<ModuleId>>,
|
imports: MutMap<ModuleId, MutSet<ModuleId>>,
|
||||||
top_level_thunks: MutMap<ModuleId, MutSet<Symbol>>,
|
top_level_thunks: MutMap<ModuleId, MutSet<Symbol>>,
|
||||||
|
ability_specializations: MutMap<ModuleId, VecMap<Symbol, PartialProc<'a>>>,
|
||||||
documentation: MutMap<ModuleId, ModuleDocumentation>,
|
documentation: MutMap<ModuleId, ModuleDocumentation>,
|
||||||
can_problems: MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
|
can_problems: MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
|
||||||
type_problems: MutMap<ModuleId, Vec<solve::TypeError>>,
|
type_problems: MutMap<ModuleId, Vec<solve::TypeError>>,
|
||||||
|
@ -181,6 +182,7 @@ impl Default for ModuleCache<'_> {
|
||||||
external_specializations_requested: Default::default(),
|
external_specializations_requested: Default::default(),
|
||||||
imports: Default::default(),
|
imports: Default::default(),
|
||||||
top_level_thunks: Default::default(),
|
top_level_thunks: Default::default(),
|
||||||
|
ability_specializations: Default::default(),
|
||||||
documentation: Default::default(),
|
documentation: Default::default(),
|
||||||
can_problems: Default::default(),
|
can_problems: Default::default(),
|
||||||
type_problems: Default::default(),
|
type_problems: Default::default(),
|
||||||
|
@ -437,7 +439,7 @@ fn start_phase<'a>(
|
||||||
module_id,
|
module_id,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
subs,
|
subs,
|
||||||
procs_base,
|
mut procs_base,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
module_timing,
|
module_timing,
|
||||||
mut abilities_store,
|
mut abilities_store,
|
||||||
|
@ -463,6 +465,13 @@ fn start_phase<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (_, ability_specializations) in
|
||||||
|
state.module_cache.ability_specializations.iter()
|
||||||
|
{
|
||||||
|
procs_base
|
||||||
|
.partial_procs
|
||||||
|
.extend(ability_specializations.iter().map(|(s, p)| (*s, p.clone())));
|
||||||
|
}
|
||||||
|
|
||||||
BuildTask::MakeSpecializations {
|
BuildTask::MakeSpecializations {
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -2208,6 +2217,30 @@ fn update<'a>(
|
||||||
.or_default()
|
.or_default()
|
||||||
.extend(procs_base.module_thunks.iter().copied());
|
.extend(procs_base.module_thunks.iter().copied());
|
||||||
|
|
||||||
|
let ability_specialization_procs: VecMap<_, _> = state
|
||||||
|
.exposed_types
|
||||||
|
.get(&module_id)
|
||||||
|
.expect("Module solved, but no exposed types")
|
||||||
|
.solved_specializations
|
||||||
|
.iter()
|
||||||
|
.map(|(_, specialization)| {
|
||||||
|
(
|
||||||
|
specialization.symbol,
|
||||||
|
procs_base
|
||||||
|
.partial_procs
|
||||||
|
.get(&specialization.symbol)
|
||||||
|
.expect("Specialization known, but not exposed")
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let old = state
|
||||||
|
.module_cache
|
||||||
|
.ability_specializations
|
||||||
|
.insert(module_id, ability_specialization_procs);
|
||||||
|
debug_assert!(old.is_none(), "Found specializations for module twice");
|
||||||
|
|
||||||
let found_specializations_module = FoundSpecializationsModule {
|
let found_specializations_module = FoundSpecializationsModule {
|
||||||
module_id,
|
module_id,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
|
|
@ -2850,25 +2850,29 @@ fn resolve_abilities_in_specialized_body<'a>(
|
||||||
// since `var` may only have partial specialization information - enough to
|
// since `var` may only have partial specialization information - enough to
|
||||||
// figure out what specialization we need, but not the types of all arguments
|
// figure out what specialization we need, but not the types of all arguments
|
||||||
// and return types. So, unify with the variable with the specialization's type.
|
// and return types. So, unify with the variable with the specialization's type.
|
||||||
let specialization_def = if !self.env.is_imported_symbol(specialization)
|
// let specialization_def = if !self.env.is_imported_symbol(specialization)
|
||||||
{
|
// {
|
||||||
let specialization_def = self
|
let specialization_def = self
|
||||||
.procs
|
.procs
|
||||||
.partial_procs
|
.partial_procs
|
||||||
.get_symbol(specialization)
|
.get_symbol(specialization)
|
||||||
.expect("Specialization found, but it's not in procs");
|
.unwrap_or_else(|| {
|
||||||
let specialization_var = specialization_def.annotation;
|
internal_error!(
|
||||||
|
"Specialization for {:?} found, but it's not in procs",
|
||||||
|
specialization
|
||||||
|
)
|
||||||
|
});
|
||||||
|
let specialization_var = specialization_def.annotation;
|
||||||
|
|
||||||
let unified =
|
let unified = unify(self.env.subs, var, specialization_var, Mode::EQ);
|
||||||
unify(self.env.subs, var, specialization_var, Mode::EQ);
|
unified.expect_success(
|
||||||
unified.expect_success(
|
"Specialization does not unify - this is a typechecker bug!",
|
||||||
"Specialization does not unify - this is a typechecker bug!",
|
);
|
||||||
);
|
|
||||||
|
|
||||||
Some(specialization_def)
|
let specialization_def = Some(specialization_def);
|
||||||
} else {
|
// } else {
|
||||||
None
|
// None
|
||||||
};
|
// };
|
||||||
|
|
||||||
(specialization, specialization_def)
|
(specialization, specialization_def)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue