mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Remove mono-related changes for now
This commit is contained in:
parent
3f4336d15a
commit
6d19f31574
3 changed files with 33 additions and 120 deletions
|
@ -46,6 +46,7 @@ impl AbilityMemberData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// (member, specialization type) -> specialization
|
||||||
pub type SolvedSpecializations = VecMap<(Symbol, Symbol), MemberSpecialization>;
|
pub type SolvedSpecializations = VecMap<(Symbol, Symbol), MemberSpecialization>;
|
||||||
|
|
||||||
/// A particular specialization of an ability member.
|
/// A particular specialization of an ability member.
|
||||||
|
|
|
@ -136,7 +136,6 @@ 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>>,
|
||||||
|
@ -182,7 +181,6 @@ 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(),
|
||||||
|
@ -439,40 +437,12 @@ fn start_phase<'a>(
|
||||||
module_id,
|
module_id,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
subs,
|
subs,
|
||||||
mut procs_base,
|
procs_base,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
module_timing,
|
module_timing,
|
||||||
mut abilities_store,
|
abilities_store,
|
||||||
} = found_specializations;
|
} = found_specializations;
|
||||||
|
|
||||||
// At this point, we know what specializations our dependents want and what
|
|
||||||
// ability specializations our dependencies have. But we also need to know what
|
|
||||||
// ability specializations our dependents have, because those might be used by the
|
|
||||||
// specializations we've been asked to make.
|
|
||||||
for (_module_id, exposed_types) in state.exposed_types.iter_all() {
|
|
||||||
let ExposedModuleTypes {
|
|
||||||
solved_specializations,
|
|
||||||
..
|
|
||||||
} = exposed_types;
|
|
||||||
for (&(member, typ), &specialization) in solved_specializations.iter() {
|
|
||||||
match abilities_store.get_specialization(member, typ) {
|
|
||||||
None => abilities_store.register_specialization_for_type(
|
|
||||||
member,
|
|
||||||
typ,
|
|
||||||
specialization,
|
|
||||||
),
|
|
||||||
Some(existing) => debug_assert_eq!(existing, specialization),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
@ -2217,30 +2187,6 @@ 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,
|
||||||
|
@ -3686,19 +3632,6 @@ fn run_solve_solve(
|
||||||
|
|
||||||
let mut subs = Subs::new_from_varstore(var_store);
|
let mut subs = Subs::new_from_varstore(var_store);
|
||||||
|
|
||||||
// We don't know what types we're about to solve for in our module, so we need to include the
|
|
||||||
// solved abilities across all dependencies.
|
|
||||||
// TODO: there's got to be a better way to do this. Maybe keep a cache of module -> solved
|
|
||||||
// abilities?
|
|
||||||
// let mut exposed_for_module = exposed_for_module;
|
|
||||||
// let mut imported_modules = VecSet::with_capacity(2);
|
|
||||||
// for imported in exposed_for_module.imported_values.iter() {
|
|
||||||
// imported_modules.insert(imported.module_id());
|
|
||||||
// }
|
|
||||||
// for module in imported_modules.into_iter() {
|
|
||||||
// let typechecked =
|
|
||||||
// }
|
|
||||||
|
|
||||||
let import_variables = add_imports(
|
let import_variables = add_imports(
|
||||||
&mut subs,
|
&mut subs,
|
||||||
&mut abilities_store,
|
&mut abilities_store,
|
||||||
|
@ -3726,8 +3659,8 @@ fn run_solve_solve(
|
||||||
abilities_store,
|
abilities_store,
|
||||||
);
|
);
|
||||||
|
|
||||||
// STORE ABILITIES
|
|
||||||
let module_id = module.module_id;
|
let module_id = module.module_id;
|
||||||
|
// Figure out what specializations belong to this module
|
||||||
let solved_specializations: SolvedSpecializations = abilities_store
|
let solved_specializations: SolvedSpecializations = abilities_store
|
||||||
.iter_specializations()
|
.iter_specializations()
|
||||||
.filter(|((member, typ), _)| {
|
.filter(|((member, typ), _)| {
|
||||||
|
@ -3737,17 +3670,14 @@ fn run_solve_solve(
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let specialization_symbols: VecSet<_> = solved_specializations
|
let is_specialization_symbol =
|
||||||
.values()
|
|sym| solved_specializations.values().any(|ms| ms.symbol == sym);
|
||||||
.map(|ms| ms.symbol)
|
|
||||||
.collect();
|
|
||||||
// END STORE ABILITIES
|
|
||||||
|
|
||||||
// Expose anything that is explicitly exposed by the header, or is a specialization of an
|
// Expose anything that is explicitly exposed by the header, or is a specialization of an
|
||||||
// ability.
|
// ability.
|
||||||
let exposed_vars_by_symbol: Vec<_> = solved_env
|
let exposed_vars_by_symbol: Vec<_> = solved_env
|
||||||
.vars_by_symbol()
|
.vars_by_symbol()
|
||||||
.filter(|(k, _)| exposed_symbols.contains(k) || specialization_symbols.contains(k))
|
.filter(|(k, _)| exposed_symbols.contains(k) || is_specialization_symbol(*k))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -3803,11 +3733,11 @@ fn run_solve<'a>(
|
||||||
Some((subs, exposed_vars_by_symbol)) => {
|
Some((subs, exposed_vars_by_symbol)) => {
|
||||||
(
|
(
|
||||||
Solved(subs),
|
Solved(subs),
|
||||||
// TODO(abilities) replace when we have abilities for builtins
|
// TODO(abilities) cache abilities for builtins
|
||||||
VecMap::default(),
|
VecMap::default(),
|
||||||
exposed_vars_by_symbol.to_vec(),
|
exposed_vars_by_symbol.to_vec(),
|
||||||
vec![],
|
vec![],
|
||||||
// TODO(abilities) replace when we have abilities for builtins
|
// TODO(abilities) cache abilities for builtins
|
||||||
AbilitiesStore::default(),
|
AbilitiesStore::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ 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_error_macros::internal_error;
|
|
||||||
use roc_exhaustive::{Ctor, CtorName, Guard, RenderAs, TagId};
|
use roc_exhaustive::{Ctor, CtorName, Guard, RenderAs, TagId};
|
||||||
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
|
@ -2784,13 +2783,14 @@ fn resolve_abilities_in_specialized_body<'a>(
|
||||||
use roc_can::traverse::{walk_expr, Visitor};
|
use roc_can::traverse::{walk_expr, Visitor};
|
||||||
use roc_unify::unify::unify;
|
use roc_unify::unify::unify;
|
||||||
|
|
||||||
struct Resolver<'b, 'a, 'i> {
|
struct Resolver<'a> {
|
||||||
env: &'b mut Env<'a, 'i>,
|
subs: &'a mut Subs,
|
||||||
procs: &'b Procs<'a>,
|
procs: &'a Procs<'a>,
|
||||||
|
abilities_store: &'a mut AbilitiesStore,
|
||||||
seen_defs: MutSet<Symbol>,
|
seen_defs: MutSet<Symbol>,
|
||||||
specialized: std::vec::Vec<SpecializationId>,
|
specialized: std::vec::Vec<SpecializationId>,
|
||||||
}
|
}
|
||||||
impl Visitor for Resolver<'_, '_, '_> {
|
impl Visitor for Resolver<'_> {
|
||||||
fn visit_expr(&mut self, expr: &Expr, _region: Region, var: Variable) {
|
fn visit_expr(&mut self, expr: &Expr, _region: Region, var: Variable) {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Closure(..) => {
|
Expr::Closure(..) => {
|
||||||
|
@ -2806,7 +2806,6 @@ fn resolve_abilities_in_specialized_body<'a>(
|
||||||
}
|
}
|
||||||
Expr::AbilityMember(member_sym, specialization_id, _specialization_var) => {
|
Expr::AbilityMember(member_sym, specialization_id, _specialization_var) => {
|
||||||
let (specialization, specialization_def) = match self
|
let (specialization, specialization_def) = match self
|
||||||
.env
|
|
||||||
.abilities_store
|
.abilities_store
|
||||||
.get_resolved(*specialization_id)
|
.get_resolved(*specialization_id)
|
||||||
{
|
{
|
||||||
|
@ -2818,29 +2817,21 @@ fn resolve_abilities_in_specialized_body<'a>(
|
||||||
//
|
//
|
||||||
// However, we do need to walk the specialization def, because it may
|
// However, we do need to walk the specialization def, because it may
|
||||||
// itself contain unspecialized defs.
|
// itself contain unspecialized defs.
|
||||||
if !self.env.is_imported_symbol(specialization) {
|
self.procs
|
||||||
let def = self
|
.partial_procs
|
||||||
.procs
|
.get_symbol(specialization)
|
||||||
.partial_procs
|
.expect("Specialization found, but it's not in procs"),
|
||||||
.get_symbol(specialization)
|
|
||||||
.expect("Specialization found, but it's not in procs");
|
|
||||||
|
|
||||||
Some(def)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
None => {
|
None => {
|
||||||
let specialization = resolve_ability_specialization(
|
let specialization = resolve_ability_specialization(
|
||||||
self.env.subs,
|
self.subs,
|
||||||
self.env.abilities_store,
|
self.abilities_store,
|
||||||
*member_sym,
|
*member_sym,
|
||||||
var,
|
var,
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| internal_error!("Specialization for {:?} is unknown - code generation cannot proceed!", member_sym));
|
.expect("Ability specialization is unknown - code generation cannot proceed!");
|
||||||
|
|
||||||
self.env
|
self.abilities_store
|
||||||
.abilities_store
|
|
||||||
.insert_resolved(*specialization_id, specialization);
|
.insert_resolved(*specialization_id, specialization);
|
||||||
|
|
||||||
debug_assert!(!self.specialized.contains(specialization_id));
|
debug_assert!(!self.specialized.contains(specialization_id));
|
||||||
|
@ -2850,41 +2841,31 @@ 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 = self
|
let specialization_def = self
|
||||||
.procs
|
.procs
|
||||||
.partial_procs
|
.partial_procs
|
||||||
.get_symbol(specialization)
|
.get_symbol(specialization)
|
||||||
.unwrap_or_else(|| {
|
.expect("Specialization found, but it's not in procs");
|
||||||
internal_error!(
|
|
||||||
"Specialization for {:?} found, but it's not in procs",
|
|
||||||
specialization
|
|
||||||
)
|
|
||||||
});
|
|
||||||
let specialization_var = specialization_def.annotation;
|
let specialization_var = specialization_def.annotation;
|
||||||
|
|
||||||
let unified = unify(self.env.subs, var, specialization_var, Mode::EQ);
|
let unified = unify(self.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!",
|
||||||
);
|
);
|
||||||
|
|
||||||
let specialization_def = Some(specialization_def);
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// };
|
|
||||||
|
|
||||||
(specialization, specialization_def)
|
(specialization, specialization_def)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Now walk the specialization def to pick up any more needed types. Of course,
|
// Now walk the specialization def to pick up any more needed types. Of course,
|
||||||
// we only want to pass through it once to avoid unbounded recursion.
|
// we only want to pass through it once to avoid unbounded recursion.
|
||||||
if let Some(def) = specialization_def {
|
if !self.seen_defs.contains(&specialization) {
|
||||||
if !self.seen_defs.contains(&specialization) {
|
self.visit_expr(
|
||||||
self.visit_expr(&def.body, Region::zero(), def.body_var);
|
&specialization_def.body,
|
||||||
self.seen_defs.insert(specialization);
|
Region::zero(),
|
||||||
}
|
specialization_def.body_var,
|
||||||
|
);
|
||||||
|
self.seen_defs.insert(specialization);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => walk_expr(self, expr, var),
|
_ => walk_expr(self, expr, var),
|
||||||
|
@ -2893,8 +2874,9 @@ fn resolve_abilities_in_specialized_body<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut resolver = Resolver {
|
let mut resolver = Resolver {
|
||||||
env,
|
subs: env.subs,
|
||||||
procs,
|
procs,
|
||||||
|
abilities_store: env.abilities_store,
|
||||||
seen_defs: MutSet::default(),
|
seen_defs: MutSet::default(),
|
||||||
specialized: vec![],
|
specialized: vec![],
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue