diff --git a/crates/compiler/load/src/lib.rs b/crates/compiler/load/src/lib.rs index 402eb9c344..56804d34da 100644 --- a/crates/compiler/load/src/lib.rs +++ b/crates/compiler/load/src/lib.rs @@ -1,7 +1,7 @@ use bumpalo::Bump; use roc_can::module::{ExposedByModule, TypeState}; use roc_collections::all::MutMap; -use roc_module::symbol::{Interns, ModuleId}; +use roc_module::symbol::ModuleId; use roc_reporting::report::RenderTarget; use roc_target::TargetInfo; use std::path::PathBuf; @@ -25,7 +25,7 @@ fn load<'a>( load_start: LoadStart<'a>, exposed_types: ExposedByModule, load_config: LoadConfig, -) -> Result, (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result, LoadingProblem<'a>> { let cached_types = read_cached_types(); roc_load_internal::file::load(arena, load_start, exposed_types, cached_types, load_config) @@ -39,7 +39,7 @@ pub fn load_single_threaded<'a>( target_info: TargetInfo, render: RenderTarget, exec_mode: ExecutionMode, -) -> Result, (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result, LoadingProblem<'a>> { let cached_subs = read_cached_types(); roc_load_internal::file::load_single_threaded( @@ -84,7 +84,7 @@ pub fn load_and_monomorphize_from_str<'a>( src_dir: PathBuf, exposed_types: ExposedByModule, load_config: LoadConfig, -) -> Result, (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result, LoadingProblem<'a>> { use LoadResult::*; let load_start = LoadStart::from_str(arena, filename, src, src_dir)?; diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index a4b6949105..24b9d62281 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -1193,7 +1193,7 @@ pub fn load_and_typecheck_str<'a>( target_info: TargetInfo, render: RenderTarget, threading: Threading, -) -> Result, (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result> { use LoadResult::*; let load_start = LoadStart::from_str(arena, filename, source, src_dir)?; @@ -1255,7 +1255,7 @@ impl<'a> LoadStart<'a> { root_start_time, ); - match dbg!(res_loaded) { + match res_loaded { Ok((module_id, msg)) => { if let Msg::Header(ModuleHeader { module_id: header_id, @@ -1282,6 +1282,25 @@ impl<'a> LoadStart<'a> { (module_id, msg) } + + Err(LoadingProblem::ParsingFailed(problem)) => { + let module_ids = Arc::try_unwrap(arc_modules) + .unwrap_or_else(|_| { + panic!("There were still outstanding Arc references to module_ids") + }) + .into_inner() + .into_module_ids(); + + // if parsing failed, this module did not add any identifiers + let root_exposed_ident_ids = IdentIds::exposed_builtins(0); + let buf = to_parse_problem_report( + problem, + module_ids, + root_exposed_ident_ids, + render, + ); + return Err(LoadingProblem::FormattedReport(buf)); + } Err(LoadingProblem::FileProblem { filename, error }) => { let buf = to_file_problem_report(&filename, error); return Err(LoadingProblem::FormattedReport(buf)); @@ -1344,7 +1363,7 @@ impl<'a> LoadStart<'a> { filename: PathBuf, src: &'a str, src_dir: PathBuf, - ) -> Result, ModuleId, Interns)> { + ) -> Result> { let arc_modules = Arc::new(Mutex::new(PackageModuleIds::default())); let root_exposed_ident_ids = IdentIds::exposed_builtins(0); let ident_ids_by_module = Arc::new(Mutex::new(root_exposed_ident_ids)); @@ -1442,7 +1461,7 @@ pub fn load<'a>( exposed_types: ExposedByModule, cached_types: MutMap, load_config: LoadConfig, -) -> Result, (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result, LoadingProblem<'a>> { enum Threads { Single, Many(usize), @@ -1500,7 +1519,7 @@ pub fn load_single_threaded<'a>( cached_types: MutMap, render: RenderTarget, exec_mode: ExecutionMode, -) -> Result, (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result, LoadingProblem<'a>> { let LoadStart { arc_modules, ident_ids_by_module, @@ -1632,7 +1651,17 @@ fn state_thread_step<'a>( let buf = to_file_problem_report(&filename, error); Err(LoadingProblem::FormattedReport(buf)) } - Msg::FailedToParse(problem) => Err(LoadingProblem::ParsingFailed(problem)), + + Msg::FailedToParse(problem) => { + let module_ids = (*state.arc_modules).lock().clone().into_module_ids(); + let buf = to_parse_problem_report( + problem, + module_ids, + state.constrained_ident_ids, + state.render, + ); + Err(LoadingProblem::FormattedReport(buf)) + } Msg::IncorrectModuleName(FileError { problem: SourceError { problem, bytes }, filename, @@ -1739,7 +1768,7 @@ fn load_multi_threaded<'a>( render: RenderTarget, available_threads: usize, exec_mode: ExecutionMode, -) -> Result, (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result, LoadingProblem<'a>> { let LoadStart { arc_modules, ident_ids_by_module, @@ -3395,7 +3424,7 @@ fn parse_header<'a>( ident_ids_by_module: SharedIdentIdsByModule, src_bytes: &'a [u8], start_time: Instant, -) -> Result<(ModuleId, Msg<'a>), (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { let parse_start = Instant::now(); let parse_state = roc_parse::state::State::new(src_bytes); let parsed = roc_parse::module::parse_header(arena, parse_state.clone()); @@ -3407,7 +3436,7 @@ fn parse_header<'a>( module_timing.read_roc_file = read_file_duration; module_timing.parse_header = parse_header_duration; - match dbg!(parsed) { + match parsed { Ok((ast::Module::Interface { header }, parse_state)) => { verify_interface_matches_file_path(header.name, &filename, &parse_state)?; @@ -3610,7 +3639,7 @@ fn load_filename<'a>( module_ids: Arc>>, ident_ids_by_module: SharedIdentIdsByModule, module_start_time: Instant, -) -> Result<(ModuleId, Msg<'a>), (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { let file_io_start = Instant::now(); let file = fs::read(&filename); let file_io_duration = file_io_start.elapsed(); @@ -3645,7 +3674,7 @@ fn load_from_str<'a>( module_ids: Arc>>, ident_ids_by_module: SharedIdentIdsByModule, module_start_time: Instant, -) -> Result<(ModuleId, Msg<'a>), (LoadingProblem<'a>, ModuleId, Interns)> { +) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { let file_io_start = Instant::now(); let file_io_duration = file_io_start.elapsed(); @@ -5833,8 +5862,12 @@ fn to_parse_problem_report<'a>( ) -> String { use roc_reporting::report::{parse_problem, RocDocAllocator, DEFAULT_PALETTE}; - let src = std::str::from_utf8(problem.problem.bytes).unwrap(); + // TODO this is not in fact safe + let src = unsafe { from_utf8_unchecked(problem.problem.bytes) }; let src_lines = src.lines().collect::>(); + // let mut src_lines: Vec<&str> = problem.prefix.lines().collect(); + // src_lines.extend(src.lines().skip(1)); + let module_id = module_ids.get_or_insert(&"find module name somehow?".into()); let interns = Interns { @@ -5844,7 +5877,9 @@ fn to_parse_problem_report<'a>( // Report parsing and canonicalization problems let alloc = RocDocAllocator::new(&src_lines, module_id, &interns); + let starting_line = 0; + let lines = LineInfo::new(src); let report = parse_problem( diff --git a/crates/repl_eval/src/gen.rs b/crates/repl_eval/src/gen.rs index 3e22498527..a21d086491 100644 --- a/crates/repl_eval/src/gen.rs +++ b/crates/repl_eval/src/gen.rs @@ -1,6 +1,6 @@ use bumpalo::Bump; use roc_load::{ExecutionMode, LoadConfig, Threading}; -use roc_reporting::report::{parse_problem, Palette, RenderTarget, Severity, DEFAULT_PALETTE}; +use roc_reporting::report::{Palette, Severity}; use std::path::PathBuf; use roc_fmt::annotation::Formattable; @@ -51,7 +51,7 @@ pub fn compile_to_mono<'a>( let filename = PathBuf::from(""); let src_dir = PathBuf::from("fake/test/path"); - let module_src = arena.alloc(dbg!(promote_expr_to_module(src))); + let module_src = arena.alloc(promote_expr_to_module(src)); let exposed_types = Default::default(); let loaded = roc_load::load_and_monomorphize_from_str( @@ -68,7 +68,7 @@ pub fn compile_to_mono<'a>( }, ); - let mut loaded = match dbg!(loaded) { + let mut loaded = match loaded { Ok(v) => v, Err(LoadingProblem::FormattedReport(report)) => { return ( @@ -79,27 +79,6 @@ pub fn compile_to_mono<'a>( }, ); } - Err(LoadingProblem::ParsingFailed(problem)) => { - let lines = LineInfo::new(src); - let alloc = RocDocAllocator::new(&src_lines, module_id, &interns); - let starting_line = 0; - let report = parse_problem( - &alloc, - &lines, - problem.filename.clone(), - starting_line, - problem, - ); - - let mut buf = String::new(); - let palette = DEFAULT_PALETTE; - - // Seems safe to assume that the REPL is in an actual terminal (e.g. as opposed to CI). - // If we want to be extra careful, we could try to detect whether colors are supported. - report.render(RenderTarget::ColorTerminal, &mut buf, &alloc, &palette); - - buf - } Err(e) => { todo!("error while loading module: {:?}", e) } @@ -118,25 +97,24 @@ pub fn compile_to_mono<'a>( let errors = &mut problems.errors; let warnings = &mut problems.warnings; - for (home, (module_path, src)) in dbg!(sources).iter() { + for (home, (module_path, src)) in sources.iter() { let can_probs = can_problems.remove(home).unwrap_or_default(); let type_probs = type_problems.remove(home).unwrap_or_default(); + let error_count = can_probs.len() + type_probs.len(); if error_count == 0 { continue; } - // Skip over the repl app module wrapper lines, so that line 1 becomes the first - // line of the expr you entered. - let line_info = LineInfo::new(dbg!(&module_src)); + let line_info = LineInfo::new(module_src); let src_lines: Vec<&str> = src.split('\n').collect(); // Report parsing and canonicalization problems let alloc = RocDocAllocator::new(&src_lines, *home, interns); for problem in can_probs.into_iter() { - let report = can_problem(&alloc, &line_info, module_path.clone(), dbg!(problem)); + let report = can_problem(&alloc, &line_info, module_path.clone(), problem); let severity = report.severity; let mut buf = String::new(); @@ -171,24 +149,12 @@ pub fn compile_to_mono<'a>( } } - (Some(loaded), dbg!(problems)) -} - -const REPL_APP_MODULE_WRAPPER: &str = - "app \"app\" provides [replOutput] to \"./platform\"\n\nreplOutput =\n"; - -const REPL_APP_MODULE_WRAPPER_LINES: usize = 3; - -#[test] -fn repl_app_module_wrapper_lines() { - assert_eq!( - REPL_APP_MODULE_WRAPPER_LINES, - REPL_APP_MODULE_WRAPPER.lines().count() - ); + (Some(loaded), problems) } fn promote_expr_to_module(src: &str) -> String { - let mut buffer = String::from(REPL_APP_MODULE_WRAPPER); + let mut buffer = + String::from("app \"app\" provides [replOutput] to \"./platform\"\n\nreplOutput =\n"); for line in src.lines() { // indent the body!