limit cost of inner_scope

This commit is contained in:
Folkert 2022-04-28 23:43:24 +02:00
parent e243402f9b
commit 42d74199e5
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
2 changed files with 19 additions and 10 deletions

View file

@ -1,5 +1,4 @@
use roc_collections::all::{MutSet, SendMap}; use roc_collections::{MutSet, SmallStringInterner, VecMap};
use roc_collections::SmallStringInterner;
use roc_module::ident::{Ident, Lowercase}; use roc_module::ident::{Ident, Lowercase};
use roc_module::symbol::{IdentIds, ModuleId, Symbol}; use roc_module::symbol::{IdentIds, ModuleId, Symbol};
use roc_problem::can::RuntimeError; use roc_problem::can::RuntimeError;
@ -14,7 +13,7 @@ pub struct Scope {
idents: IdentStore, idents: IdentStore,
/// The type aliases currently in scope /// The type aliases currently in scope
pub aliases: SendMap<Symbol, Alias>, pub aliases: VecMap<Symbol, Alias>,
/// The abilities currently in scope, and their implementors. /// The abilities currently in scope, and their implementors.
pub abilities_store: AbilitiesStore, pub abilities_store: AbilitiesStore,
@ -29,11 +28,11 @@ pub struct Scope {
exposed_ident_count: usize, exposed_ident_count: usize,
} }
fn add_aliases(var_store: &mut VarStore) -> SendMap<Symbol, Alias> { fn add_aliases(var_store: &mut VarStore) -> VecMap<Symbol, Alias> {
use roc_types::solved_types::{BuiltinAlias, FreeVars}; use roc_types::solved_types::{BuiltinAlias, FreeVars};
let solved_aliases = roc_types::builtin_aliases::aliases(); let solved_aliases = roc_types::builtin_aliases::aliases();
let mut aliases = SendMap::default(); let mut aliases = VecMap::default();
for (symbol, builtin_alias) in solved_aliases { for (symbol, builtin_alias) in solved_aliases {
let BuiltinAlias { let BuiltinAlias {
@ -76,7 +75,7 @@ impl Scope {
exposed_ident_count: initial_ident_ids.len(), exposed_ident_count: initial_ident_ids.len(),
ident_ids: initial_ident_ids, ident_ids: initial_ident_ids,
idents: IdentStore::new(), idents: IdentStore::new(),
aliases: SendMap::default(), aliases: VecMap::default(),
// TODO(abilities): default abilities in scope // TODO(abilities): default abilities in scope
abilities_store: AbilitiesStore::default(), abilities_store: AbilitiesStore::default(),
} }
@ -348,15 +347,20 @@ impl Scope {
where where
F: FnOnce(&mut Scope) -> T, F: FnOnce(&mut Scope) -> T,
{ {
// store enough information to roll back to the original outer scope
//
// - abilities_store: abilitie definitions not allowed in inner scopes
// - ident_ids: identifiers in inner scopes should still be available in the ident_ids
// - idents: we have to clone for now
// - aliases: stored in a VecMap, we just discard anything added in an inner scope
// - exposed_ident_count: unchanged
let idents = self.idents.clone(); let idents = self.idents.clone();
let aliases = self.aliases.clone(); let aliases_count = self.aliases.len();
let abilities_store = self.abilities_store.clone();
let result = f(self); let result = f(self);
self.idents = idents; self.idents = idents;
self.aliases = aliases; self.aliases.truncate(aliases_count);
self.abilities_store = abilities_store;
result result
} }

View file

@ -109,6 +109,11 @@ impl<K: PartialEq, V> VecMap<K, V> {
self.values.iter() self.values.iter()
} }
pub fn truncate(&mut self, len: usize) {
self.keys.truncate(len);
self.values.truncate(len);
}
pub fn unzip(self) -> (Vec<K>, Vec<V>) { pub fn unzip(self) -> (Vec<K>, Vec<V>) {
(self.keys, self.values) (self.keys, self.values)
} }