mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-04 00:54:36 +00:00
Thread derived methods map through solve and mono for use in compaction
This commit is contained in:
parent
c9d828c284
commit
a429835da4
11 changed files with 99 additions and 20 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -3869,6 +3869,7 @@ dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
|
"roc_derive_key",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_solve",
|
"roc_solve",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
|
@ -3923,6 +3924,7 @@ dependencies = [
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_constrain",
|
"roc_constrain",
|
||||||
"roc_debug_flags",
|
"roc_debug_flags",
|
||||||
|
"roc_derive_key",
|
||||||
"roc_error_macros",
|
"roc_error_macros",
|
||||||
"roc_late_solve",
|
"roc_late_solve",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
|
@ -4119,6 +4121,7 @@ dependencies = [
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_debug_flags",
|
"roc_debug_flags",
|
||||||
|
"roc_derive_key",
|
||||||
"roc_error_macros",
|
"roc_error_macros",
|
||||||
"roc_exhaustive",
|
"roc_exhaustive",
|
||||||
"roc_load",
|
"roc_load",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
|
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use encoding::{FlatEncodable, FlatEncodableKey};
|
use encoding::{FlatEncodable, FlatEncodableKey};
|
||||||
|
|
||||||
use roc_collections::MutMap;
|
use roc_collections::MutMap;
|
||||||
|
@ -50,19 +52,13 @@ impl Derived {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map of [`DeriveKey`]s to their derived symbols.
|
/// Map of [`DeriveKey`]s to their derived symbols.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
pub struct DerivedMethods {
|
pub struct DerivedMethods {
|
||||||
map: MutMap<DeriveKey, Symbol>,
|
map: MutMap<DeriveKey, Symbol>,
|
||||||
derived_ident_ids: IdentIds,
|
derived_ident_ids: IdentIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerivedMethods {
|
impl DerivedMethods {
|
||||||
pub fn new(derived_ident_ids: IdentIds) -> Self {
|
|
||||||
Self {
|
|
||||||
map: MutMap::default(),
|
|
||||||
derived_ident_ids,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_or_insert(&mut self, key: DeriveKey) -> Symbol {
|
pub fn get_or_insert(&mut self, key: DeriveKey) -> Symbol {
|
||||||
let symbol = self.map.entry(key).or_insert_with(|| {
|
let symbol = self.map.entry(key).or_insert_with(|| {
|
||||||
let ident_id = self.derived_ident_ids.gen_unique();
|
let ident_id = self.derived_ident_ids.gen_unique();
|
||||||
|
@ -72,3 +68,6 @@ impl DerivedMethods {
|
||||||
*symbol
|
*symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Thread-sharable [`DerivedMethods`].
|
||||||
|
pub type GlobalDerivedMethods = Arc<RwLock<DerivedMethods>>;
|
||||||
|
|
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
roc_types = { path = "../types" }
|
roc_types = { path = "../types" }
|
||||||
roc_can = { path = "../can" }
|
roc_can = { path = "../can" }
|
||||||
|
roc_derive_key = { path = "../derive_key" }
|
||||||
roc_module = { path = "../module" }
|
roc_module = { path = "../module" }
|
||||||
roc_unify = { path = "../unify" }
|
roc_unify = { path = "../unify" }
|
||||||
roc_solve = { path = "../solve" }
|
roc_solve = { path = "../solve" }
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::sync::{Arc, RwLock};
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use roc_can::abilities::AbilitiesStore;
|
use roc_can::abilities::AbilitiesStore;
|
||||||
use roc_collections::MutMap;
|
use roc_collections::MutMap;
|
||||||
|
use roc_derive_key::GlobalDerivedMethods;
|
||||||
use roc_module::symbol::ModuleId;
|
use roc_module::symbol::ModuleId;
|
||||||
use roc_solve::solve::{compact_lambda_sets_of_vars, Phase, Pools};
|
use roc_solve::solve::{compact_lambda_sets_of_vars, Phase, Pools};
|
||||||
use roc_types::subs::Content;
|
use roc_types::subs::Content;
|
||||||
|
@ -136,6 +137,7 @@ pub fn unify(
|
||||||
arena: &Bump,
|
arena: &Bump,
|
||||||
subs: &mut Subs,
|
subs: &mut Subs,
|
||||||
abilities: &AbilitiesView,
|
abilities: &AbilitiesView,
|
||||||
|
derived_methods: &GlobalDerivedMethods,
|
||||||
left: Variable,
|
left: Variable,
|
||||||
right: Variable,
|
right: Variable,
|
||||||
) -> Result<(), UnificationFailed> {
|
) -> Result<(), UnificationFailed> {
|
||||||
|
@ -157,6 +159,7 @@ pub fn unify(
|
||||||
&mut pools,
|
&mut pools,
|
||||||
lambda_sets_to_specialize,
|
lambda_sets_to_specialize,
|
||||||
&late_phase,
|
&late_phase,
|
||||||
|
derived_methods,
|
||||||
);
|
);
|
||||||
// Pools are only used to keep track of variable ranks for generalization purposes.
|
// Pools are only used to keep track of variable ranks for generalization purposes.
|
||||||
// Since we break generalization during monomorphization, `pools` is irrelevant
|
// Since we break generalization during monomorphization, `pools` is irrelevant
|
||||||
|
|
|
@ -13,6 +13,7 @@ roc_module = { path = "../module" }
|
||||||
roc_types = { path = "../types" }
|
roc_types = { path = "../types" }
|
||||||
roc_can = { path = "../can" }
|
roc_can = { path = "../can" }
|
||||||
roc_constrain = { path = "../constrain" }
|
roc_constrain = { path = "../constrain" }
|
||||||
|
roc_derive_key = { path = "../derive_key" }
|
||||||
roc_builtins = { path = "../builtins" }
|
roc_builtins = { path = "../builtins" }
|
||||||
roc_problem = { path = "../problem" }
|
roc_problem = { path = "../problem" }
|
||||||
roc_unify = { path = "../unify" }
|
roc_unify = { path = "../unify" }
|
||||||
|
|
|
@ -22,6 +22,7 @@ use roc_debug_flags::{
|
||||||
ROC_PRINT_IR_AFTER_REFCOUNT, ROC_PRINT_IR_AFTER_RESET_REUSE, ROC_PRINT_IR_AFTER_SPECIALIZATION,
|
ROC_PRINT_IR_AFTER_REFCOUNT, ROC_PRINT_IR_AFTER_RESET_REUSE, ROC_PRINT_IR_AFTER_SPECIALIZATION,
|
||||||
ROC_PRINT_LOAD_LOG,
|
ROC_PRINT_LOAD_LOG,
|
||||||
};
|
};
|
||||||
|
use roc_derive_key::GlobalDerivedMethods;
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
use roc_late_solve::{AbilitiesView, WorldAbilities};
|
use roc_late_solve::{AbilitiesView, WorldAbilities};
|
||||||
use roc_module::ident::{Ident, ModuleName, QualifiedModuleName};
|
use roc_module::ident::{Ident, ModuleName, QualifiedModuleName};
|
||||||
|
@ -372,6 +373,8 @@ fn start_phase<'a>(
|
||||||
..
|
..
|
||||||
} = constrained;
|
} = constrained;
|
||||||
|
|
||||||
|
let derived_methods = GlobalDerivedMethods::clone(&state.derived_methods);
|
||||||
|
|
||||||
BuildTask::solve_module(
|
BuildTask::solve_module(
|
||||||
module,
|
module,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
@ -385,6 +388,7 @@ fn start_phase<'a>(
|
||||||
dep_idents,
|
dep_idents,
|
||||||
declarations,
|
declarations,
|
||||||
state.cached_subs.clone(),
|
state.cached_subs.clone(),
|
||||||
|
derived_methods,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Phase::FindSpecializations => {
|
Phase::FindSpecializations => {
|
||||||
|
@ -412,6 +416,8 @@ fn start_phase<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let derived_methods = GlobalDerivedMethods::clone(&state.derived_methods);
|
||||||
|
|
||||||
BuildTask::BuildPendingSpecializations {
|
BuildTask::BuildPendingSpecializations {
|
||||||
layout_cache,
|
layout_cache,
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -422,6 +428,7 @@ fn start_phase<'a>(
|
||||||
ident_ids,
|
ident_ids,
|
||||||
exposed_to_host: state.exposed_to_host.clone(),
|
exposed_to_host: state.exposed_to_host.clone(),
|
||||||
abilities_store,
|
abilities_store,
|
||||||
|
derived_methods,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Phase::MakeSpecializations => {
|
Phase::MakeSpecializations => {
|
||||||
|
@ -479,6 +486,8 @@ fn start_phase<'a>(
|
||||||
(ident_ids, subs, procs_base, layout_cache, module_timing)
|
(ident_ids, subs, procs_base, layout_cache, module_timing)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let derived_methods = GlobalDerivedMethods::clone(&state.derived_methods);
|
||||||
|
|
||||||
BuildTask::MakeSpecializations {
|
BuildTask::MakeSpecializations {
|
||||||
module_id,
|
module_id,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
@ -488,6 +497,7 @@ fn start_phase<'a>(
|
||||||
specializations_we_must_make,
|
specializations_we_must_make,
|
||||||
module_timing,
|
module_timing,
|
||||||
world_abilities: state.world_abilities.clone_ref(),
|
world_abilities: state.world_abilities.clone_ref(),
|
||||||
|
derived_methods,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -795,6 +805,8 @@ struct State<'a> {
|
||||||
/// From now on, these will be used by multiple threads; time to make an Arc<Mutex<_>>!
|
/// From now on, these will be used by multiple threads; time to make an Arc<Mutex<_>>!
|
||||||
pub arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
|
pub arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
|
||||||
pub arc_shorthands: Arc<Mutex<MutMap<&'a str, PackageName<'a>>>>,
|
pub arc_shorthands: Arc<Mutex<MutMap<&'a str, PackageName<'a>>>>,
|
||||||
|
#[allow(unused)]
|
||||||
|
pub derived_methods: GlobalDerivedMethods,
|
||||||
|
|
||||||
pub ident_ids_by_module: SharedIdentIdsByModule,
|
pub ident_ids_by_module: SharedIdentIdsByModule,
|
||||||
|
|
||||||
|
@ -854,6 +866,7 @@ impl<'a> State<'a> {
|
||||||
exposed_types,
|
exposed_types,
|
||||||
arc_modules,
|
arc_modules,
|
||||||
arc_shorthands,
|
arc_shorthands,
|
||||||
|
derived_methods: Default::default(),
|
||||||
constrained_ident_ids: IdentIds::exposed_builtins(0),
|
constrained_ident_ids: IdentIds::exposed_builtins(0),
|
||||||
ident_ids_by_module,
|
ident_ids_by_module,
|
||||||
declarations_by_id: MutMap::default(),
|
declarations_by_id: MutMap::default(),
|
||||||
|
@ -973,6 +986,7 @@ enum BuildTask<'a> {
|
||||||
declarations: Vec<Declaration>,
|
declarations: Vec<Declaration>,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: IdentIdsByModule,
|
||||||
cached_subs: CachedSubs,
|
cached_subs: CachedSubs,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
},
|
},
|
||||||
BuildPendingSpecializations {
|
BuildPendingSpecializations {
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
|
@ -984,6 +998,7 @@ enum BuildTask<'a> {
|
||||||
decls: Vec<Declaration>,
|
decls: Vec<Declaration>,
|
||||||
exposed_to_host: ExposedToHost,
|
exposed_to_host: ExposedToHost,
|
||||||
abilities_store: AbilitiesStore,
|
abilities_store: AbilitiesStore,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
},
|
},
|
||||||
MakeSpecializations {
|
MakeSpecializations {
|
||||||
module_id: ModuleId,
|
module_id: ModuleId,
|
||||||
|
@ -994,6 +1009,7 @@ enum BuildTask<'a> {
|
||||||
specializations_we_must_make: Vec<ExternalSpecializations>,
|
specializations_we_must_make: Vec<ExternalSpecializations>,
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
world_abilities: WorldAbilities,
|
world_abilities: WorldAbilities,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3719,6 +3735,7 @@ impl<'a> BuildTask<'a> {
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: IdentIdsByModule,
|
||||||
declarations: Vec<Declaration>,
|
declarations: Vec<Declaration>,
|
||||||
cached_subs: CachedSubs,
|
cached_subs: CachedSubs,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let exposed_by_module = exposed_types.retain_modules(imported_modules.keys());
|
let exposed_by_module = exposed_types.retain_modules(imported_modules.keys());
|
||||||
|
|
||||||
|
@ -3746,6 +3763,7 @@ impl<'a> BuildTask<'a> {
|
||||||
dep_idents,
|
dep_idents,
|
||||||
module_timing,
|
module_timing,
|
||||||
cached_subs,
|
cached_subs,
|
||||||
|
derived_methods,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3876,6 +3894,7 @@ fn run_solve_solve(
|
||||||
pending_derives: PendingDerives,
|
pending_derives: PendingDerives,
|
||||||
mut var_store: VarStore,
|
mut var_store: VarStore,
|
||||||
module: Module,
|
module: Module,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> (
|
) -> (
|
||||||
Solved<Subs>,
|
Solved<Subs>,
|
||||||
ResolvedSpecializations,
|
ResolvedSpecializations,
|
||||||
|
@ -3923,6 +3942,7 @@ fn run_solve_solve(
|
||||||
solve_aliases,
|
solve_aliases,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
pending_derives,
|
pending_derives,
|
||||||
|
derived_methods,
|
||||||
);
|
);
|
||||||
|
|
||||||
let module_id = module.module_id;
|
let module_id = module.module_id;
|
||||||
|
@ -3979,6 +3999,7 @@ fn run_solve<'a>(
|
||||||
decls: Vec<Declaration>,
|
decls: Vec<Declaration>,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: IdentIdsByModule,
|
||||||
cached_subs: CachedSubs,
|
cached_subs: CachedSubs,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> Msg<'a> {
|
) -> Msg<'a> {
|
||||||
let solve_start = SystemTime::now();
|
let solve_start = SystemTime::now();
|
||||||
|
|
||||||
|
@ -3998,6 +4019,7 @@ fn run_solve<'a>(
|
||||||
pending_derives,
|
pending_derives,
|
||||||
var_store,
|
var_store,
|
||||||
module,
|
module,
|
||||||
|
derived_methods,
|
||||||
),
|
),
|
||||||
Some((subs, exposed_vars_by_symbol)) => {
|
Some((subs, exposed_vars_by_symbol)) => {
|
||||||
(
|
(
|
||||||
|
@ -4020,6 +4042,7 @@ fn run_solve<'a>(
|
||||||
pending_derives,
|
pending_derives,
|
||||||
var_store,
|
var_store,
|
||||||
module,
|
module,
|
||||||
|
derived_methods,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4375,6 +4398,7 @@ fn make_specializations<'a>(
|
||||||
mut module_timing: ModuleTiming,
|
mut module_timing: ModuleTiming,
|
||||||
target_info: TargetInfo,
|
target_info: TargetInfo,
|
||||||
world_abilities: WorldAbilities,
|
world_abilities: WorldAbilities,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> Msg<'a> {
|
) -> Msg<'a> {
|
||||||
let make_specializations_start = SystemTime::now();
|
let make_specializations_start = SystemTime::now();
|
||||||
let mut update_mode_ids = UpdateModeIds::new();
|
let mut update_mode_ids = UpdateModeIds::new();
|
||||||
|
@ -4389,6 +4413,7 @@ fn make_specializations<'a>(
|
||||||
// call_specialization_counter=0 is reserved
|
// call_specialization_counter=0 is reserved
|
||||||
call_specialization_counter: 1,
|
call_specialization_counter: 1,
|
||||||
abilities: AbilitiesView::World(world_abilities),
|
abilities: AbilitiesView::World(world_abilities),
|
||||||
|
derived_methods: &derived_methods,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut procs = Procs::new_in(arena);
|
let mut procs = Procs::new_in(arena);
|
||||||
|
@ -4449,9 +4474,9 @@ fn build_pending_specializations<'a>(
|
||||||
mut module_timing: ModuleTiming,
|
mut module_timing: ModuleTiming,
|
||||||
mut layout_cache: LayoutCache<'a>,
|
mut layout_cache: LayoutCache<'a>,
|
||||||
target_info: TargetInfo,
|
target_info: TargetInfo,
|
||||||
// TODO remove
|
exposed_to_host: ExposedToHost, // TODO remove
|
||||||
exposed_to_host: ExposedToHost,
|
|
||||||
abilities_store: AbilitiesStore,
|
abilities_store: AbilitiesStore,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> Msg<'a> {
|
) -> Msg<'a> {
|
||||||
let find_specializations_start = SystemTime::now();
|
let find_specializations_start = SystemTime::now();
|
||||||
|
|
||||||
|
@ -4480,6 +4505,7 @@ fn build_pending_specializations<'a>(
|
||||||
// to know the types and abilities in our modules. Only for building *all* specializations
|
// to know the types and abilities in our modules. Only for building *all* specializations
|
||||||
// do we need a global view.
|
// do we need a global view.
|
||||||
abilities: AbilitiesView::Module(&abilities_store),
|
abilities: AbilitiesView::Module(&abilities_store),
|
||||||
|
derived_methods: &derived_methods,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add modules' decls to Procs
|
// Add modules' decls to Procs
|
||||||
|
@ -4747,6 +4773,7 @@ fn run_task<'a>(
|
||||||
declarations,
|
declarations,
|
||||||
dep_idents,
|
dep_idents,
|
||||||
cached_subs,
|
cached_subs,
|
||||||
|
derived_methods,
|
||||||
} => Ok(run_solve(
|
} => Ok(run_solve(
|
||||||
module,
|
module,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
@ -4760,6 +4787,7 @@ fn run_task<'a>(
|
||||||
declarations,
|
declarations,
|
||||||
dep_idents,
|
dep_idents,
|
||||||
cached_subs,
|
cached_subs,
|
||||||
|
derived_methods,
|
||||||
)),
|
)),
|
||||||
BuildPendingSpecializations {
|
BuildPendingSpecializations {
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -4771,6 +4799,7 @@ fn run_task<'a>(
|
||||||
imported_module_thunks,
|
imported_module_thunks,
|
||||||
exposed_to_host,
|
exposed_to_host,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
|
derived_methods,
|
||||||
} => Ok(build_pending_specializations(
|
} => Ok(build_pending_specializations(
|
||||||
arena,
|
arena,
|
||||||
solved_subs,
|
solved_subs,
|
||||||
|
@ -4783,6 +4812,7 @@ fn run_task<'a>(
|
||||||
target_info,
|
target_info,
|
||||||
exposed_to_host,
|
exposed_to_host,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
|
derived_methods,
|
||||||
)),
|
)),
|
||||||
MakeSpecializations {
|
MakeSpecializations {
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -4793,6 +4823,7 @@ fn run_task<'a>(
|
||||||
specializations_we_must_make,
|
specializations_we_must_make,
|
||||||
module_timing,
|
module_timing,
|
||||||
world_abilities,
|
world_abilities,
|
||||||
|
derived_methods,
|
||||||
} => Ok(make_specializations(
|
} => Ok(make_specializations(
|
||||||
arena,
|
arena,
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -4804,6 +4835,7 @@ fn run_task<'a>(
|
||||||
module_timing,
|
module_timing,
|
||||||
target_info,
|
target_info,
|
||||||
world_abilities,
|
world_abilities,
|
||||||
|
derived_methods,
|
||||||
)),
|
)),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ use roc_can::expr::{AnnotatedMark, ClosureData, Expr, Field, Recursive, WhenBran
|
||||||
use roc_can::pattern::Pattern;
|
use roc_can::pattern::Pattern;
|
||||||
use roc_collections::SendMap;
|
use roc_collections::SendMap;
|
||||||
use roc_derive_key::encoding::FlatEncodableKey;
|
use roc_derive_key::encoding::FlatEncodableKey;
|
||||||
|
use roc_derive_key::GlobalDerivedMethods;
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
use roc_late_solve::{instantiate_rigids, AbilitiesView};
|
use roc_late_solve::{instantiate_rigids, AbilitiesView};
|
||||||
use roc_module::called_via::CalledVia;
|
use roc_module::called_via::CalledVia;
|
||||||
|
@ -43,6 +44,7 @@ pub struct Env<'a> {
|
||||||
pub subs: &'a mut Subs,
|
pub subs: &'a mut Subs,
|
||||||
pub ident_ids: &'a mut IdentIds,
|
pub ident_ids: &'a mut IdentIds,
|
||||||
pub exposed_encode_types: &'a mut ExposedTypesStorageSubs,
|
pub exposed_encode_types: &'a mut ExposedTypesStorageSubs,
|
||||||
|
pub derived_methods: &'a GlobalDerivedMethods,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Env<'_> {
|
impl Env<'_> {
|
||||||
|
@ -78,6 +80,7 @@ impl Env<'_> {
|
||||||
self.arena,
|
self.arena,
|
||||||
self.subs,
|
self.subs,
|
||||||
&AbilitiesView::Module(&AbilitiesStore::default()),
|
&AbilitiesView::Module(&AbilitiesStore::default()),
|
||||||
|
self.derived_methods,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,6 +16,7 @@ use roc_debug_flags::dbg_do;
|
||||||
use roc_debug_flags::{
|
use roc_debug_flags::{
|
||||||
ROC_PRINT_IR_AFTER_REFCOUNT, ROC_PRINT_IR_AFTER_RESET_REUSE, ROC_PRINT_IR_AFTER_SPECIALIZATION,
|
ROC_PRINT_IR_AFTER_REFCOUNT, ROC_PRINT_IR_AFTER_RESET_REUSE, ROC_PRINT_IR_AFTER_SPECIALIZATION,
|
||||||
};
|
};
|
||||||
|
use roc_derive_key::GlobalDerivedMethods;
|
||||||
use roc_error_macros::todo_abilities;
|
use roc_error_macros::todo_abilities;
|
||||||
use roc_exhaustive::{Ctor, CtorName, Guard, RenderAs, TagId};
|
use roc_exhaustive::{Ctor, CtorName, Guard, RenderAs, TagId};
|
||||||
use roc_late_solve::{
|
use roc_late_solve::{
|
||||||
|
@ -1269,6 +1270,7 @@ pub struct Env<'a, 'i> {
|
||||||
pub update_mode_ids: &'i mut UpdateModeIds,
|
pub update_mode_ids: &'i mut UpdateModeIds,
|
||||||
pub call_specialization_counter: u32,
|
pub call_specialization_counter: u32,
|
||||||
pub abilities: AbilitiesView<'i>,
|
pub abilities: AbilitiesView<'i>,
|
||||||
|
pub derived_methods: &'i GlobalDerivedMethods,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'i> Env<'a, 'i> {
|
impl<'a, 'i> Env<'a, 'i> {
|
||||||
|
@ -1304,6 +1306,7 @@ impl<'a, 'i> Env<'a, 'i> {
|
||||||
self.arena,
|
self.arena,
|
||||||
self.subs,
|
self.subs,
|
||||||
&self.abilities,
|
&self.abilities,
|
||||||
|
self.derived_methods,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,6 +13,7 @@ roc_region = { path = "../region" }
|
||||||
roc_module = { path = "../module" }
|
roc_module = { path = "../module" }
|
||||||
roc_types = { path = "../types" }
|
roc_types = { path = "../types" }
|
||||||
roc_can = { path = "../can" }
|
roc_can = { path = "../can" }
|
||||||
|
roc_derive_key = { path = "../derive_key" }
|
||||||
roc_problem = { path = "../problem" }
|
roc_problem = { path = "../problem" }
|
||||||
roc_unify = { path = "../unify" }
|
roc_unify = { path = "../unify" }
|
||||||
roc_debug_flags = { path = "../debug_flags" }
|
roc_debug_flags = { path = "../debug_flags" }
|
||||||
|
|
|
@ -5,6 +5,7 @@ use roc_can::expr::PendingDerives;
|
||||||
use roc_can::module::RigidVariables;
|
use roc_can::module::RigidVariables;
|
||||||
use roc_collections::all::MutMap;
|
use roc_collections::all::MutMap;
|
||||||
use roc_collections::VecMap;
|
use roc_collections::VecMap;
|
||||||
|
use roc_derive_key::GlobalDerivedMethods;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_types::solved_types::Solved;
|
use roc_types::solved_types::Solved;
|
||||||
use roc_types::subs::{ExposedTypesStorageSubs, StorageSubs, Subs, Variable};
|
use roc_types::subs::{ExposedTypesStorageSubs, StorageSubs, Subs, Variable};
|
||||||
|
@ -40,6 +41,7 @@ pub fn run_solve(
|
||||||
mut aliases: Aliases,
|
mut aliases: Aliases,
|
||||||
mut abilities_store: AbilitiesStore,
|
mut abilities_store: AbilitiesStore,
|
||||||
pending_derives: PendingDerives,
|
pending_derives: PendingDerives,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> (
|
) -> (
|
||||||
Solved<Subs>,
|
Solved<Subs>,
|
||||||
solve::Env,
|
solve::Env,
|
||||||
|
@ -71,6 +73,7 @@ pub fn run_solve(
|
||||||
&constraint,
|
&constraint,
|
||||||
pending_derives,
|
pending_derives,
|
||||||
&mut abilities_store,
|
&mut abilities_store,
|
||||||
|
derived_methods,
|
||||||
);
|
);
|
||||||
|
|
||||||
(solved_subs, solved_env, problems, abilities_store)
|
(solved_subs, solved_env, problems, abilities_store)
|
||||||
|
|
|
@ -13,6 +13,7 @@ use roc_collections::VecSet;
|
||||||
use roc_debug_flags::dbg_do;
|
use roc_debug_flags::dbg_do;
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
use roc_debug_flags::ROC_VERIFY_RIGID_LET_GENERALIZED;
|
use roc_debug_flags::ROC_VERIFY_RIGID_LET_GENERALIZED;
|
||||||
|
use roc_derive_key::{Derived, GlobalDerivedMethods};
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
use roc_module::ident::TagName;
|
use roc_module::ident::TagName;
|
||||||
use roc_module::symbol::{ModuleId, Symbol};
|
use roc_module::symbol::{ModuleId, Symbol};
|
||||||
|
@ -550,6 +551,7 @@ pub fn run(
|
||||||
constraint: &Constraint,
|
constraint: &Constraint,
|
||||||
pending_derives: PendingDerives,
|
pending_derives: PendingDerives,
|
||||||
abilities_store: &mut AbilitiesStore,
|
abilities_store: &mut AbilitiesStore,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> (Solved<Subs>, Env) {
|
) -> (Solved<Subs>, Env) {
|
||||||
let env = run_in_place(
|
let env = run_in_place(
|
||||||
constraints,
|
constraints,
|
||||||
|
@ -559,6 +561,7 @@ pub fn run(
|
||||||
constraint,
|
constraint,
|
||||||
pending_derives,
|
pending_derives,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
|
derived_methods,
|
||||||
);
|
);
|
||||||
|
|
||||||
(Solved(subs), env)
|
(Solved(subs), env)
|
||||||
|
@ -573,6 +576,7 @@ fn run_in_place(
|
||||||
constraint: &Constraint,
|
constraint: &Constraint,
|
||||||
pending_derives: PendingDerives,
|
pending_derives: PendingDerives,
|
||||||
abilities_store: &mut AbilitiesStore,
|
abilities_store: &mut AbilitiesStore,
|
||||||
|
derived_methods: GlobalDerivedMethods,
|
||||||
) -> Env {
|
) -> Env {
|
||||||
let mut pools = Pools::default();
|
let mut pools = Pools::default();
|
||||||
|
|
||||||
|
@ -617,6 +621,7 @@ fn run_in_place(
|
||||||
&mut pools,
|
&mut pools,
|
||||||
deferred_uls_to_resolve,
|
deferred_uls_to_resolve,
|
||||||
&SolvePhase { abilities_store },
|
&SolvePhase { abilities_store },
|
||||||
|
&derived_methods,
|
||||||
);
|
);
|
||||||
|
|
||||||
state.env
|
state.env
|
||||||
|
@ -1748,6 +1753,7 @@ pub fn compact_lambda_sets_of_vars<P: Phase>(
|
||||||
pools: &mut Pools,
|
pools: &mut Pools,
|
||||||
uls_of_var: UlsOfVar,
|
uls_of_var: UlsOfVar,
|
||||||
phase: &P,
|
phase: &P,
|
||||||
|
derived_methods: &GlobalDerivedMethods,
|
||||||
) {
|
) {
|
||||||
let mut seen = VecSet::default();
|
let mut seen = VecSet::default();
|
||||||
for (_, lambda_sets) in uls_of_var.drain() {
|
for (_, lambda_sets) in uls_of_var.drain() {
|
||||||
|
@ -1757,7 +1763,7 @@ pub fn compact_lambda_sets_of_vars<P: Phase>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
compact_lambda_set(subs, arena, pools, root_lset, phase);
|
compact_lambda_set(subs, arena, pools, root_lset, phase, derived_methods);
|
||||||
|
|
||||||
seen.insert(root_lset);
|
seen.insert(root_lset);
|
||||||
}
|
}
|
||||||
|
@ -1770,6 +1776,7 @@ fn compact_lambda_set<P: Phase>(
|
||||||
pools: &mut Pools,
|
pools: &mut Pools,
|
||||||
this_lambda_set: Variable,
|
this_lambda_set: Variable,
|
||||||
phase: &P,
|
phase: &P,
|
||||||
|
derived_methods: &GlobalDerivedMethods,
|
||||||
) {
|
) {
|
||||||
let LambdaSet {
|
let LambdaSet {
|
||||||
solved,
|
solved,
|
||||||
|
@ -1795,14 +1802,30 @@ fn compact_lambda_set<P: Phase>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Structure(_) | Alias(_, _, _, AliasKind::Structural) => {
|
Structure(_) | Alias(_, _, _, AliasKind::Structural) => {
|
||||||
// TODO: figure out a convention for references to structural types in the
|
// This is a structural type, find the name of the derived ability function it
|
||||||
// unspecialized lambda set. This may very well happen, for example
|
// should use.
|
||||||
//
|
let specialization_symbol = match Derived::encoding(subs, var) {
|
||||||
// Default has default : {} -> a | a has Default
|
Derived::Immediate(symbol) => symbol,
|
||||||
//
|
Derived::Key(derive_key) => {
|
||||||
// {a, b} = default {}
|
let mut derived_methods = derived_methods.write().unwrap();
|
||||||
// # ^^^^^^^ {} -[{a: t1, b: t2}:default:1]-> {a: t1, b: t2}
|
derived_methods.get_or_insert(derive_key)
|
||||||
new_unspecialized.push(uls);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let specialization_symbol_slice =
|
||||||
|
UnionLabels::insert_into_subs(subs, vec![(specialization_symbol, vec![])]);
|
||||||
|
let lambda_set_for_derived = subs.fresh(Descriptor {
|
||||||
|
content: LambdaSet(subs::LambdaSet {
|
||||||
|
solved: specialization_symbol_slice,
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: SubsSlice::default(),
|
||||||
|
}),
|
||||||
|
rank: target_rank,
|
||||||
|
mark: Mark::NONE,
|
||||||
|
copy: OptVariable::NONE,
|
||||||
|
});
|
||||||
|
|
||||||
|
specialized_to_unify_with.push(lambda_set_for_derived);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Alias(opaque, _, _, AliasKind::Opaque) => opaque,
|
Alias(opaque, _, _, AliasKind::Opaque) => opaque,
|
||||||
|
@ -1864,7 +1887,14 @@ fn compact_lambda_set<P: Phase>(
|
||||||
|
|
||||||
// Ensure the specialization lambda set is already compacted.
|
// Ensure the specialization lambda set is already compacted.
|
||||||
if subs.get_root_key(specialized_lambda_set) != subs.get_root_key(this_lambda_set) {
|
if subs.get_root_key(specialized_lambda_set) != subs.get_root_key(this_lambda_set) {
|
||||||
compact_lambda_set(subs, arena, pools, specialized_lambda_set, phase);
|
compact_lambda_set(
|
||||||
|
subs,
|
||||||
|
arena,
|
||||||
|
pools,
|
||||||
|
specialized_lambda_set,
|
||||||
|
phase,
|
||||||
|
derived_methods,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the specialization lambda set we'll unify with is not a generalized one, but one
|
// Ensure the specialization lambda set we'll unify with is not a generalized one, but one
|
||||||
|
@ -1889,7 +1919,7 @@ fn compact_lambda_set<P: Phase>(
|
||||||
unify(subs, this_lambda_set, other_specialized, Mode::EQ)
|
unify(subs, this_lambda_set, other_specialized, Mode::EQ)
|
||||||
.expect_success("lambda sets don't unify");
|
.expect_success("lambda sets don't unify");
|
||||||
|
|
||||||
introduce(subs, subs.get_rank(this_lambda_set), pools, &vars);
|
introduce(subs, target_rank, pools, &vars);
|
||||||
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
must_implement_ability.is_empty(),
|
must_implement_ability.is_empty(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue