move identids into Scope

This commit is contained in:
Folkert 2022-04-28 21:08:28 +02:00
parent 37cb9279f5
commit 7fb5b23fb0
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
10 changed files with 123 additions and 181 deletions

View file

@ -277,7 +277,7 @@ fn make_apply_symbol(
} }
} }
} else { } else {
match env.qualified_lookup(module_name, ident, region) { match env.qualified_lookup(scope, module_name, ident, region) {
Ok(symbol) => Ok(symbol), Ok(symbol) => Ok(symbol),
Err(problem) => { Err(problem) => {
// Either the module wasn't imported, or // Either the module wasn't imported, or
@ -579,7 +579,7 @@ fn can_annotation_help(
vars: loc_vars, vars: loc_vars,
}, },
) => { ) => {
let symbol = match scope.introduce(name.value.into(), &mut env.ident_ids, region) { let symbol = match scope.introduce(name.value.into(), region) {
Ok(symbol) => symbol, Ok(symbol) => symbol,
Err((original_region, shadow, _new_symbol)) => { Err((original_region, shadow, _new_symbol)) => {

View file

@ -243,7 +243,7 @@ pub(crate) fn canonicalize_defs<'a>(
} }
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
env.home.register_debug_idents(&env.ident_ids); scope.register_debug_idents();
} }
enum TypeDef<'a> { enum TypeDef<'a> {
@ -278,7 +278,8 @@ pub(crate) fn canonicalize_defs<'a>(
} => { } => {
let referenced_symbols = crate::annotation::find_type_def_symbols( let referenced_symbols = crate::annotation::find_type_def_symbols(
env.home, env.home,
&mut env.ident_ids, // TODO IDENT_IDS
&mut scope.ident_ids,
&ann.value, &ann.value,
); );
@ -295,7 +296,8 @@ pub(crate) fn canonicalize_defs<'a>(
// definition. // definition.
referenced_symbols.extend(crate::annotation::find_type_def_symbols( referenced_symbols.extend(crate::annotation::find_type_def_symbols(
env.home, env.home,
&mut env.ident_ids, // TODO IDENT_IDS
&mut scope.ident_ids,
&member.typ.value, &member.typ.value,
)); ));
} }
@ -569,8 +571,7 @@ fn resolve_abilities<'a>(
let name_region = member.name.region; let name_region = member.name.region;
let member_name = member.name.extract_spaces().item; let member_name = member.name.extract_spaces().item;
let member_sym = let member_sym = match scope.introduce(member_name.into(), name_region) {
match scope.introduce(member_name.into(), &mut env.ident_ids, name_region) {
Ok(sym) => sym, Ok(sym) => sym,
Err((original_region, shadow, _new_symbol)) => { Err((original_region, shadow, _new_symbol)) => {
env.problem(roc_problem::can::Problem::Shadowing { env.problem(roc_problem::can::Problem::Shadowing {
@ -1072,7 +1073,7 @@ fn canonicalize_pending_value_def<'a>(
region: loc_ann.region, region: loc_ann.region,
} }
} else { } else {
let symbol = env.gen_unique_symbol(); let symbol = scope.gen_unique_symbol();
// generate a fake pattern for each argument. this makes signatures // generate a fake pattern for each argument. this makes signatures
// that are functions only crash when they are applied. // that are functions only crash when they are applied.
@ -1359,11 +1360,7 @@ fn to_pending_type_def<'a>(
let region = Region::span_across(&name.region, &ann.region); let region = Region::span_across(&name.region, &ann.region);
match scope.introduce_without_shadow_symbol( match scope.introduce_without_shadow_symbol(&Ident::from(name.value), region) {
&Ident::from(name.value),
&mut env.ident_ids,
region,
) {
Ok(symbol) => { Ok(symbol) => {
let mut can_rigids: Vec<Loc<Lowercase>> = Vec::with_capacity(vars.len()); let mut can_rigids: Vec<Loc<Lowercase>> = Vec::with_capacity(vars.len());
@ -1438,11 +1435,9 @@ fn to_pending_type_def<'a>(
members, members,
loc_has: _, loc_has: _,
} => { } => {
let name = match scope.introduce_without_shadow_symbol( let name = match scope
&Ident::from(name.value), .introduce_without_shadow_symbol(&Ident::from(name.value), name.region)
&mut env.ident_ids, {
name.region,
) {
Ok(symbol) => Loc::at(name.region, symbol), Ok(symbol) => Loc::at(name.region, symbol),
Err((original_region, shadowed_symbol)) => { Err((original_region, shadowed_symbol)) => {
env.problem(Problem::Shadowing { env.problem(Problem::Shadowing {

View file

@ -87,15 +87,13 @@ pub(crate) fn build_effect_builtins(
// show up with their name. We have to register them like below to make the names show up in // show up with their name. We have to register them like below to make the names show up in
// debug prints // debug prints
if false { if false {
env.home.register_debug_idents(&env.ident_ids); scope.register_debug_idents();
} }
} }
macro_rules! new_symbol { macro_rules! new_symbol {
($scope:expr, $env:expr, $name:expr) => {{ ($scope:expr, $env:expr, $name:expr) => {{
$scope $scope.introduce($name.into(), Region::zero()).unwrap()
.introduce($name.into(), &mut $env.ident_ids, Region::zero())
.unwrap()
}}; }};
} }
@ -109,29 +107,17 @@ fn build_effect_always(
let value_symbol = { let value_symbol = {
scope scope
.introduce( .introduce("effect_always_value".into(), Region::zero())
"effect_always_value".into(),
&mut env.ident_ids,
Region::zero(),
)
.unwrap() .unwrap()
}; };
let inner_closure_symbol = { let inner_closure_symbol = {
scope scope
.introduce( .introduce("effect_always_inner".into(), Region::zero())
"effect_always_inner".into(),
&mut env.ident_ids,
Region::zero(),
)
.unwrap() .unwrap()
}; };
let always_symbol = { let always_symbol = { scope.introduce("always".into(), Region::zero()).unwrap() };
scope
.introduce("always".into(), &mut env.ident_ids, Region::zero())
.unwrap()
};
// \{} -> value // \{} -> value
let const_closure = { let const_closure = {
@ -247,29 +233,17 @@ fn build_effect_map(
let thunk_symbol = { let thunk_symbol = {
scope scope
.introduce( .introduce("effect_map_thunk".into(), Region::zero())
"effect_map_thunk".into(),
&mut env.ident_ids,
Region::zero(),
)
.unwrap() .unwrap()
}; };
let mapper_symbol = { let mapper_symbol = {
scope scope
.introduce( .introduce("effect_map_mapper".into(), Region::zero())
"effect_map_mapper".into(),
&mut env.ident_ids,
Region::zero(),
)
.unwrap() .unwrap()
}; };
let map_symbol = { let map_symbol = { scope.introduce("map".into(), Region::zero()).unwrap() };
scope
.introduce("map".into(), &mut env.ident_ids, Region::zero())
.unwrap()
};
// `thunk {}` // `thunk {}`
let force_thunk_call = { let force_thunk_call = {
@ -299,11 +273,7 @@ fn build_effect_map(
let inner_closure_symbol = { let inner_closure_symbol = {
scope scope
.introduce( .introduce("effect_map_inner".into(), Region::zero())
"effect_map_inner".into(),
&mut env.ident_ids,
Region::zero(),
)
.unwrap() .unwrap()
}; };
@ -457,29 +427,17 @@ fn build_effect_after(
let thunk_symbol = { let thunk_symbol = {
scope scope
.introduce( .introduce("effect_after_thunk".into(), Region::zero())
"effect_after_thunk".into(),
&mut env.ident_ids,
Region::zero(),
)
.unwrap() .unwrap()
}; };
let to_effect_symbol = { let to_effect_symbol = {
scope scope
.introduce( .introduce("effect_after_toEffect".into(), Region::zero())
"effect_after_toEffect".into(),
&mut env.ident_ids,
Region::zero(),
)
.unwrap() .unwrap()
}; };
let after_symbol = { let after_symbol = { scope.introduce("after".into(), Region::zero()).unwrap() };
scope
.introduce("after".into(), &mut env.ident_ids, Region::zero())
.unwrap()
};
// `thunk {}` // `thunk {}`
let force_thunk_call = { let force_thunk_call = {
@ -762,17 +720,9 @@ fn build_effect_forever(
// //
// Making `foreverInner` perfectly tail-call optimizable // Making `foreverInner` perfectly tail-call optimizable
let forever_symbol = { let forever_symbol = { scope.introduce("forever".into(), Region::zero()).unwrap() };
scope
.introduce("forever".into(), &mut env.ident_ids, Region::zero())
.unwrap()
};
let effect = { let effect = { scope.introduce("effect".into(), Region::zero()).unwrap() };
scope
.introduce("effect".into(), &mut env.ident_ids, Region::zero())
.unwrap()
};
let body = let body =
build_effect_forever_body(env, scope, effect_symbol, forever_symbol, effect, var_store); build_effect_forever_body(env, scope, effect_symbol, forever_symbol, effect, var_store);
@ -860,7 +810,7 @@ fn build_effect_forever_body(
) -> Expr { ) -> Expr {
let closure_name = { let closure_name = {
scope scope
.introduce("forever_inner".into(), &mut env.ident_ids, Region::zero()) .introduce("forever_inner".into(), Region::zero())
.unwrap() .unwrap()
}; };
@ -891,17 +841,9 @@ fn build_effect_forever_inner_body(
effect: Symbol, effect: Symbol,
var_store: &mut VarStore, var_store: &mut VarStore,
) -> Expr { ) -> Expr {
let thunk1_symbol = { let thunk1_symbol = { scope.introduce("thunk1".into(), Region::zero()).unwrap() };
scope
.introduce("thunk1".into(), &mut env.ident_ids, Region::zero())
.unwrap()
};
let thunk2_symbol = { let thunk2_symbol = { scope.introduce("thunk2".into(), Region::zero()).unwrap() };
scope
.introduce("thunk2".into(), &mut env.ident_ids, Region::zero())
.unwrap()
};
// @Effect thunk1 = effect // @Effect thunk1 = effect
let thunk_from_effect = { let thunk_from_effect = {
@ -1138,7 +1080,7 @@ fn build_effect_loop_body(
) -> Expr { ) -> Expr {
let closure_name = { let closure_name = {
scope scope
.introduce("loop_inner".into(), &mut env.ident_ids, Region::zero()) .introduce("loop_inner".into(), Region::zero())
.unwrap() .unwrap()
}; };
@ -1352,9 +1294,7 @@ pub fn build_host_exposed_def(
let arg_symbol = { let arg_symbol = {
let ident = name.clone().into(); let ident = name.clone().into();
scope scope.introduce(ident, Region::zero()).unwrap()
.introduce(ident, &mut env.ident_ids, Region::zero())
.unwrap()
}; };
let arg_var = var_store.fresh(); let arg_var = var_store.fresh();
@ -1376,9 +1316,7 @@ pub fn build_host_exposed_def(
let name = format!("effect_closure_{}", ident); let name = format!("effect_closure_{}", ident);
let ident = name.into(); let ident = name.into();
scope scope.introduce(ident, Region::zero()).unwrap()
.introduce(ident, &mut env.ident_ids, Region::zero())
.unwrap()
}; };
let effect_closure = Expr::Closure(ClosureData { let effect_closure = Expr::Closure(ClosureData {
@ -1433,9 +1371,7 @@ pub fn build_host_exposed_def(
let name = format!("effect_closure_{}", ident); let name = format!("effect_closure_{}", ident);
let ident = name.into(); let ident = name.into();
scope scope.introduce(ident, Region::zero()).unwrap()
.introduce(ident, &mut env.ident_ids, Region::zero())
.unwrap()
}; };
let empty_record_pattern = Pattern::RecordDestructure { let empty_record_pattern = Pattern::RecordDestructure {

View file

@ -1,4 +1,5 @@
use crate::procedure::References; use crate::procedure::References;
use crate::scope::Scope;
use roc_collections::{MutMap, VecSet}; use roc_collections::{MutMap, VecSet};
use roc_module::ident::{Ident, Lowercase, ModuleName}; use roc_module::ident::{Ident, Lowercase, ModuleName};
use roc_module::symbol::{IdentIds, IdentIdsByModule, ModuleId, ModuleIds, Symbol}; use roc_module::symbol::{IdentIds, IdentIdsByModule, ModuleId, ModuleIds, Symbol};
@ -32,7 +33,7 @@ pub struct Env<'a> {
pub top_level_symbols: VecSet<Symbol>, pub top_level_symbols: VecSet<Symbol>,
pub ident_ids: IdentIds, ident_ids: IdentIds,
} }
impl<'a> Env<'a> { impl<'a> Env<'a> {
@ -59,6 +60,7 @@ impl<'a> Env<'a> {
/// Returns Err if the symbol resolved, but it was not exposed by the given module /// Returns Err if the symbol resolved, but it was not exposed by the given module
pub fn qualified_lookup( pub fn qualified_lookup(
&mut self, &mut self,
scope: &Scope,
module_name_str: &str, module_name_str: &str,
ident: &str, ident: &str,
region: Region, region: Region,
@ -79,7 +81,7 @@ impl<'a> Env<'a> {
// You can do qualified lookups on your own module, e.g. // You can do qualified lookups on your own module, e.g.
// if I'm in the Foo module, I can do a `Foo.bar` lookup. // if I'm in the Foo module, I can do a `Foo.bar` lookup.
if module_id == self.home { if module_id == self.home {
match self.ident_ids.get_id(&ident) { match scope.ident_ids.get_id(&ident) {
Some(ident_id) => { Some(ident_id) => {
let symbol = Symbol::new(module_id, ident_id); let symbol = Symbol::new(module_id, ident_id);
@ -97,7 +99,8 @@ impl<'a> Env<'a> {
value: ident, value: ident,
region, region,
}, },
self.ident_ids scope
.ident_ids
.ident_strs() .ident_strs()
.map(|(_, string)| string.into()) .map(|(_, string)| string.into())
.collect(), .collect(),
@ -167,6 +170,7 @@ impl<'a> Env<'a> {
/// ///
/// This is used, for example, during canonicalization of an Expr::Closure /// This is used, for example, during canonicalization of an Expr::Closure
/// to generate a unique symbol to refer to that closure. /// to generate a unique symbol to refer to that closure.
// TODO IDENT_IDS
pub fn gen_unique_symbol(&mut self) -> Symbol { pub fn gen_unique_symbol(&mut self) -> Symbol {
let ident_id = self.ident_ids.gen_unique(); let ident_id = self.ident_ids.gen_unique();

View file

@ -407,6 +407,7 @@ pub fn canonicalize_expr<'a>(
fields, fields,
update: loc_update, update: loc_update,
} => { } => {
dbg!(&loc_update);
let (can_update, update_out) = let (can_update, update_out) =
canonicalize_expr(env, var_store, scope, loc_update.region, &loc_update.value); canonicalize_expr(env, var_store, scope, loc_update.region, &loc_update.value);
if let Var(symbol) = &can_update.value { if let Var(symbol) = &can_update.value {
@ -437,6 +438,7 @@ pub fn canonicalize_expr<'a>(
), ),
} }
} else { } else {
dbg!(&can_update.value);
// only (optionally qualified) variables can be updated, not arbitrary expressions // only (optionally qualified) variables can be updated, not arbitrary expressions
let error = roc_problem::can::RuntimeError::InvalidRecordUpdate { let error = roc_problem::can::RuntimeError::InvalidRecordUpdate {
@ -731,7 +733,7 @@ pub fn canonicalize_expr<'a>(
} }
ast::Expr::AccessorFunction(field) => ( ast::Expr::AccessorFunction(field) => (
Accessor(AccessorData { Accessor(AccessorData {
name: env.gen_unique_symbol(), name: scope.gen_unique_symbol(),
function_var: var_store.fresh(), function_var: var_store.fresh(),
record_var: var_store.fresh(), record_var: var_store.fresh(),
ext_var: var_store.fresh(), ext_var: var_store.fresh(),
@ -746,7 +748,7 @@ pub fn canonicalize_expr<'a>(
let variant_var = var_store.fresh(); let variant_var = var_store.fresh();
let ext_var = var_store.fresh(); let ext_var = var_store.fresh();
let symbol = env.gen_unique_symbol(); let symbol = scope.gen_unique_symbol();
( (
ZeroArgumentTag { ZeroArgumentTag {
@ -976,7 +978,7 @@ fn canonicalize_closure_inner_scope<'a>(
) -> (ClosureData, Output) { ) -> (ClosureData, Output) {
// The globally unique symbol that will refer to this closure once it gets converted // The globally unique symbol that will refer to this closure once it gets converted
// into a top-level procedure for code gen. // into a top-level procedure for code gen.
let symbol = opt_def_name.unwrap_or_else(|| env.gen_unique_symbol()); let symbol = opt_def_name.unwrap_or_else(|| scope.gen_unique_symbol());
let mut can_args = Vec::with_capacity(loc_arg_patterns.len()); let mut can_args = Vec::with_capacity(loc_arg_patterns.len());
let mut output = Output::default(); let mut output = Output::default();
@ -1273,7 +1275,7 @@ fn canonicalize_var_lookup(
} else { } else {
// Since module_name was nonempty, this is a qualified var. // Since module_name was nonempty, this is a qualified var.
// Look it up in the env! // Look it up in the env!
match env.qualified_lookup(module_name, ident, region) { match env.qualified_lookup(scope, module_name, ident, region) {
Ok(symbol) => { Ok(symbol) => {
output.references.insert_value_lookup(symbol); output.references.insert_value_lookup(symbol);

View file

@ -107,9 +107,7 @@ impl GeneratedInfo {
env.problem(Problem::UnknownGeneratesWith(unknown)); env.problem(Problem::UnknownGeneratesWith(unknown));
} }
let effect_symbol = scope let effect_symbol = scope.introduce(name.into(), Region::zero()).unwrap();
.introduce(name.into(), &mut env.ident_ids, Region::zero())
.unwrap();
{ {
let a_var = var_store.fresh(); let a_var = var_store.fresh();
@ -409,7 +407,7 @@ pub fn canonicalize_module_defs<'a>(
let symbol = def.pattern_vars.iter().next().unwrap().0; let symbol = def.pattern_vars.iter().next().unwrap().0;
let ident_id = symbol.ident_id(); let ident_id = symbol.ident_id();
let ident = let ident =
env.ident_ids.get_name(ident_id).unwrap().to_string(); scope.ident_ids.get_name(ident_id).unwrap().to_string();
let def_annotation = def.annotation.clone().unwrap(); let def_annotation = def.annotation.clone().unwrap();
let annotation = crate::annotation::Annotation { let annotation = crate::annotation::Annotation {
typ: def_annotation.signature, typ: def_annotation.signature,
@ -537,6 +535,8 @@ pub fn canonicalize_module_defs<'a>(
} }
} }
let ident_ids = scope.ident_ids.clone();
let output = ModuleOutput { let output = ModuleOutput {
scope, scope,
aliases, aliases,
@ -547,7 +547,7 @@ pub fn canonicalize_module_defs<'a>(
exposed_imports: can_exposed_imports, exposed_imports: can_exposed_imports,
problems: env.problems, problems: env.problems,
lookups, lookups,
ident_ids: env.ident_ids, ident_ids,
}; };
Ok(output) Ok(output)

View file

@ -190,11 +190,8 @@ pub fn canonicalize_def_header_pattern<'a>(
match pattern { match pattern {
// Identifiers that shadow ability members may appear (and may only appear) at the header of a def. // Identifiers that shadow ability members may appear (and may only appear) at the header of a def.
Identifier(name) => match scope.introduce_or_shadow_ability_member( Identifier(name) => {
(*name).into(), match scope.introduce_or_shadow_ability_member((*name).into(), region) {
&mut env.ident_ids,
region,
) {
Ok((symbol, shadowing_ability_member)) => { Ok((symbol, shadowing_ability_member)) => {
output.references.insert_bound(symbol); output.references.insert_bound(symbol);
let can_pattern = match shadowing_ability_member { let can_pattern = match shadowing_ability_member {
@ -219,7 +216,8 @@ pub fn canonicalize_def_header_pattern<'a>(
let can_pattern = Pattern::Shadowed(original_region, shadow, new_symbol); let can_pattern = Pattern::Shadowed(original_region, shadow, new_symbol);
Loc::at(region, can_pattern) Loc::at(region, can_pattern)
} }
}, }
}
_ => canonicalize_pattern(env, var_store, scope, output, pattern_type, pattern, region), _ => canonicalize_pattern(env, var_store, scope, output, pattern_type, pattern, region),
} }
} }
@ -237,7 +235,7 @@ pub fn canonicalize_pattern<'a>(
use PatternType::*; use PatternType::*;
let can_pattern = match pattern { let can_pattern = match pattern {
Identifier(name) => match scope.introduce((*name).into(), &mut env.ident_ids, region) { Identifier(name) => match scope.introduce((*name).into(), region) {
Ok(symbol) => { Ok(symbol) => {
output.references.insert_bound(symbol); output.references.insert_bound(symbol);
@ -457,7 +455,7 @@ pub fn canonicalize_pattern<'a>(
for loc_pattern in patterns.iter() { for loc_pattern in patterns.iter() {
match loc_pattern.value { match loc_pattern.value {
Identifier(label) => { Identifier(label) => {
match scope.introduce(label.into(), &mut env.ident_ids, region) { match scope.introduce(label.into(), region) {
Ok(symbol) => { Ok(symbol) => {
output.references.insert_bound(symbol); output.references.insert_bound(symbol);
@ -490,7 +488,7 @@ pub fn canonicalize_pattern<'a>(
RequiredField(label, loc_guard) => { RequiredField(label, loc_guard) => {
// a guard does not introduce the label into scope! // a guard does not introduce the label into scope!
let symbol = scope.ignore(&Ident::from(label), &mut env.ident_ids); let symbol = scope.ignore(&Ident::from(label));
let can_guard = canonicalize_pattern( let can_guard = canonicalize_pattern(
env, env,
var_store, var_store,
@ -513,7 +511,7 @@ pub fn canonicalize_pattern<'a>(
} }
OptionalField(label, loc_default) => { OptionalField(label, loc_default) => {
// an optional DOES introduce the label into scope! // an optional DOES introduce the label into scope!
match scope.introduce(label.into(), &mut env.ident_ids, region) { match scope.introduce(label.into(), region) {
Ok(symbol) => { Ok(symbol) => {
let (can_default, expr_output) = canonicalize_expr( let (can_default, expr_output) = canonicalize_expr(
env, env,

View file

@ -24,7 +24,7 @@ pub struct Scope {
home: ModuleId, home: ModuleId,
exposed_ident_ids: IdentIds, exposed_ident_ids: IdentIds,
all_ident_ids: IdentIds, pub ident_ids: IdentIds,
} }
fn add_aliases(var_store: &mut VarStore) -> SendMap<Symbol, Alias> { fn add_aliases(var_store: &mut VarStore) -> SendMap<Symbol, Alias> {
@ -71,7 +71,7 @@ impl Scope {
pub fn new(home: ModuleId, _var_store: &mut VarStore, initial_ident_ids: IdentIds) -> Scope { pub fn new(home: ModuleId, _var_store: &mut VarStore, initial_ident_ids: IdentIds) -> Scope {
Scope { Scope {
home, home,
all_ident_ids: initial_ident_ids.clone(), ident_ids: initial_ident_ids.clone(),
exposed_ident_ids: initial_ident_ids, exposed_ident_ids: initial_ident_ids,
idents: IdentStore::new(), idents: IdentStore::new(),
aliases: SendMap::default(), aliases: SendMap::default(),
@ -87,7 +87,7 @@ impl Scope {
) -> Scope { ) -> Scope {
Scope { Scope {
home, home,
all_ident_ids: initial_ident_ids.clone(), ident_ids: initial_ident_ids.clone(),
exposed_ident_ids: initial_ident_ids, exposed_ident_ids: initial_ident_ids,
idents: IdentStore::new(), idents: IdentStore::new(),
aliases: add_aliases(var_store), aliases: add_aliases(var_store),
@ -202,13 +202,12 @@ impl Scope {
pub fn introduce( pub fn introduce(
&mut self, &mut self,
ident: Ident, ident: Ident,
all_ident_ids: &mut IdentIds,
region: Region, region: Region,
) -> Result<Symbol, (Region, Loc<Ident>, Symbol)> { ) -> Result<Symbol, (Region, Loc<Ident>, Symbol)> {
match self.introduce_without_shadow_symbol(&ident, all_ident_ids, region) { match self.introduce_without_shadow_symbol(&ident, region) {
Ok(symbol) => Ok(symbol), Ok(symbol) => Ok(symbol),
Err((original_region, shadow)) => { Err((original_region, shadow)) => {
let ident_id = all_ident_ids.add_ident(&ident); let ident_id = self.ident_ids.add_ident(&ident);
let symbol = Symbol::new(self.home, ident_id); let symbol = Symbol::new(self.home, ident_id);
Err((original_region, shadow, symbol)) Err((original_region, shadow, symbol))
@ -220,7 +219,6 @@ impl Scope {
pub fn introduce_without_shadow_symbol( pub fn introduce_without_shadow_symbol(
&mut self, &mut self,
ident: &Ident, ident: &Ident,
all_ident_ids: &mut IdentIds,
region: Region, region: Region,
) -> Result<Symbol, (Region, Loc<Ident>)> { ) -> Result<Symbol, (Region, Loc<Ident>)> {
match self.idents.get_symbol_and_region(ident) { match self.idents.get_symbol_and_region(ident) {
@ -231,7 +229,7 @@ impl Scope {
}; };
Err((original_region, shadow)) Err((original_region, shadow))
} }
None => Ok(self.commit_introduction(ident, all_ident_ids, region)), None => Ok(self.commit_introduction(ident, region)),
} }
} }
@ -245,7 +243,6 @@ impl Scope {
pub fn introduce_or_shadow_ability_member( pub fn introduce_or_shadow_ability_member(
&mut self, &mut self,
ident: Ident, ident: Ident,
all_ident_ids: &mut IdentIds,
region: Region, region: Region,
) -> Result<(Symbol, Option<Symbol>), (Region, Loc<Ident>, Symbol)> { ) -> Result<(Symbol, Option<Symbol>), (Region, Loc<Ident>, Symbol)> {
match self.idents.get_index(&ident) { match self.idents.get_index(&ident) {
@ -253,7 +250,7 @@ impl Scope {
let original_symbol = self.idents.symbols[index]; let original_symbol = self.idents.symbols[index];
let original_region = self.idents.regions[index]; let original_region = self.idents.regions[index];
let shadow_ident_id = all_ident_ids.add_ident(&ident); let shadow_ident_id = self.ident_ids.add_ident(&ident);
let shadow_symbol = Symbol::new(self.home, shadow_ident_id); let shadow_symbol = Symbol::new(self.home, shadow_ident_id);
if self.abilities_store.is_ability_member_name(original_symbol) { if self.abilities_store.is_ability_member_name(original_symbol) {
@ -276,24 +273,19 @@ impl Scope {
} }
} }
None => { None => {
let new_symbol = self.commit_introduction(&ident, all_ident_ids, region); let new_symbol = self.commit_introduction(&ident, region);
Ok((new_symbol, None)) Ok((new_symbol, None))
} }
} }
} }
fn commit_introduction( fn commit_introduction(&mut self, ident: &Ident, region: Region) -> Symbol {
&mut self,
ident: &Ident,
all_ident_ids: &mut IdentIds,
region: Region,
) -> Symbol {
// If this IdentId was already added previously // If this IdentId was already added previously
// when the value was exposed in the module header, // when the value was exposed in the module header,
// use that existing IdentId. Otherwise, create a fresh one. // use that existing IdentId. Otherwise, create a fresh one.
let ident_id = match self.exposed_ident_ids.get_id(ident) { let ident_id = match self.exposed_ident_ids.get_id(ident) {
Some(ident_id) => ident_id, Some(ident_id) => ident_id,
None => all_ident_ids.add_ident(ident), None => self.ident_ids.add_ident(ident),
}; };
let symbol = Symbol::new(self.home, ident_id); let symbol = Symbol::new(self.home, ident_id);
@ -306,8 +298,8 @@ impl Scope {
/// Ignore an identifier. /// Ignore an identifier.
/// ///
/// Used for record guards like { x: Just _ } /// Used for record guards like { x: Just _ }
pub fn ignore(&mut self, ident: &Ident, all_ident_ids: &mut IdentIds) -> Symbol { pub fn ignore(&mut self, ident: &Ident) -> Symbol {
let ident_id = all_ident_ids.add_ident(ident); let ident_id = self.ident_ids.add_ident(ident);
Symbol::new(self.home, ident_id) Symbol::new(self.home, ident_id)
} }
@ -365,6 +357,21 @@ impl Scope {
result result
} }
pub fn register_debug_idents(&self) {
self.home.register_debug_idents(&self.ident_ids)
}
/// Generates a unique, new symbol like "$1" or "$5",
/// using the home module as the module_id.
///
/// This is used, for example, during canonicalization of an Expr::Closure
/// to generate a unique symbol to refer to that closure.
pub fn gen_unique_symbol(&mut self) -> Symbol {
let ident_id = self.ident_ids.gen_unique();
Symbol::new(self.home, ident_id)
}
} }
pub fn create_alias( pub fn create_alias(

View file

@ -55,7 +55,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
// rules multiple times unnecessarily. // rules multiple times unnecessarily.
let loc_expr = operator::desugar_expr(arena, &loc_expr); let loc_expr = operator::desugar_expr(arena, &loc_expr);
let mut scope = Scope::new(home, &mut var_store, dep_idents.clone()); let mut scope = Scope::new(home, &mut var_store, IdentIds::default());
scope.add_alias( scope.add_alias(
Symbol::NUM_INT, Symbol::NUM_INT,
Region::zero(), Region::zero(),
@ -75,7 +75,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
); );
let mut all_ident_ids = IdentIds::exposed_builtins(1); let mut all_ident_ids = IdentIds::exposed_builtins(1);
all_ident_ids.insert(home, env.ident_ids); all_ident_ids.insert(home, scope.ident_ids);
let interns = Interns { let interns = Interns {
module_ids: env.module_ids.clone(), module_ids: env.module_ids.clone(),

View file

@ -184,7 +184,7 @@ pub fn can_expr_with<'a>(
introduce_builtin_imports(&mut constraints, imports, constraint, &mut var_store); introduce_builtin_imports(&mut constraints, imports, constraint, &mut var_store);
let mut all_ident_ids = IdentIds::exposed_builtins(1); let mut all_ident_ids = IdentIds::exposed_builtins(1);
all_ident_ids.insert(home, env.ident_ids); all_ident_ids.insert(home, scope.ident_ids);
let interns = Interns { let interns = Interns {
module_ids: env.module_ids.clone(), module_ids: env.module_ids.clone(),