diff --git a/cli/src/main.rs b/cli/src/main.rs index 0be3741de3..3a069935d1 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -307,12 +307,15 @@ fn gen( let loc_expr = main_expr.unwrap_or_else(|| { panic!("TODO gracefully handle the case where `main` was declared but not exposed") }); + let mut subs = loaded.solved.into_inner(); let content = match main_var { Some(var) => subs.get_without_compacting(var).content, None => todo!("TODO gracefully handle the case where `main` was declared but not exposed"), }; + todo!("step 1. mono-module, step 2. actually have main here use the loaded builtin modules!"); + // Generate the binary let context = Context::create(); diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index 00d7266c9e..9339b28659 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -1,13 +1,27 @@ -use crate::def::Def; -use crate::expr::Expr; -use crate::expr::Recursive; -use roc_collections::all::SendMap; +use crate::def::{Declaration, Def}; +use crate::expr::{Expr, Recursive}; +use roc_collections::all::{MutMap, MutSet, SendMap}; use roc_module::ident::TagName; -use roc_module::symbol::Symbol; +use roc_module::symbol::{ModuleId, Symbol}; use roc_parse::operator::CalledVia; use roc_region::all::{Located, Region}; use roc_types::subs::{VarStore, Variable}; +fn exposed_symbols() -> MutMap> { + let mut all = MutMap::default(); // TODO use with_capacity_and_hasher here + + all.insert(ModuleId::LIST, { + let mut set = MutSet::default(); // TODO use with_capacity_and_hasher here + + set.insert(Symbol::LIST_GET); + set.insert(Symbol::LIST_FIRST); + + set + }); + + all +} + /// Some builtins cannot be constructed in code gen alone, and need to be defined /// as separate Roc defs. For example, List.get has this type: /// @@ -25,16 +39,24 @@ use roc_types::subs::{VarStore, Variable}; /// delegates to the compiler-internal List.getUnsafe function to do the actual /// lookup (if the bounds check passed). That internal function is hardcoded in code gen, /// which works fine because it doesn't involve any open tag unions. -pub fn builtin_defs(var_store: &VarStore) -> Vec { - vec![ - list_get(var_store), - list_first(var_store), - int_div(var_store), - ] +pub fn declarations_by_id() -> MutMap> { + let var_store = VarStore::default(); + let mut decls = MutMap::default(); // TODO use with_capacity_and_hasher here + + decls.insert( + ModuleId::LIST, + vec![ + list_get(&var_store), + list_first(&var_store), + int_div(&var_store), + ], + ); + + decls } /// List.get : List elem, Int -> Result elem [ OutOfBounds ]* -fn list_get(var_store: &VarStore) -> Def { +fn list_get(var_store: &VarStore) -> Declaration { use crate::expr::Expr::*; defn( @@ -105,7 +127,7 @@ fn list_get(var_store: &VarStore) -> Def { } /// Int.div : Int, Int -> Result Int [ DivByZero ]* -fn int_div(var_store: &VarStore) -> Def { +fn int_div(var_store: &VarStore) -> Declaration { use crate::expr::Expr::*; use crate::pattern::Pattern::*; @@ -174,17 +196,17 @@ fn int_div(var_store: &VarStore) -> Def { Box::new((no_region(body), var_store.fresh())), ); - Def { + Declare(Def { loc_pattern: no_region(Identifier(Symbol::INT_DIV)), loc_expr: no_region(expr), expr_var: var_store.fresh(), pattern_vars: SendMap::default(), annotation: None, - } + }) } /// List.first : List elem -> Result elem [ ListWasEmpty ]* -fn list_first(var_store: &VarStore) -> Def { +fn list_first(var_store: &VarStore) -> Declaration { use crate::expr::Expr::*; defn( @@ -276,7 +298,7 @@ fn call(symbol: Symbol, args: Vec, var_store: &VarStore) -> Expr { } #[inline(always)] -fn defn(fn_name: Symbol, args: Vec, var_store: &VarStore, body: Expr) -> Def { +fn defn(fn_name: Symbol, args: Vec, var_store: &VarStore, body: Expr) -> Declaration { use crate::expr::Expr::*; use crate::pattern::Pattern::*; @@ -293,11 +315,11 @@ fn defn(fn_name: Symbol, args: Vec, var_store: &VarStore, body: Expr) -> Box::new((no_region(body), var_store.fresh())), ); - Def { + Declaration::Declare(Def { loc_pattern: no_region(Identifier(fn_name)), loc_expr: no_region(expr), expr_var: var_store.fresh(), pattern_vars: SendMap::default(), annotation: None, - } + }) } diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 6b7687f70c..69cc3d2539 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -193,8 +193,7 @@ pub async fn load<'a>( loading_started.insert(root_id); // The declarations we'll ultimately be returning - let mut declarations_by_id: MutMap> = MutMap::default(); - + let mut declarations_by_id: MutMap> = roc_can::builtins::declarations_by_id(); let mut exposed_symbols_by_module: MutMap> = MutMap::default(); // Modules which are waiting for certain headers to be parsed @@ -469,8 +468,11 @@ pub async fn load<'a>( stdlib, ); - for _unused_module_id in unused_modules.iter() { - panic!("TODO gracefully report unused imports for {:?}, namely {:?}", home, unused_modules); + for unused_module_id in unused_modules.iter() { + // Never report builtin modules as unused + if !unused_module_id.is_builtin() { + todo!("TODO gracefully report unused imports for {:?}, namely {:?}", home, unused_modules); + } } } } @@ -581,7 +583,7 @@ fn send_header<'a>( // If it isn't, report a problem! let mut imported: Vec<(ModuleName, Vec, Region)> = Vec::with_capacity(imports.len()); - let mut imported_modules: MutSet = MutSet::default(); + let mut imported_modules: MutSet = ModuleId::default_imports(); let mut scope_size = 0; for loc_entry in imports { diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index bb2c11ff2d..1d270d6b79 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -1,8 +1,8 @@ use crate::ident::Ident; use inlinable_string::InlinableString; -use roc_collections::all::{default_hasher, ImMap, MutMap}; +use roc_collections::all::{default_hasher, ImMap, MutMap, MutSet}; use roc_region::all::Region; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::{fmt, u32}; // TODO: benchmark this as { ident_id: u32, module_id: u32 } and see if perf stays the same @@ -496,6 +496,16 @@ macro_rules! define_builtins { self.0 < $total } + pub fn default_imports() -> MutSet { + let mut all = HashSet::with_capacity_and_hasher($total, default_hasher()); + + $( + all.insert(ModuleId($module_id)); + )+ + + all + } + $( pub const $module_const: ModuleId = ModuleId($module_id); )+