diff --git a/compiler/load_internal/src/file.rs b/compiler/load_internal/src/file.rs index e41009511d..a920c4b707 100644 --- a/compiler/load_internal/src/file.rs +++ b/compiler/load_internal/src/file.rs @@ -136,6 +136,7 @@ struct ModuleCache<'a> { /// Various information imports: MutMap>, top_level_thunks: MutMap>, + ability_specializations: MutMap>>, documentation: MutMap, can_problems: MutMap>, type_problems: MutMap>, @@ -181,6 +182,7 @@ impl Default for ModuleCache<'_> { external_specializations_requested: Default::default(), imports: Default::default(), top_level_thunks: Default::default(), + ability_specializations: Default::default(), documentation: Default::default(), can_problems: Default::default(), type_problems: Default::default(), @@ -437,7 +439,7 @@ fn start_phase<'a>( module_id, ident_ids, subs, - procs_base, + mut procs_base, layout_cache, module_timing, 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 { module_id, @@ -2208,6 +2217,30 @@ fn update<'a>( .or_default() .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 { module_id, ident_ids, diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 7648ac8562..e5d164e449 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -2850,25 +2850,29 @@ fn resolve_abilities_in_specialized_body<'a>( // since `var` may only have partial specialization information - enough to // 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. - let specialization_def = if !self.env.is_imported_symbol(specialization) - { - let specialization_def = self - .procs - .partial_procs - .get_symbol(specialization) - .expect("Specialization found, but it's not in procs"); - let specialization_var = specialization_def.annotation; + // let specialization_def = if !self.env.is_imported_symbol(specialization) + // { + let specialization_def = self + .procs + .partial_procs + .get_symbol(specialization) + .unwrap_or_else(|| { + internal_error!( + "Specialization for {:?} found, but it's not in procs", + specialization + ) + }); + let specialization_var = specialization_def.annotation; - let unified = - unify(self.env.subs, var, specialization_var, Mode::EQ); - unified.expect_success( - "Specialization does not unify - this is a typechecker bug!", - ); + let unified = unify(self.env.subs, var, specialization_var, Mode::EQ); + unified.expect_success( + "Specialization does not unify - this is a typechecker bug!", + ); - Some(specialization_def) - } else { - None - }; + let specialization_def = Some(specialization_def); + // } else { + // None + // }; (specialization, specialization_def) }