Save ability specializations

Unfortunately not enough...
This commit is contained in:
Ayaz Hafiz 2022-05-18 10:02:11 -04:00
parent f8cf18b10e
commit 3f4336d15a
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 55 additions and 18 deletions

View file

@ -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,

View file

@ -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)
} }