World abilities: big world vs tiny world

Normally a module can see all of its abilities, and any module it
depends on (this is the tiny world, i.e. only the world it is aware of).
But when making specializations, a module may need to see all abilities
in all modules (big world). This patch supports big-world viewing of
abilities.
This commit is contained in:
Ayaz Hafiz 2022-06-09 16:18:59 -04:00
parent c583112497
commit ee6d733cc4
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
4 changed files with 76 additions and 28 deletions

View file

@ -1,8 +1,10 @@
use std::sync::{Arc, RwLock};
use roc_can::abilities::AbilitiesStore;
use roc_can::expr::PendingDerives;
use roc_collections::VecMap;
use roc_collections::{MutMap, VecMap};
use roc_error_macros::internal_error;
use roc_module::symbol::Symbol;
use roc_module::symbol::{ModuleId, Symbol};
use roc_region::all::{Loc, Region};
use roc_types::subs::{Content, FlatType, GetSubsSlice, Rank, Subs, Variable};
use roc_types::types::{AliasKind, Category, ErrorType, PatternCategory};
@ -12,6 +14,29 @@ use roc_unify::unify::{MustImplementAbility, Obligated};
use crate::solve::{instantiate_rigids, type_to_var};
use crate::solve::{Aliases, Pools, TypeError};
pub type AllModuleAbilities = Arc<RwLock<MutMap<ModuleId, AbilitiesStore>>>;
pub enum WorldAbilities<'a> {
BigWorld(AllModuleAbilities),
TinyWorld(&'a AbilitiesStore),
}
impl WorldAbilities<'_> {
pub fn with_module_store<T, F>(&self, module: ModuleId, mut f: F) -> T
where
F: FnMut(&AbilitiesStore) -> T,
{
match self {
WorldAbilities::BigWorld(world) => {
let world = world.read().unwrap();
let module_store = world.get(&module).unwrap();
f(module_store)
}
WorldAbilities::TinyWorld(store) => f(store),
}
}
}
#[derive(Debug, Clone)]
pub enum AbilityImplError {
/// Promote this to an error that the type does not fully implement an ability