diff --git a/ast/src/lang/scope.rs b/ast/src/lang/scope.rs index ced87957e4..8cd657f7f9 100644 --- a/ast/src/lang/scope.rs +++ b/ast/src/lang/scope.rs @@ -246,7 +246,7 @@ impl Scope { // use that existing IdentId. Otherwise, create a fresh one. let ident_id = match exposed_ident_ids.get_id(&ident) { Some(ident_id) => ident_id, - None => all_ident_ids.add_ident(&ident), + None => all_ident_ids.add_str(ident.as_str()), }; let symbol = Symbol::new(self.home, ident_id); @@ -263,7 +263,7 @@ impl Scope { /// /// Used for record guards like { x: Just _ } pub fn ignore(&mut self, ident: Ident, all_ident_ids: &mut IdentIds) -> Symbol { - let ident_id = all_ident_ids.add_ident(&ident); + let ident_id = all_ident_ids.add_str(ident.as_str()); Symbol::new(self.home, ident_id) } diff --git a/compiler/can/src/pattern.rs b/compiler/can/src/pattern.rs index b4590a7e24..ca4b77ca39 100644 --- a/compiler/can/src/pattern.rs +++ b/compiler/can/src/pattern.rs @@ -288,7 +288,7 @@ pub fn canonicalize_pattern<'a>( use PatternType::*; let can_pattern = match pattern { - Identifier(name) => match scope.introduce((*name).into(), region) { + Identifier(name) => match scope.introduce_str(name, region) { Ok(symbol) => { output.references.insert_bound(symbol); diff --git a/compiler/can/src/scope.rs b/compiler/can/src/scope.rs index 4db2f54246..b51af4821c 100644 --- a/compiler/can/src/scope.rs +++ b/compiler/can/src/scope.rs @@ -53,7 +53,7 @@ impl Scope { pub fn lookup(&self, ident: &Ident, region: Region) -> Result { use ContainsIdent::*; - match self.scope_contains_ident(ident) { + match self.scope_contains_ident(ident.as_str()) { InScope(symbol, _) => Ok(symbol), NotInScope(_) | NotPresent => { let error = RuntimeError::LookupNotInScope( @@ -85,7 +85,8 @@ impl Scope { lookup_region: Region, ) -> Result<(Symbol, &Alias), RuntimeError> { debug_assert!(opaque_ref.starts_with('@')); - let opaque = opaque_ref[1..].into(); + let opaque_str = &opaque_ref[1..]; + let opaque = opaque_str.into(); match self.locals.has_in_scope(&opaque) { Some((symbol, _)) => match self.lookup_opaque_alias(symbol) { @@ -96,7 +97,7 @@ impl Scope { }, None => { // opaque types can only be wrapped/unwrapped in the scope they are defined in (and below) - let error = if let Some((_, decl_region)) = self.has_imported(&opaque) { + let error = if let Some((_, decl_region)) = self.has_imported(opaque_str) { // specific error for when the opaque is imported, which definitely does not work RuntimeError::OpaqueOutsideScope { opaque, @@ -159,9 +160,9 @@ impl Scope { } } - fn has_imported(&self, ident: &Ident) -> Option<(Symbol, Region)> { + fn has_imported(&self, ident: &str) -> Option<(Symbol, Region)> { for (import, shadow, original_region) in self.imports.iter() { - if ident == import { + if ident == import.as_str() { return Some((*shadow, *original_region)); } } @@ -170,7 +171,7 @@ impl Scope { } /// Is an identifier in scope, either in the locals or imports - fn scope_contains_ident(&self, ident: &Ident) -> ContainsIdent { + fn scope_contains_ident(&self, ident: &str) -> ContainsIdent { // exposed imports are likely to be small match self.has_imported(ident) { Some((symbol, region)) => ContainsIdent::InScope(symbol, region), @@ -178,11 +179,7 @@ impl Scope { } } - fn introduce_help( - &mut self, - ident: &Ident, - region: Region, - ) -> Result { + fn introduce_help(&mut self, ident: &str, region: Region) -> Result { match self.scope_contains_ident(ident) { ContainsIdent::InScope(original_symbol, original_region) => { // the ident is already in scope; up to the caller how to handle that @@ -229,10 +226,22 @@ impl Scope { ident: Ident, region: Region, ) -> Result, Symbol)> { - match self.introduce_without_shadow_symbol(&ident, region) { + self.introduce_str(ident.as_str(), region) + } + + pub fn introduce_str( + &mut self, + ident: &str, + region: Region, + ) -> Result, Symbol)> { + match self.introduce_help(ident, region) { Ok(symbol) => Ok(symbol), - Err((original_region, shadow)) => { - let symbol = self.scopeless_symbol(&ident, region); + Err((_, original_region)) => { + let shadow = Loc { + value: Ident::from(ident), + region, + }; + let symbol = self.locals.scopeless_symbol(ident, region); Err((original_region, shadow, symbol)) } @@ -245,7 +254,7 @@ impl Scope { ident: &Ident, region: Region, ) -> Result)> { - match self.introduce_help(ident, region) { + match self.introduce_help(ident.as_str(), region) { Err((_, original_region)) => { let shadow = Loc { value: ident.clone(), @@ -271,7 +280,7 @@ impl Scope { ) -> Result<(Symbol, Option), (Region, Loc, Symbol)> { let ident = &ident; - match self.introduce_help(ident, region) { + match self.introduce_help(ident.as_str(), region) { Err((original_symbol, original_region)) => { let shadow_symbol = self.scopeless_symbol(ident, region); @@ -300,7 +309,7 @@ impl Scope { /// but also in other places where we need to create a symbol and we don't have the right /// scope information yet. An identifier can be introduced later, and will use the same IdentId pub fn scopeless_symbol(&mut self, ident: &Ident, region: Region) -> Symbol { - self.locals.scopeless_symbol(ident, region) + self.locals.scopeless_symbol(ident.as_str(), region) } /// Import a Symbol from another module into this module's top-level scope. @@ -313,7 +322,7 @@ impl Scope { symbol: Symbol, region: Region, ) -> Result<(), (Symbol, Region)> { - if let Some((s, r)) = self.has_imported(&ident) { + if let Some((s, r)) = self.has_imported(ident.as_str()) { return Err((s, r)); } @@ -463,13 +472,13 @@ impl ScopedIdentIds { } fn has_in_scope(&self, ident: &Ident) -> Option<(Symbol, Region)> { - match self.contains_ident(ident) { + match self.contains_ident(ident.as_str()) { ContainsIdent::InScope(symbol, region) => Some((symbol, region)), ContainsIdent::NotInScope(_) | ContainsIdent::NotPresent => None, } } - fn contains_ident(&self, ident: &Ident) -> ContainsIdent { + fn contains_ident(&self, ident: &str) -> ContainsIdent { use ContainsIdent::*; let mut result = NotPresent; @@ -499,8 +508,8 @@ impl ScopedIdentIds { }) } - fn introduce_into_scope(&mut self, ident_name: &Ident, region: Region) -> IdentId { - let id = self.ident_ids.add_ident(ident_name); + fn introduce_into_scope(&mut self, ident_name: &str, region: Region) -> IdentId { + let id = self.ident_ids.add_str(ident_name); debug_assert_eq!(id.index(), self.in_scope.len()); debug_assert_eq!(id.index(), self.regions.len()); @@ -524,8 +533,8 @@ impl ScopedIdentIds { } /// Adds an IdentId, but does not introduce it to the scope - fn scopeless_symbol(&mut self, ident_name: &Ident, region: Region) -> Symbol { - let id = self.ident_ids.add_ident(ident_name); + fn scopeless_symbol(&mut self, ident_name: &str, region: Region) -> Symbol { + let id = self.ident_ids.add_str(ident_name); debug_assert_eq!(id.index(), self.in_scope.len()); debug_assert_eq!(id.index(), self.regions.len()); diff --git a/compiler/collections/src/small_string_interner.rs b/compiler/collections/src/small_string_interner.rs index 6b91136c13..37f396ad96 100644 --- a/compiler/collections/src/small_string_interner.rs +++ b/compiler/collections/src/small_string_interner.rs @@ -25,7 +25,7 @@ impl Length { #[inline(always)] const fn kind(self) -> Kind { if self.0 == 0 { - Kind::Emtpy + Kind::Empty } else if self.0 > 0 { Kind::Interned(self.0 as usize) } else { @@ -41,7 +41,7 @@ impl Length { enum Kind { Generated(usize), - Emtpy, + Empty, Interned(usize), } @@ -49,7 +49,7 @@ impl Debug for Kind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Generated(arg0) => write!(f, "Generated({})", arg0), - Self::Emtpy => write!(f, "Emtpy"), + Self::Empty => write!(f, "Emtpy"), Self::Interned(arg0) => write!(f, "Interned({})", arg0), } } @@ -174,7 +174,7 @@ impl SmallStringInterner { .enumerate() .filter_map(move |(index, length)| match length.kind() { Kind::Generated(_) => None, - Kind::Emtpy => { + Kind::Empty => { if target_length == 0 { Some(index) } else { @@ -198,7 +198,7 @@ impl SmallStringInterner { fn get(&self, index: usize) -> &str { match self.lengths[index].kind() { - Kind::Emtpy => "", + Kind::Empty => "", Kind::Generated(length) | Kind::Interned(length) => { let offset = self.offsets[index] as usize; diff --git a/compiler/gen_wasm/src/backend.rs b/compiler/gen_wasm/src/backend.rs index 3654696cc6..2d38016a1c 100644 --- a/compiler/gen_wasm/src/backend.rs +++ b/compiler/gen_wasm/src/backend.rs @@ -4,7 +4,6 @@ use std::fmt::Write; use code_builder::Align; use roc_builtins::bitcode::{FloatWidth, IntWidth}; use roc_collections::all::MutMap; -use roc_module::ident::Ident; use roc_module::low_level::{LowLevel, LowLevelWrapperType}; use roc_module::symbol::{Interns, Symbol}; use roc_mono::code_gen_help::{CodeGenHelp, HelperOp, REFCOUNT_MAX}; @@ -183,7 +182,7 @@ impl<'a> WasmBackend<'a> { .get_mut(&self.env.module_id) .unwrap(); - let ident_id = ident_ids.add_ident(&Ident::from(debug_name)); + let ident_id = ident_ids.add_str(debug_name); Symbol::new(self.env.module_id, ident_id) } diff --git a/compiler/load_internal/src/file.rs b/compiler/load_internal/src/file.rs index 11edbb4913..b28ed53e2a 100644 --- a/compiler/load_internal/src/file.rs +++ b/compiler/load_internal/src/file.rs @@ -1106,7 +1106,7 @@ pub fn load<'a>( ) -> Result, LoadingProblem<'a>> { // When compiling to wasm, we cannot spawn extra threads // so we have a single-threaded implementation - if cfg!(target_family = "wasm") { + if true || cfg!(target_family = "wasm") { load_single_threaded( arena, load_start, diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index 7b09d04532..0619e3c3d6 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -543,7 +543,11 @@ impl IdentIds { } pub fn add_ident(&mut self, ident_name: &Ident) -> IdentId { - IdentId(self.interner.insert(ident_name.as_str()) as u32) + self.add_str(ident_name.as_str()) + } + + pub fn add_str(&mut self, ident_name: &str) -> IdentId { + IdentId(self.interner.insert(ident_name) as u32) } pub fn duplicate_ident(&mut self, ident_id: IdentId) -> IdentId { @@ -553,7 +557,7 @@ impl IdentIds { pub fn get_or_insert(&mut self, name: &Ident) -> IdentId { match self.get_id(name) { Some(id) => id, - None => self.add_ident(name), + None => self.add_str(name.as_str()), } } @@ -585,9 +589,9 @@ impl IdentIds { } #[inline(always)] - pub fn get_id_many<'a>(&'a self, ident_name: &'a Ident) -> impl Iterator + 'a { + pub fn get_id_many<'a>(&'a self, ident_name: &'a str) -> impl Iterator + 'a { self.interner - .find_indices(ident_name.as_str()) + .find_indices(ident_name) .map(|i| IdentId(i as u32)) } diff --git a/compiler/mono/src/code_gen_help/mod.rs b/compiler/mono/src/code_gen_help/mod.rs index 68361fd267..7c5cb3eecc 100644 --- a/compiler/mono/src/code_gen_help/mod.rs +++ b/compiler/mono/src/code_gen_help/mod.rs @@ -1,6 +1,5 @@ use bumpalo::collections::vec::Vec; use bumpalo::Bump; -use roc_module::ident::Ident; use roc_module::low_level::LowLevel; use roc_module::symbol::{IdentIds, ModuleId, Symbol}; use roc_target::TargetInfo; @@ -396,7 +395,7 @@ impl<'a> CodeGenHelp<'a> { } fn create_symbol(&self, ident_ids: &mut IdentIds, debug_name: &str) -> Symbol { - let ident_id = ident_ids.add_ident(&Ident::from(debug_name)); + let ident_id = ident_ids.add_str(debug_name); Symbol::new(self.home, ident_id) } diff --git a/editor/src/editor/mvc/let_update.rs b/editor/src/editor/mvc/let_update.rs index b9a734b8f4..482b5d4c9a 100644 --- a/editor/src/editor/mvc/let_update.rs +++ b/editor/src/editor/mvc/let_update.rs @@ -1,7 +1,6 @@ use roc_ast::lang::core::expr::expr2::Expr2; use roc_ast::lang::core::pattern::Pattern2; use roc_ast::lang::core::val_def::ValueDef; -use roc_module::ident::Ident; use roc_module::symbol::Symbol; use crate::editor::ed_error::EdResult; @@ -26,8 +25,7 @@ pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult< let val_expr2_node = Expr2::Blank; let val_expr_id = ed_model.module.env.pool.add(val_expr2_node); - let ident = Ident::from(val_name_string); - let ident_id = ed_model.module.env.ident_ids.add_ident(&ident); + let ident_id = ed_model.module.env.ident_ids.add_str(&val_name_string); let var_symbol = Symbol::new(ed_model.module.env.home, ident_id); let body = Expr2::Var(var_symbol); let body_id = ed_model.module.env.pool.add(body); diff --git a/editor/src/editor/mvc/tld_value_update.rs b/editor/src/editor/mvc/tld_value_update.rs index 3afaafdcf8..72323b25c2 100644 --- a/editor/src/editor/mvc/tld_value_update.rs +++ b/editor/src/editor/mvc/tld_value_update.rs @@ -1,6 +1,5 @@ use roc_ast::lang::core::{def::def2::Def2, expr::expr2::Expr2}; use roc_code_markup::slow_pool::MarkNodeId; -use roc_module::ident::Ident; use crate::{ editor::ed_error::{EdResult, FailedToUpdateIdentIdName, KeyNotFound}, @@ -27,8 +26,8 @@ pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult< let val_expr_node = Expr2::Blank; let val_expr_id = ed_model.module.env.pool.add(val_expr_node); - let ident = Ident::from(new_char.to_string().as_str()); - let ident_id = ed_model.module.env.ident_ids.add_ident(&ident); + let ident_str = new_char.to_string(); + let ident_id = ed_model.module.env.ident_ids.add_str(&ident_str); let module_ident_ids_opt = ed_model .loaded_module @@ -38,7 +37,7 @@ pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult< if let Some(module_ident_ids_ref) = module_ident_ids_opt { // this might create different IdentId for interns and env.ident_ids which may be a problem - module_ident_ids_ref.add_ident(&ident); + module_ident_ids_ref.add_str(&ident_str); } else { KeyNotFound { key_str: format!("{:?}", ed_model.module.env.home), diff --git a/examples/hello-world/helloWorld.roc b/examples/hello-world/helloWorld.roc index 2381655195..40f354147d 100644 --- a/examples/hello-world/helloWorld.roc +++ b/examples/hello-world/helloWorld.roc @@ -8,15 +8,4 @@ app "helloWorld" imports [] provides [ main ] to pf -a = - foobar = "Hello" - - foobar - -b = - foobar = "World" - - foobar - -# main = "Hello, World!\n" -main = Str.concat a b +main = "Hello, World!\n"