mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
refactor ExternalSpecializations to use Vec
This commit is contained in:
parent
ede5967ced
commit
d3528a3ed3
1 changed files with 37 additions and 23 deletions
|
@ -419,40 +419,54 @@ impl<'a> Proc<'a> {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ExternalSpecializations<'a> {
|
pub struct ExternalSpecializations<'a> {
|
||||||
/// Not a bumpalo vec because bumpalo is not thread safe
|
/// Not a bumpalo vec because bumpalo is not thread safe
|
||||||
pub specs: BumpMap<Symbol, std::vec::Vec<SolvedType>>,
|
/// Separate array so we can search for membership quickly
|
||||||
|
symbols: std::vec::Vec<Symbol>,
|
||||||
|
/// For each symbol, what types to specialize it for
|
||||||
|
types_to_specialize: std::vec::Vec<std::vec::Vec<SolvedType>>,
|
||||||
_lifetime: std::marker::PhantomData<&'a u8>,
|
_lifetime: std::marker::PhantomData<&'a u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ExternalSpecializations<'a> {
|
impl<'a> ExternalSpecializations<'a> {
|
||||||
pub fn new_in(arena: &'a Bump) -> Self {
|
pub fn new_in(_arena: &'a Bump) -> Self {
|
||||||
Self {
|
Self {
|
||||||
specs: BumpMap::new_in(arena),
|
symbols: std::vec::Vec::new(),
|
||||||
|
types_to_specialize: std::vec::Vec::new(),
|
||||||
_lifetime: std::marker::PhantomData,
|
_lifetime: std::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, symbol: Symbol, typ: SolvedType) {
|
pub fn insert(&mut self, symbol: Symbol, typ: SolvedType) {
|
||||||
use hashbrown::hash_map::Entry::{Occupied, Vacant};
|
match self.symbols.iter().position(|s| *s == symbol) {
|
||||||
|
None => {
|
||||||
let existing = match self.specs.entry(symbol) {
|
self.symbols.push(symbol);
|
||||||
Vacant(entry) => entry.insert(std::vec::Vec::new()),
|
self.types_to_specialize.push(vec![typ]);
|
||||||
Occupied(entry) => entry.into_mut(),
|
}
|
||||||
};
|
Some(index) => {
|
||||||
|
let types_to_specialize = &mut self.types_to_specialize[index];
|
||||||
existing.push(typ);
|
types_to_specialize.push(typ);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extend(&mut self, other: Self) {
|
pub fn extend(&mut self, other: Self) {
|
||||||
use hashbrown::hash_map::Entry::{Occupied, Vacant};
|
for (symbol, tts) in other.into_iter() {
|
||||||
|
match self.symbols.iter().position(|s| *s == symbol) {
|
||||||
for (symbol, solved_types) in other.specs {
|
None => {
|
||||||
let existing = match self.specs.entry(symbol) {
|
self.symbols.push(symbol);
|
||||||
Vacant(entry) => entry.insert(std::vec::Vec::new()),
|
self.types_to_specialize.push(tts);
|
||||||
Occupied(entry) => entry.into_mut(),
|
|
||||||
};
|
|
||||||
|
|
||||||
existing.extend(solved_types);
|
|
||||||
}
|
}
|
||||||
|
Some(index) => {
|
||||||
|
let types_to_specialize = &mut self.types_to_specialize[index];
|
||||||
|
types_to_specialize.extend(tts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_iter(self) -> impl Iterator<Item = (Symbol, std::vec::Vec<SolvedType>)> {
|
||||||
|
self.symbols
|
||||||
|
.into_iter()
|
||||||
|
.zip(self.types_to_specialize.into_iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1970,14 +1984,14 @@ fn specialize_externals_others_need<'a>(
|
||||||
externals_others_need: ExternalSpecializations<'a>,
|
externals_others_need: ExternalSpecializations<'a>,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
) {
|
) {
|
||||||
for (symbol, solved_types) in externals_others_need.specs.iter() {
|
for (symbol, solved_types) in externals_others_need.into_iter() {
|
||||||
for solved_type in solved_types {
|
for solved_type in solved_types {
|
||||||
// historical note: we used to deduplicate with a hash here,
|
// historical note: we used to deduplicate with a hash here,
|
||||||
// but the cost of that hash is very high. So for now we make
|
// but the cost of that hash is very high. So for now we make
|
||||||
// duplicate specializations, and the insertion into a hash map
|
// duplicate specializations, and the insertion into a hash map
|
||||||
// below will deduplicate them.
|
// below will deduplicate them.
|
||||||
|
|
||||||
let name = *symbol;
|
let name = symbol;
|
||||||
|
|
||||||
let partial_proc_id = match procs.partial_procs.symbol_to_id(name) {
|
let partial_proc_id = match procs.partial_procs.symbol_to_id(name) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
|
@ -1992,7 +2006,7 @@ fn specialize_externals_others_need<'a>(
|
||||||
procs,
|
procs,
|
||||||
name,
|
name,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
solved_type,
|
&solved_type,
|
||||||
BumpMap::new_in(env.arena),
|
BumpMap::new_in(env.arena),
|
||||||
partial_proc_id,
|
partial_proc_id,
|
||||||
) {
|
) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue