diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 570341ac5d..2cfe40f489 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -690,6 +690,7 @@ enum Msg<'a> { #[derive(Debug)] struct State<'a> { pub root_id: ModuleId, + pub platform_id: Option, pub goal_phase: Phase, pub stdlib: StdLib, pub exposed_types: SubsByModule, @@ -844,12 +845,6 @@ enum BuildTask<'a> { ident_ids_by_module: Arc>>, mode: Mode, }, - LoadPkgConfig { - shorthand: &'a str, - module_ids: Arc>>, - ident_ids_by_module: Arc>>, - mode: Mode, - }, Parse { header: ModuleHeader<'a>, }, @@ -1272,6 +1267,7 @@ where let mut state = State { root_id, + platform_id: None, goal_phase, stdlib, output_path: None, @@ -1426,6 +1422,10 @@ fn update<'a>( } } + if let ModuleNameEnum::PkgConfig(_shorthand) = header.module_name { + state.platform_id = Some(header.module_id); + } + state.platform_path = state.platform_path.or_else(|| header.to_platform.clone()); // store an ID to name mapping, so we know the file to read when fetching dependencies' headers @@ -1603,7 +1603,7 @@ fn update<'a>( let work = state.dependencies.notify(module_id, Phase::SolveTypes); - if module_id == state.root_id { + if Some(module_id) == state.platform_id { state .exposed_to_host .extend(solved_module.exposed_vars_by_symbol.iter().copied()); @@ -1638,15 +1638,10 @@ fn update<'a>( // the originally requested module, we're all done! return Ok(state); } else { - if module_id != state.root_id { - state.exposed_types.insert( - module_id, - ExposedModuleTypes::Valid( - solved_module.solved_types, - solved_module.aliases, - ), - ); - } + state.exposed_types.insert( + module_id, + ExposedModuleTypes::Valid(solved_module.solved_types, solved_module.aliases), + ); if state.goal_phase > Phase::SolveTypes { let layout_cache = state.layout_caches.pop().unwrap_or_default(); @@ -1914,6 +1909,7 @@ fn load_pkg_config<'a>( arena: &'a Bump, src_dir: &Path, shorthand: &'a str, + app_module_id: ModuleId, module_ids: Arc>>, ident_ids_by_module: Arc>>, mode: Mode, @@ -1961,6 +1957,7 @@ fn load_pkg_config<'a>( let pkg_config_module_msg = fabricate_pkg_config_module( arena, shorthand, + app_module_id, filename, parser_state, module_ids.clone(), @@ -2183,6 +2180,7 @@ fn parse_header<'a>( arena, &pkg_config_roc, shorthand, + module_id, module_ids, ident_ids_by_module, mode, @@ -2488,10 +2486,13 @@ fn send_header<'a>( #[allow(clippy::too_many_arguments)] fn send_header_two<'a>( + arena: &'a Bump, filename: PathBuf, shorthand: &'a str, + app_module_id: ModuleId, packages: &'a [Located>], provides: &'a [Located>], + requires: &'a [Located>], imports: &'a [Located>], to_platform: Option>, parse_state: parser::State<'a>, @@ -2501,15 +2502,23 @@ fn send_header_two<'a>( ) -> (ModuleId, Msg<'a>) { use inlinable_string::InlinableString; - let declared_name: InlinableString = "Pkg-Config".into(); + let declared_name: InlinableString = "".into(); let mut imported: Vec<(QualifiedModuleName, Vec, Region)> = Vec::with_capacity(imports.len()); let mut imported_modules: MutSet = MutSet::default(); + let num_exposes = provides.len(); + let mut deps_by_name: MutMap = + HashMap::with_capacity_and_hasher(num_exposes, default_hasher()); + // add standard imports - // imported_modules.insert(ModuleId::APP); - // imported_modules.insert(ModuleId::EFFECT); + // TODO add Effect by default + imported_modules.insert(app_module_id); + deps_by_name.insert( + PQModuleName::Unqualified(ModuleName::APP.into()), + app_module_id, + ); let mut scope_size = 0; @@ -2521,9 +2530,6 @@ fn send_header_two<'a>( imported.push((qualified_module_name, exposed, loc_entry.region)); } - let num_exposes = provides.len(); - let mut deps_by_name: MutMap = - HashMap::with_capacity_and_hasher(num_exposes, default_hasher()); let mut exposed: Vec = Vec::with_capacity(num_exposes); // Make sure the module_ids has ModuleIds for all our deps, @@ -2582,6 +2588,23 @@ fn send_header_two<'a>( } } + { + let ident_ids = ident_ids_by_module + .entry(app_module_id) + .or_insert_with(IdentIds::default); + + for (loc_ident, _) in unpack_exposes_entries(arena, requires) { + let ident: Ident = loc_ident.value.into(); + let ident_id = ident_ids.get_or_insert(ident.as_inline_str()); + let symbol = Symbol::new(app_module_id, ident_id); + + // Since this value is exposed, add it to our module's default scope. + debug_assert!(!scope.contains_key(&ident.clone())); + + scope.insert(ident, (symbol, loc_ident.region)); + } + } + let ident_ids = ident_ids_by_module.get_mut(&home).unwrap(); // Generate IdentIds entries for all values this module exposes. @@ -2771,24 +2794,26 @@ fn run_solve<'a>( fn fabricate_pkg_config_module<'a>( arena: &'a Bump, shorthand: &'a str, + app_module_id: ModuleId, filename: PathBuf, parse_state: parser::State<'a>, module_ids: Arc>>, ident_ids_by_module: Arc>>, - mode: Mode, + _mode: Mode, header: &PlatformHeader<'a>, module_timing: ModuleTiming, ) -> Result<(ModuleId, Msg<'a>), LoadingProblem> { - let name = format!("{}.Pkg-Config", shorthand); - let provides: &'a [Located>] = header.provides.clone().into_bump_slice(); Ok(send_header_two( + arena, filename, shorthand, + app_module_id, &[], provides, + header.requires.clone().into_bump_slice(), header.imports.clone().into_bump_slice(), None, parse_state, @@ -3545,19 +3570,6 @@ fn run_task<'a>( mode, ) .map(|(_, msg)| msg), - LoadPkgConfig { - shorthand, - module_ids, - ident_ids_by_module, - mode, - } => load_pkg_config( - arena, - src_dir, - shorthand, - module_ids, - ident_ids_by_module, - mode, - ), Parse { header } => parse(arena, header), CanonicalizeAndConstrain { parsed, diff --git a/examples/task/Main.roc b/examples/task/Main.roc index f0f346d294..6ab3406342 100644 --- a/examples/task/Main.roc +++ b/examples/task/Main.roc @@ -3,6 +3,6 @@ app "effect-example" imports [ base.Task.{ Task, after } ] provides [ main ] to base -main : Task.Task {} I64 as Fx +main : Task.Task {} I64 main = Task.succeed {} diff --git a/examples/task/platform/Pkg-Config.roc b/examples/task/platform/Pkg-Config.roc index af963e5cbd..23d36a3455 100644 --- a/examples/task/platform/Pkg-Config.roc +++ b/examples/task/platform/Pkg-Config.roc @@ -2,7 +2,7 @@ platform folkertdev/foo requires { main : Effect {} } exposes [] packages {} - imports [ Effect ] + imports [ Task ] provides [ mainForHost ] effects Effect { @@ -10,5 +10,5 @@ platform folkertdev/foo readAllUtf8 : Str -> Effect { errno : I64, bytes : Str } } -mainForHost : Effect.Effect {} as Fx -mainForHost = UserApp.main +mainForHost : Task.Task {} I64 as Fx +mainForHost = main diff --git a/examples/task/platform/host.zig b/examples/task/platform/host.zig index 5de36ec6b3..682fe07296 100644 --- a/examples/task/platform/host.zig +++ b/examples/task/platform/host.zig @@ -2,15 +2,15 @@ const std = @import("std"); const str = @import("../../../compiler/builtins/bitcode/src/str.zig"); const testing = std.testing; -extern fn roc__main_1_exposed([*]u8) void; -extern fn roc__main_1_size() i64; -extern fn roc__main_1_Fx_caller(*const u8, [*]u8, [*]u8) void; -extern fn roc__main_1_Fx_size() i64; +extern fn roc__mainForHost_1_exposed([*]u8) void; +extern fn roc__mainForHost_1_size() i64; +extern fn roc__mainForHost_1_Fx_caller(*const u8, [*]u8, [*]u8) void; +extern fn roc__mainForHost_1_Fx_size() i64; pub export fn main() u8 { const stdout = std.io.getStdOut().writer(); - const size = @intCast(usize, roc__main_1_size()); + const size = @intCast(usize, roc__mainForHost_1_size()); const raw_output = std.heap.c_allocator.alloc(u8, size) catch unreachable; var output = @ptrCast([*]u8, raw_output); @@ -18,7 +18,7 @@ pub export fn main() u8 { std.heap.c_allocator.free(raw_output); } - roc__main_1_exposed(output); + roc__mainForHost_1_exposed(output); const elements = @ptrCast([*]u64, @alignCast(8, output)); @@ -38,7 +38,7 @@ pub export fn main() u8 { } fn call_the_closure(function_pointer: *const u8, closure_data_pointer: [*]u8) void { - const size = roc__main_1_Fx_size(); + const size = roc__mainForHost_1_Fx_size(); const raw_output = std.heap.c_allocator.alloc(u8, @intCast(usize, size)) catch unreachable; var output = @ptrCast([*]u8, raw_output); @@ -46,7 +46,7 @@ fn call_the_closure(function_pointer: *const u8, closure_data_pointer: [*]u8) vo std.heap.c_allocator.free(raw_output); } - roc__main_1_Fx_caller(function_pointer, closure_data_pointer, output); + roc__mainForHost_1_Fx_caller(function_pointer, closure_data_pointer, output); const elements = @ptrCast([*]u64, @alignCast(8, output));