Have load_internal deal with separate declared/known ability specializations

This commit is contained in:
Ayaz Hafiz 2022-07-25 09:24:58 -04:00
parent e2454f497f
commit cd0b8577ab
No known key found for this signature in database
GPG Key ID: 0E2A37416A25EF58
3 changed files with 54 additions and 20 deletions

View File

@ -5,12 +5,13 @@ use crossbeam::deque::{Injector, Stealer, Worker};
use crossbeam::thread; use crossbeam::thread;
use parking_lot::Mutex; use parking_lot::Mutex;
use roc_builtins::roc::module_source; use roc_builtins::roc::module_source;
use roc_can::abilities::{AbilitiesStore, PendingAbilitiesStore, ResolvedSpecializations}; use roc_can::abilities::{AbilitiesStore, PendingAbilitiesStore};
use roc_can::constraint::{Constraint as ConstraintSoa, Constraints}; use roc_can::constraint::{Constraint as ConstraintSoa, Constraints};
use roc_can::expr::Declarations; use roc_can::expr::Declarations;
use roc_can::expr::PendingDerives; use roc_can::expr::PendingDerives;
use roc_can::module::{ use roc_can::module::{
canonicalize_module_defs, ExposedByModule, ExposedForModule, ExposedModuleTypes, Module, canonicalize_module_defs, ExposedByModule, ExposedForModule, ExposedModuleTypes, Module,
ResolvedSpecializations,
}; };
use roc_collections::{default_hasher, BumpMap, MutMap, MutSet, VecMap, VecSet}; use roc_collections::{default_hasher, BumpMap, MutMap, MutSet, VecMap, VecSet};
use roc_constrain::module::constrain_module; use roc_constrain::module::constrain_module;
@ -45,7 +46,7 @@ use roc_solve::module::{Solved, SolvedModule};
use roc_solve::solve; use roc_solve::solve;
use roc_target::TargetInfo; use roc_target::TargetInfo;
use roc_types::subs::{ExposedTypesStorageSubs, Subs, VarStore, Variable}; use roc_types::subs::{ExposedTypesStorageSubs, Subs, VarStore, Variable};
use roc_types::types::{Alias, AliasKind}; use roc_types::types::{Alias, AliasKind, MemberImpl};
use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap; use std::collections::HashMap;
use std::env::current_dir; use std::env::current_dir;
@ -4050,8 +4051,8 @@ pub fn add_imports(
// One idea is to just always assume external modules fulfill their specialization obligations // One idea is to just always assume external modules fulfill their specialization obligations
// and save lambda set resolution for mono. // and save lambda set resolution for mono.
for (_, module_types) in exposed_for_module.exposed_by_module.iter_all() { for (_, module_types) in exposed_for_module.exposed_by_module.iter_all() {
for ((member, typ), specialization) in module_types.resolved_specializations.iter() { for resolved_specialization in module_types.resolved_specializations.values() {
pending_abilities.import_specialization(*member, *typ, specialization) pending_abilities.import_specialization(resolved_specialization)
} }
} }
@ -4101,6 +4102,30 @@ pub fn add_imports(
(import_variables, abilities_store) (import_variables, abilities_store)
} }
/// Extracts the ability member specializations owned by a solved module.
fn extract_module_owned_specializations(
module_id: ModuleId,
abilities_store: &AbilitiesStore,
) -> ResolvedSpecializations {
abilities_store
.iter_declared_implementations()
.filter(|((member, typ), _)| {
// This module solved this specialization if either the member or the type comes from the
// module.
member.module_id() == module_id || typ.module_id() == module_id
})
.filter_map(|(_, member_impl)| match member_impl {
MemberImpl::Impl(impl_symbol) => {
let specialization = abilities_store.specialization_info(*impl_symbol).expect(
"declared implementations should be resolved conclusively after solving",
);
Some((*impl_symbol, specialization.clone()))
}
MemberImpl::Derived | MemberImpl::Error => None,
})
.collect()
}
#[allow(clippy::complexity)] #[allow(clippy::complexity)]
fn run_solve_solve( fn run_solve_solve(
exposed_for_module: ExposedForModule, exposed_for_module: ExposedForModule,
@ -4164,16 +4189,8 @@ fn run_solve_solve(
derived_module, derived_module,
); );
// Figure out what specializations belong to this module let solved_specializations =
let solved_specializations: ResolvedSpecializations = abilities_store extract_module_owned_specializations(module_id, &abilities_store);
.iter_declared_implementations()
.filter(|((member, typ), _)| {
// This module solved this specialization if either the member or the type comes from the
// module.
member.module_id() == module_id || typ.module_id() == module_id
})
.map(|(key, specialization)| (key, specialization.clone()))
.collect();
let is_specialization_symbol = let is_specialization_symbol =
|sym| solved_specializations.values().any(|ms| ms.symbol == sym); |sym| solved_specializations.values().any(|ms| ms.symbol == sym);

View File

@ -19,7 +19,10 @@ mod solve_expr {
use roc_region::all::{LineColumn, LineColumnRegion, LineInfo, Region}; use roc_region::all::{LineColumn, LineColumnRegion, LineInfo, Region};
use roc_reporting::report::{can_problem, type_problem, RocDocAllocator}; use roc_reporting::report::{can_problem, type_problem, RocDocAllocator};
use roc_solve::solve::TypeError; use roc_solve::solve::TypeError;
use roc_types::pretty_print::{name_and_print_var, DebugPrint}; use roc_types::{
pretty_print::{name_and_print_var, DebugPrint},
types::MemberImpl,
};
use std::path::PathBuf; use std::path::PathBuf;
// HELPERS // HELPERS
@ -361,13 +364,24 @@ mod solve_expr {
if !type_problems.is_empty() { if !type_problems.is_empty() {
eprintln!("{:?}", type_problems); eprintln!("{:?}", type_problems);
panic!(); panic!();
}iter_declared_impls }
let known_specializations = abilities_store.iter_declared_implementations().filter_map(
|((member, typ), member_impl)| match member_impl {
MemberImpl::Impl(impl_symbol) => {
let specialization = abilities_store.specialization_info(*impl_symbol).expect(
"declared implementations should be resolved conclusively after solving",
);
Some((member, typ, specialization.clone()))
}
MemberImpl::Derived | MemberImpl::Error => None,
},
);
let known_specializations = abilities_store.iter_specializations();
use std::collections::HashSet; use std::collections::HashSet;
let pretty_specializations = known_specializations let pretty_specializations = known_specializations
.into_iter() .into_iter()
.map(|((member, typ), _)| { .map(|(member, typ, _)| {
let member_data = abilities_store.member_def(member).unwrap(); let member_data = abilities_store.member_def(member).unwrap();
let member_str = member.as_str(&interns); let member_str = member.as_str(&interns);
let ability_str = member_data.parent_ability.as_str(&interns); let ability_str = member_data.parent_ability.as_str(&interns);

View File

@ -13,11 +13,14 @@ use ven_pretty::DocAllocator;
use crate::pretty_print::{pretty_print_def, Ctx}; use crate::pretty_print::{pretty_print_def, Ctx};
use roc_can::{ use roc_can::{
abilities::{AbilitiesStore, ResolvedSpecializations, SpecializationLambdaSets}, abilities::{AbilitiesStore, SpecializationLambdaSets},
constraint::Constraints, constraint::Constraints,
def::Def, def::Def,
expr::Declarations, expr::Declarations,
module::{ExposedByModule, ExposedForModule, ExposedModuleTypes, RigidVariables}, module::{
ExposedByModule, ExposedForModule, ExposedModuleTypes, ResolvedSpecializations,
RigidVariables,
},
}; };
use roc_collections::VecSet; use roc_collections::VecSet;
use roc_constrain::expr::constrain_decls; use roc_constrain::expr::constrain_decls;