diff --git a/crates/ast/src/module.rs b/crates/ast/src/module.rs index b01c46f02c..0e95fea098 100644 --- a/crates/ast/src/module.rs +++ b/crates/ast/src/module.rs @@ -10,12 +10,15 @@ pub fn load_module(src_file: &Path, threading: Threading) -> LoadedModule { let loaded = roc_load::load_and_typecheck( &arena, src_file.to_path_buf(), - src_file.parent().unwrap_or_else(|| { - panic!( - "src_file {:?} did not have a parent directory but I need to have one.", - src_file - ) - }), + src_file + .parent() + .unwrap_or_else(|| { + panic!( + "src_file {:?} did not have a parent directory but I need to have one.", + src_file + ) + }) + .to_path_buf(), subs_by_module, TargetInfo::default_x86_64(), roc_reporting::report::RenderTarget::ColorTerminal, diff --git a/crates/bindgen/src/load.rs b/crates/bindgen/src/load.rs index c66e2216d1..528d3ac17c 100644 --- a/crates/bindgen/src/load.rs +++ b/crates/bindgen/src/load.rs @@ -4,13 +4,13 @@ use roc_load::{LoadedModule, Threading}; use roc_reporting::report::RenderTarget; use roc_target::{Architecture, TargetInfo}; use std::io; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use strum::IntoEnumIterator; use target_lexicon::Triple; pub fn load_types( full_file_path: PathBuf, - dir: &Path, + dir: PathBuf, threading: Threading, ) -> Result, io::Error> { let target_info = (&Triple::host()).into(); diff --git a/crates/bindgen/src/main.rs b/crates/bindgen/src/main.rs index 68336737a1..9a1c2d5b2a 100644 --- a/crates/bindgen/src/main.rs +++ b/crates/bindgen/src/main.rs @@ -56,7 +56,7 @@ pub fn main() { } }; - match load_types(input_path.clone(), &cwd, Threading::AllAvailable) { + match load_types(input_path.clone(), cwd, Threading::AllAvailable) { Ok(types_and_targets) => { let mut file = File::create(output_path.clone()).unwrap_or_else(|err| { eprintln!( diff --git a/crates/bindgen/tests/helpers/mod.rs b/crates/bindgen/tests/helpers/mod.rs index 410d3eac90..d1cf822fb8 100644 --- a/crates/bindgen/tests/helpers/mod.rs +++ b/crates/bindgen/tests/helpers/mod.rs @@ -33,7 +33,7 @@ pub fn generate_bindings(decl_src: &str) -> String { let mut file = File::create(file_path).unwrap(); writeln!(file, "{}", &src).unwrap(); - let result = load_types(full_file_path, dir.path(), Threading::Single); + let result = load_types(full_file_path, dir.path().to_path_buf(), Threading::Single); dir.close().expect("Unable to close tempdir"); diff --git a/crates/cli/src/build.rs b/crates/cli/src/build.rs index b4d03a5bee..5cf4a7106e 100644 --- a/crates/cli/src/build.rs +++ b/crates/cli/src/build.rs @@ -55,7 +55,7 @@ pub fn build_file<'a>( let loaded = roc_load::load_and_monomorphize( arena, app_module_path.clone(), - src_dir.as_path(), + src_dir, subs_by_module, target_info, // TODO: expose this from CLI? @@ -436,7 +436,7 @@ pub fn check_file( let mut loaded = roc_load::load_and_typecheck( arena, roc_file_path, - src_dir.as_path(), + src_dir, subs_by_module, target_info, // TODO: expose this from CLI? diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 84cf30890d..3dd67c7c5a 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -367,7 +367,7 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result { let loaded = roc_load::load_and_monomorphize( arena, path, - src_dir.as_path(), + src_dir, subs_by_module, target_info, // TODO: expose this from CLI? diff --git a/crates/compiler/can/src/builtins.rs b/crates/compiler/can/src/builtins.rs index 168a1d37f3..9fd73d3055 100644 --- a/crates/compiler/can/src/builtins.rs +++ b/crates/compiler/can/src/builtins.rs @@ -244,21 +244,6 @@ map_symbol_to_lowlevel_and_arity! { /// 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. -/// Does a builtin depend on any other builtins? -/// -/// NOTE: you are supposed to give all symbols that are relied on, -/// even those that are relied on transitively! -pub fn builtin_dependencies(symbol: Symbol) -> &'static [Symbol] { - match symbol { - Symbol::LIST_SORT_ASC => &[Symbol::LIST_SORT_WITH, Symbol::NUM_COMPARE], - Symbol::LIST_SORT_DESC => &[Symbol::LIST_SORT_WITH], - Symbol::LIST_PRODUCT => &[Symbol::LIST_WALK, Symbol::NUM_MUL], - Symbol::LIST_SUM => &[Symbol::LIST_WALK, Symbol::NUM_ADD], - Symbol::LIST_SET => &[Symbol::LIST_REPLACE], - _ => &[], - } -} - /// Implementation for a builtin pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option { debug_assert!(symbol.is_builtin()); diff --git a/crates/compiler/can/src/module.rs b/crates/compiler/can/src/module.rs index 24d0affda4..110a7741b9 100644 --- a/crates/compiler/can/src/module.rs +++ b/crates/compiler/can/src/module.rs @@ -415,16 +415,6 @@ pub fn canonicalize_module_defs<'a>( referenced_values.extend(env.qualified_value_lookups.iter().copied()); referenced_types.extend(env.qualified_type_lookups.iter().copied()); - // add any builtins used by other builtins - let transitive_builtins: Vec = referenced_values - .iter() - .filter(|s| s.is_builtin()) - .flat_map(|s| crate::builtins::builtin_dependencies(*s)) - .copied() - .collect(); - - referenced_values.extend(transitive_builtins); - // NOTE previously we inserted builtin defs into the list of defs here // this is now done later, in file.rs. diff --git a/crates/compiler/fmt/src/collection.rs b/crates/compiler/fmt/src/collection.rs index f68c25c032..47fe924f55 100644 --- a/crates/compiler/fmt/src/collection.rs +++ b/crates/compiler/fmt/src/collection.rs @@ -1,8 +1,8 @@ -use roc_parse::ast::{Collection, ExtractSpaces}; +use roc_parse::ast::{Collection, CommentOrNewline, ExtractSpaces}; use crate::{ annotation::{Formattable, Newlines}, - spaces::{count_leading_newlines, fmt_comments_only, NewlineAt, INDENT}, + spaces::{fmt_comments_only, NewlineAt, INDENT}, Buf, }; @@ -41,24 +41,43 @@ pub fn fmt_collection<'a, 'buf, T: ExtractSpaces<'a> + Formattable>( buf.push(start); for (index, item) in items.iter().enumerate() { - let item = item.extract_spaces(); let is_first_item = index == 0; + let item = item.extract_spaces(); + let is_only_newlines = item.before.iter().all(|s| s.is_newline()); - buf.newline(); + if item.before.is_empty() || is_only_newlines { + buf.ensure_ends_in_newline(); + } else { + if is_first_item { + // The first item in a multiline collection always begins with exactly + // one newline (so the delimiter is at the end of its own line), + // and that newline appears before the first comment (if there is one). + buf.ensure_ends_in_newline(); + } else { + if item.before.starts_with(&[CommentOrNewline::Newline]) { + buf.ensure_ends_in_newline(); + } - if !item.before.is_empty() { - let is_only_newlines = item.before.iter().all(|s| s.is_newline()); + if item + .before + .starts_with(&[CommentOrNewline::Newline, CommentOrNewline::Newline]) + { + // If there's a comment, and it's not on the first item, + // and it's preceded by at least one blank line, maintain 1 blank line. + // (We already ensured that it ends in a newline, so this will turn that + // into a blank line.) - if !is_first_item - && !is_only_newlines - && count_leading_newlines(item.before.iter()) > 1 - { - buf.newline(); + buf.newline(); + } } - fmt_comments_only(buf, item.before.iter(), NewlineAt::Bottom, item_indent); + fmt_comments_only(buf, item.before.iter(), NewlineAt::None, item_indent); + + if !is_only_newlines { + if item.before.ends_with(&[CommentOrNewline::Newline]) { + buf.newline(); + } - if !is_only_newlines && count_leading_newlines(item.before.iter().rev()) > 0 { buf.newline(); } } @@ -68,21 +87,33 @@ pub fn fmt_collection<'a, 'buf, T: ExtractSpaces<'a> + Formattable>( buf.push(','); if !item.after.is_empty() { - fmt_comments_only(buf, item.after.iter(), NewlineAt::Top, item_indent); + if item.after.iter().any(|s| s.is_newline()) { + buf.newline(); + } + + fmt_comments_only(buf, item.after.iter(), NewlineAt::None, item_indent); } } - if count_leading_newlines(items.final_comments().iter()) > 1 { + if items.final_comments().iter().any(|s| s.is_newline()) { + buf.newline(); + } + + if items + .final_comments() + .starts_with(&[CommentOrNewline::Newline, CommentOrNewline::Newline]) + { buf.newline(); } fmt_comments_only( buf, items.final_comments().iter(), - NewlineAt::Top, + NewlineAt::None, item_indent, ); - buf.newline(); + + buf.ensure_ends_in_newline(); buf.indent(braces_indent); } else { // is_multiline == false diff --git a/crates/compiler/fmt/tests/test_fmt.rs b/crates/compiler/fmt/tests/test_fmt.rs index a914d08510..8e8f137067 100644 --- a/crates/compiler/fmt/tests/test_fmt.rs +++ b/crates/compiler/fmt/tests/test_fmt.rs @@ -2347,8 +2347,7 @@ mod test_fmt { indoc!( r#" f : { - x : Int *, - # comment 1 + x : Int *, # comment 1 # comment 2 } @@ -4588,7 +4587,7 @@ mod test_fmt { } #[test] - fn multiline_tag_union_annotation() { + fn multiline_tag_union_annotation_no_comments() { expr_formats_same(indoc!( r#" b : [ @@ -4694,8 +4693,7 @@ mod test_fmt { b : [ True, # comment 1 - False, - # comment 2 + False, # comment 2 # comment 3 ] @@ -5082,6 +5080,38 @@ mod test_fmt { ); } + #[test] + fn comments_in_multiline_tag_union_annotation() { + expr_formats_to( + indoc!( + r#" + UnionAnn : [ + Foo, # comment 1 + Bar, # comment 2 + Baz, # comment 3 + # comment 4 line 1 + # comment 4 line 2 + ] + + 0 + "# + ), + indoc!( + r#" + UnionAnn : [ + Foo, # comment 1 + Bar, # comment 2 + Baz, # comment 3 + # comment 4 line 1 + # comment 4 line 2 + ] + + 0 + "# + ), + ); + } + #[test] /// Test that everything under examples/ is formatted correctly /// If this test fails on your diff, it probably means you need to re-format the examples. diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 16b6f408c1..01b658f8b3 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -5480,7 +5480,7 @@ fn run_low_level<'a, 'ctx, 'env>( let string = load_symbol(scope, &args[0]); - let result = call_bitcode_fn(env, &[string], intrinsic); + let result = call_bitcode_fn_fixing_for_convention(env, &[string], layout, intrinsic); // zig passes the result as a packed integer sometimes, instead of a struct. So we cast let expected_type = basic_type_from_layout(env, layout); diff --git a/crates/compiler/load/build.rs b/crates/compiler/load/build.rs index c8c5f70f61..8f6ed834c4 100644 --- a/crates/compiler/load/build.rs +++ b/crates/compiler/load/build.rs @@ -40,7 +40,7 @@ fn write_subs_for_module(module_id: ModuleId, filename: &str) { &arena, PathBuf::from(filename), source, - &src_dir, + src_dir, Default::default(), target_info, roc_reporting::report::RenderTarget::ColorTerminal, diff --git a/crates/compiler/load/src/lib.rs b/crates/compiler/load/src/lib.rs index 645299d7f6..cee9864eac 100644 --- a/crates/compiler/load/src/lib.rs +++ b/crates/compiler/load/src/lib.rs @@ -7,7 +7,7 @@ use roc_module::symbol::{ModuleId, Symbol}; use roc_reporting::report::RenderTarget; use roc_target::TargetInfo; use roc_types::subs::{Subs, Variable}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; pub use roc_load_internal::docs; pub use roc_load_internal::file::{ @@ -18,7 +18,6 @@ pub use roc_load_internal::file::{ fn load<'a>( arena: &'a Bump, load_start: LoadStart<'a>, - src_dir: &Path, exposed_types: ExposedByModule, goal_phase: Phase, target_info: TargetInfo, @@ -30,7 +29,6 @@ fn load<'a>( roc_load_internal::file::load( arena, load_start, - src_dir, exposed_types, goal_phase, target_info, @@ -44,7 +42,6 @@ fn load<'a>( pub fn load_single_threaded<'a>( arena: &'a Bump, load_start: LoadStart<'a>, - src_dir: &Path, exposed_types: ExposedByModule, goal_phase: Phase, target_info: TargetInfo, @@ -55,7 +52,6 @@ pub fn load_single_threaded<'a>( roc_load_internal::file::load_single_threaded( arena, load_start, - src_dir, exposed_types, goal_phase, target_info, @@ -69,7 +65,7 @@ pub fn load_and_monomorphize_from_str<'a>( arena: &'a Bump, filename: PathBuf, src: &'a str, - src_dir: &Path, + src_dir: PathBuf, exposed_types: ExposedByModule, target_info: TargetInfo, render: RenderTarget, @@ -77,12 +73,11 @@ pub fn load_and_monomorphize_from_str<'a>( ) -> Result, LoadingProblem<'a>> { use LoadResult::*; - let load_start = LoadStart::from_str(arena, filename, src)?; + let load_start = LoadStart::from_str(arena, filename, src, src_dir)?; match load( arena, load_start, - src_dir, exposed_types, Phase::MakeSpecializations, target_info, @@ -94,23 +89,22 @@ pub fn load_and_monomorphize_from_str<'a>( } } -pub fn load_and_monomorphize<'a>( - arena: &'a Bump, +pub fn load_and_monomorphize( + arena: &Bump, filename: PathBuf, - src_dir: &Path, + src_dir: PathBuf, exposed_types: ExposedByModule, target_info: TargetInfo, render: RenderTarget, threading: Threading, -) -> Result, LoadingProblem<'a>> { +) -> Result, LoadingProblem<'_>> { use LoadResult::*; - let load_start = LoadStart::from_path(arena, filename, render)?; + let load_start = LoadStart::from_path(arena, src_dir, filename, render)?; match load( arena, load_start, - src_dir, exposed_types, Phase::MakeSpecializations, target_info, @@ -122,23 +116,22 @@ pub fn load_and_monomorphize<'a>( } } -pub fn load_and_typecheck<'a>( - arena: &'a Bump, +pub fn load_and_typecheck( + arena: &Bump, filename: PathBuf, - src_dir: &Path, + src_dir: PathBuf, exposed_types: ExposedByModule, target_info: TargetInfo, render: RenderTarget, threading: Threading, -) -> Result> { +) -> Result> { use LoadResult::*; - let load_start = LoadStart::from_path(arena, filename, render)?; + let load_start = LoadStart::from_path(arena, src_dir, filename, render)?; match load( arena, load_start, - src_dir, exposed_types, Phase::SolveTypes, target_info, @@ -154,14 +147,14 @@ pub fn load_and_typecheck_str<'a>( arena: &'a Bump, filename: PathBuf, source: &'a str, - src_dir: &Path, + src_dir: PathBuf, exposed_types: ExposedByModule, target_info: TargetInfo, render: RenderTarget, ) -> Result> { use LoadResult::*; - let load_start = LoadStart::from_str(arena, filename, source)?; + let load_start = LoadStart::from_str(arena, filename, source, src_dir)?; // NOTE: this function is meant for tests, and so we use single-threaded // solving so we don't use too many threads per-test. That gives higher @@ -169,7 +162,6 @@ pub fn load_and_typecheck_str<'a>( match load_single_threaded( arena, load_start, - src_dir, exposed_types, Phase::SolveTypes, target_info, diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 21f7f163c3..b10256d532 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -1067,7 +1067,7 @@ pub fn load_and_typecheck_str<'a>( arena: &'a Bump, filename: PathBuf, source: &'a str, - src_dir: &Path, + src_dir: PathBuf, exposed_types: ExposedByModule, target_info: TargetInfo, render: RenderTarget, @@ -1075,7 +1075,7 @@ pub fn load_and_typecheck_str<'a>( ) -> Result> { use LoadResult::*; - let load_start = LoadStart::from_str(arena, filename, source)?; + let load_start = LoadStart::from_str(arena, filename, source, src_dir)?; // this function is used specifically in the case // where we want to regenerate the cached data @@ -1084,7 +1084,6 @@ pub fn load_and_typecheck_str<'a>( match load( arena, load_start, - src_dir, exposed_types, Phase::SolveTypes, target_info, @@ -1108,11 +1107,13 @@ pub struct LoadStart<'a> { ident_ids_by_module: SharedIdentIdsByModule, root_id: ModuleId, root_msg: Msg<'a>, + src_dir: PathBuf, } impl<'a> LoadStart<'a> { pub fn from_path( arena: &'a Bump, + mut src_dir: PathBuf, filename: PathBuf, render: RenderTarget, ) -> Result> { @@ -1135,7 +1136,32 @@ impl<'a> LoadStart<'a> { ); match res_loaded { - Ok(good) => good, + Ok((module_id, msg)) => { + if let Msg::Header(ModuleHeader { + module_id: header_id, + module_name, + is_root_module, + .. + }) = &msg + { + debug_assert_eq!(*header_id, module_id); + debug_assert!(is_root_module); + + if let ModuleNameEnum::Interface(name) = module_name { + // Interface modules can have names like Foo.Bar.Baz, + // in which case we need to adjust the src_dir to + // remove the "Bar/Baz" directories in order to correctly + // resolve this interface module's imports! + let dirs_to_pop = name.as_str().matches('.').count(); + + for _ in 0..dirs_to_pop { + src_dir.pop(); + } + } + } + + (module_id, msg) + } Err(LoadingProblem::ParsingFailed(problem)) => { let module_ids = Arc::try_unwrap(arc_modules) @@ -1166,6 +1192,7 @@ impl<'a> LoadStart<'a> { Ok(LoadStart { arc_modules, ident_ids_by_module, + src_dir, root_id, root_msg, }) @@ -1175,6 +1202,7 @@ impl<'a> LoadStart<'a> { arena: &'a Bump, filename: PathBuf, src: &'a str, + src_dir: PathBuf, ) -> Result> { let arc_modules = Arc::new(Mutex::new(PackageModuleIds::default())); let root_exposed_ident_ids = IdentIds::exposed_builtins(0); @@ -1196,6 +1224,7 @@ impl<'a> LoadStart<'a> { Ok(LoadStart { arc_modules, + src_dir, ident_ids_by_module, root_id, root_msg, @@ -1269,7 +1298,6 @@ pub enum Threading { pub fn load<'a>( arena: &'a Bump, load_start: LoadStart<'a>, - src_dir: &Path, exposed_types: ExposedByModule, goal_phase: Phase, target_info: TargetInfo, @@ -1305,7 +1333,6 @@ pub fn load<'a>( Threads::Single => load_single_threaded( arena, load_start, - src_dir, exposed_types, goal_phase, target_info, @@ -1315,7 +1342,6 @@ pub fn load<'a>( Threads::Many(threads) => load_multi_threaded( arena, load_start, - src_dir, exposed_types, goal_phase, target_info, @@ -1331,7 +1357,6 @@ pub fn load<'a>( pub fn load_single_threaded<'a>( arena: &'a Bump, load_start: LoadStart<'a>, - src_dir: &Path, exposed_types: ExposedByModule, goal_phase: Phase, target_info: TargetInfo, @@ -1343,6 +1368,7 @@ pub fn load_single_threaded<'a>( ident_ids_by_module, root_id, root_msg, + src_dir, .. } = load_start; @@ -1394,7 +1420,7 @@ pub fn load_single_threaded<'a>( stealers, &worker_msg_rx, &msg_tx, - src_dir, + &src_dir, target_info, ); @@ -1532,7 +1558,6 @@ fn state_thread_step<'a>( fn load_multi_threaded<'a>( arena: &'a Bump, load_start: LoadStart<'a>, - src_dir: &Path, exposed_types: ExposedByModule, goal_phase: Phase, target_info: TargetInfo, @@ -1545,6 +1570,7 @@ fn load_multi_threaded<'a>( ident_ids_by_module, root_id, root_msg, + src_dir, .. } = load_start; @@ -1622,8 +1648,9 @@ fn load_multi_threaded<'a>( // We only want to move a *reference* to the main task queue's // injector in the thread, not the injector itself - // (since other threads need to reference it too). + // (since other threads need to reference it too). Same with src_dir. let injector = &injector; + let src_dir = &src_dir; // Record this thread's handle so the main thread can join it later. let res_join_handle = thread_scope diff --git a/crates/compiler/load_internal/tests/fixtures/build/app_with_deps/Dep3/Blah.roc b/crates/compiler/load_internal/tests/fixtures/build/app_with_deps/Dep3/Blah.roc index da94d8c6a7..b868374a0d 100644 --- a/crates/compiler/load_internal/tests/fixtures/build/app_with_deps/Dep3/Blah.roc +++ b/crates/compiler/load_internal/tests/fixtures/build/app_with_deps/Dep3/Blah.roc @@ -1,10 +1,10 @@ interface Dep3.Blah exposes [one, two, foo, bar] - imports [] + imports [Dep3.Other] one = 1 two = 2 foo = "foo from Dep3" -bar = "bar from Dep3" +bar = Dep3.Other.bar diff --git a/crates/compiler/load_internal/tests/fixtures/build/app_with_deps/Dep3/Other.roc b/crates/compiler/load_internal/tests/fixtures/build/app_with_deps/Dep3/Other.roc new file mode 100644 index 0000000000..67df17c8a7 --- /dev/null +++ b/crates/compiler/load_internal/tests/fixtures/build/app_with_deps/Dep3/Other.roc @@ -0,0 +1,6 @@ +interface Dep3.Other + exposes [foo, bar] + imports [] + +foo = "foo from Dep3.Other" +bar = "bar from Dep3.Other" diff --git a/crates/compiler/load_internal/tests/test_load.rs b/crates/compiler/load_internal/tests/test_load.rs index 35909a02f4..ac15c4ae41 100644 --- a/crates/compiler/load_internal/tests/test_load.rs +++ b/crates/compiler/load_internal/tests/test_load.rs @@ -30,23 +30,22 @@ use roc_target::TargetInfo; use roc_types::pretty_print::name_and_print_var; use roc_types::pretty_print::DebugPrint; use std::collections::HashMap; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; -fn load_and_typecheck<'a>( - arena: &'a Bump, +fn load_and_typecheck( + arena: &Bump, filename: PathBuf, - src_dir: &Path, + src_dir: PathBuf, exposed_types: ExposedByModule, target_info: TargetInfo, -) -> Result> { +) -> Result { use LoadResult::*; - let load_start = LoadStart::from_path(arena, filename, RenderTarget::Generic)?; + let load_start = LoadStart::from_path(arena, src_dir, filename, RenderTarget::Generic)?; match roc_load_internal::file::load( arena, load_start, - src_dir, exposed_types, Phase::SolveTypes, target_info, @@ -167,7 +166,7 @@ fn multiple_modules_help<'a>( load_and_typecheck( arena, full_file_path, - dir.path(), + dir.path().to_path_buf(), Default::default(), TARGET_INFO, ) @@ -184,13 +183,7 @@ fn load_fixture( let src_dir = fixtures_dir().join(dir_name); let filename = src_dir.join(format!("{}.roc", module_name)); let arena = Bump::new(); - let loaded = load_and_typecheck( - &arena, - filename, - src_dir.as_path(), - subs_by_module, - TARGET_INFO, - ); + let loaded = load_and_typecheck(&arena, filename, src_dir, subs_by_module, TARGET_INFO); let mut loaded_module = match loaded { Ok(x) => x, Err(roc_load_internal::file::LoadingProblem::FormattedReport(report)) => { @@ -346,13 +339,7 @@ fn interface_with_deps() { let src_dir = fixtures_dir().join("interface_with_deps"); let filename = src_dir.join("Primary.roc"); let arena = Bump::new(); - let loaded = load_and_typecheck( - &arena, - filename, - src_dir.as_path(), - subs_by_module, - TARGET_INFO, - ); + let loaded = load_and_typecheck(&arena, filename, src_dir, subs_by_module, TARGET_INFO); let mut loaded_module = loaded.expect("Test module failed to load"); let home = loaded_module.module_id; diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 3545d0ecc8..89e60d7538 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -98,7 +98,7 @@ mod solve_expr { arena, file_path, module_src, - dir.path(), + dir.path().to_path_buf(), exposed_types, roc_target::TargetInfo::default_x86_64(), roc_reporting::report::RenderTarget::Generic, @@ -6575,7 +6575,7 @@ mod solve_expr { A := {} id1 = \@A {} -> @A {} #^^^{-1} - + id2 = \@A {} -> id1 (@A {}) #^^^{-1} ^^^ @@ -6922,7 +6922,7 @@ mod solve_expr { Ok u -> [Pair u (List.drop inp 1)] _ -> [] - main = any + main = any "# ), "Parser U8", @@ -7324,4 +7324,21 @@ mod solve_expr { "OList", ); } + + #[test] + fn rosetree_with_result_is_legal_recursive_type() { + infer_eq_without_problem( + indoc!( + r#" + Rose a : [Rose (Result (List (Rose a)) I64)] + + x : Rose I64 + x = Rose (Ok []) + + x + "# + ), + "Rose I64", + ); + } } diff --git a/crates/compiler/test_derive/src/encoding.rs b/crates/compiler/test_derive/src/encoding.rs index d34d132a22..e3968586c5 100644 --- a/crates/compiler/test_derive/src/encoding.rs +++ b/crates/compiler/test_derive/src/encoding.rs @@ -234,7 +234,7 @@ where &arena, encode_path().file_name().unwrap().into(), source, - encode_path().parent().unwrap(), + encode_path().parent().unwrap().to_path_buf(), Default::default(), target_info, roc_reporting::report::RenderTarget::ColorTerminal, diff --git a/crates/compiler/test_gen/src/gen_abilities.rs b/crates/compiler/test_gen/src/gen_abilities.rs index d54d8bc458..587bd93198 100644 --- a/crates/compiler/test_gen/src/gen_abilities.rs +++ b/crates/compiler/test_gen/src/gen_abilities.rs @@ -1,13 +1,10 @@ #[cfg(feature = "gen-llvm")] use crate::helpers::llvm::assert_evals_to; -#[cfg(feature = "gen-dev")] -use crate::helpers::dev::assert_evals_to; - #[cfg(feature = "gen-wasm")] use crate::helpers::wasm::assert_evals_to; -#[cfg(test)] +#[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))] use indoc::indoc; #[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))] diff --git a/crates/compiler/test_gen/src/gen_compare.rs b/crates/compiler/test_gen/src/gen_compare.rs index 495ddee3c0..31db80dddd 100644 --- a/crates/compiler/test_gen/src/gen_compare.rs +++ b/crates/compiler/test_gen/src/gen_compare.rs @@ -542,10 +542,7 @@ fn eq_different_rosetrees() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn rosetree_with_tag() { - // currently stack overflows in type checking - assert_evals_to!( indoc!( r#" diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index 796c3a278a..a782dc55bc 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -1622,7 +1622,6 @@ fn first_int_list() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn first_wildcard_empty_list() { assert_evals_to!( indoc!( @@ -1671,7 +1670,6 @@ fn last_int_list() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn last_wildcard_empty_list() { assert_evals_to!( indoc!( @@ -1720,7 +1718,6 @@ fn get_empty_list() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn get_wildcard_empty_list() { assert_evals_to!( indoc!( diff --git a/crates/compiler/test_gen/src/gen_primitives.rs b/crates/compiler/test_gen/src/gen_primitives.rs index 732fd2436d..383444b074 100644 --- a/crates/compiler/test_gen/src/gen_primitives.rs +++ b/crates/compiler/test_gen/src/gen_primitives.rs @@ -2464,7 +2464,6 @@ fn expanded_result() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn backpassing_result() { assert_evals_to!( indoc!( diff --git a/crates/compiler/test_gen/src/gen_records.rs b/crates/compiler/test_gen/src/gen_records.rs index 7da336b3b1..bfeec21557 100644 --- a/crates/compiler/test_gen/src/gen_records.rs +++ b/crates/compiler/test_gen/src/gen_records.rs @@ -10,7 +10,7 @@ use crate::helpers::wasm::{assert_evals_to, expect_runtime_error_panic}; // use crate::assert_wasm_evals_to as assert_evals_to; use indoc::indoc; -#[cfg(test)] +#[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))] use roc_std::{RocList, RocStr}; #[test] diff --git a/crates/compiler/test_gen/src/gen_str.rs b/crates/compiler/test_gen/src/gen_str.rs index 3ee7db96c1..f9eeecabb0 100644 --- a/crates/compiler/test_gen/src/gen_str.rs +++ b/crates/compiler/test_gen/src/gen_str.rs @@ -1377,7 +1377,6 @@ fn str_to_nat() { } #[test] -#[ignore = "TODO: figure out why returning i128 across FFI boundary is an issue"] #[cfg(any(feature = "gen-llvm"))] fn str_to_i128() { assert_evals_to!( @@ -1395,7 +1394,6 @@ fn str_to_i128() { } #[test] -#[ignore = "TODO: figure out why returning i128 across FFI boundary is an issue"] #[cfg(any(feature = "gen-llvm"))] fn str_to_u128() { assert_evals_to!( @@ -1569,7 +1567,6 @@ fn str_to_f32() { } #[test] -#[ignore = "TODO: figure out why returning i128 across FFI boundary is an issue"] #[cfg(any(feature = "gen-llvm"))] fn str_to_dec() { use roc_std::RocDec; diff --git a/crates/compiler/test_gen/src/gen_tags.rs b/crates/compiler/test_gen/src/gen_tags.rs index 620babaa6b..15bb82d1e1 100644 --- a/crates/compiler/test_gen/src/gen_tags.rs +++ b/crates/compiler/test_gen/src/gen_tags.rs @@ -9,7 +9,8 @@ use crate::helpers::wasm::assert_evals_to; #[cfg(test)] use indoc::indoc; -#[cfg(test)] + +#[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))] use roc_std::{RocList, RocStr}; #[test] @@ -532,14 +533,12 @@ fn if_guard_vanilla() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn when_on_single_value_tag() { - // this fails because the switched-on symbol is not defined assert_evals_to!( indoc!( r#" when Identity 0 is - Identity 0 -> 0 + Identity 0 -> 6 Identity s -> s "# ), @@ -1046,9 +1045,7 @@ fn alignment_in_multi_tag_pattern_match() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn phantom_polymorphic() { - // see https://github.com/rtfeldman/roc/issues/786 and below assert_evals_to!( indoc!( r"# @@ -1072,11 +1069,7 @@ fn phantom_polymorphic() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[ignore] fn phantom_polymorphic_record() { - // see https://github.com/rtfeldman/roc/issues/786 - // also seemed to hit an issue where we check whether `add` - // has a Closure layout while the type is not fully specialized yet assert_evals_to!( indoc!( r#" diff --git a/crates/compiler/test_gen/src/helpers/dev.rs b/crates/compiler/test_gen/src/helpers/dev.rs index 3430eb857b..38ddd2fea8 100644 --- a/crates/compiler/test_gen/src/helpers/dev.rs +++ b/crates/compiler/test_gen/src/helpers/dev.rs @@ -1,11 +1,13 @@ use libloading::Library; use roc_build::link::{link, LinkType}; use roc_builtins::bitcode; -use roc_collections::all::MutMap; use roc_load::Threading; use roc_region::all::LineInfo; use tempfile::tempdir; +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +use roc_collections::all::MutMap; + #[allow(unused_imports)] use roc_mono::ir::pretty_print_ir_symbols; @@ -30,11 +32,11 @@ pub fn helper( _leak: bool, lazy_literals: bool, ) -> (String, Vec, Library) { - use std::path::{Path, PathBuf}; + use std::path::PathBuf; let dir = tempdir().unwrap(); let filename = PathBuf::from("Test.roc"); - let src_dir = Path::new("fake/test/path"); + let src_dir = PathBuf::from("fake/test/path"); let app_o_file = dir.path().join("app.o"); let module_src; diff --git a/crates/compiler/test_gen/src/helpers/llvm.rs b/crates/compiler/test_gen/src/helpers/llvm.rs index b56243efef..81f8538a23 100644 --- a/crates/compiler/test_gen/src/helpers/llvm.rs +++ b/crates/compiler/test_gen/src/helpers/llvm.rs @@ -50,12 +50,10 @@ fn create_llvm_module<'a>( context: &'a inkwell::context::Context, target: &Triple, ) -> (&'static str, String, &'a Module<'a>) { - use std::path::Path; - let target_info = roc_target::TargetInfo::from(target); let filename = PathBuf::from("Test.roc"); - let src_dir = Path::new("fake/test/path"); + let src_dir = PathBuf::from("fake/test/path"); let module_src; let temp; diff --git a/crates/compiler/test_gen/src/helpers/wasm.rs b/crates/compiler/test_gen/src/helpers/wasm.rs index c4e57597d4..575f1ff76f 100644 --- a/crates/compiler/test_gen/src/helpers/wasm.rs +++ b/crates/compiler/test_gen/src/helpers/wasm.rs @@ -69,7 +69,7 @@ fn compile_roc_to_wasm_bytes<'a, T: Wasm32Result>( _test_wrapper_type_info: PhantomData, ) -> Vec { let filename = PathBuf::from("Test.roc"); - let src_dir = Path::new("fake/test/path"); + let src_dir = PathBuf::from("fake/test/path"); let module_src; let temp; diff --git a/crates/compiler/test_mono/src/tests.rs b/crates/compiler/test_mono/src/tests.rs index c1ce52f904..c7ef0e7450 100644 --- a/crates/compiler/test_mono/src/tests.rs +++ b/crates/compiler/test_mono/src/tests.rs @@ -73,12 +73,12 @@ fn promote_expr_to_module(src: &str) -> String { fn compiles_to_ir(test_name: &str, src: &str) { use bumpalo::Bump; - use std::path::{Path, PathBuf}; + use std::path::PathBuf; let arena = &Bump::new(); let filename = PathBuf::from("Test.roc"); - let src_dir = Path::new("fake/test/path"); + let src_dir = PathBuf::from("fake/test/path"); let module_src; let temp; diff --git a/crates/compiler/types/src/types.rs b/crates/compiler/types/src/types.rs index df0a5a2d32..adfd08b72a 100644 --- a/crates/compiler/types/src/types.rs +++ b/crates/compiler/types/src/types.rs @@ -1482,6 +1482,8 @@ impl Type { Type::Apply(Symbol::LIST_LIST | Symbol::SET_SET, _, _) => false, Type::Apply(..) => internal_error!("cannot chase an Apply!"), Type::Alias { .. } => internal_error!("should be dealiased"), + // Must be conservative here because we don't know what the alias expands to yet + Type::DelayedAlias(..) => false, // Non-composite types are trivially narrow _ => true, } diff --git a/crates/docs/src/lib.rs b/crates/docs/src/lib.rs index c3995c8bc3..0af885947e 100644 --- a/crates/docs/src/lib.rs +++ b/crates/docs/src/lib.rs @@ -438,7 +438,7 @@ pub fn load_modules_for_files(filenames: Vec) -> Vec { match roc_load::load_and_typecheck( &arena, filename, - src_dir.as_path(), + src_dir, Default::default(), roc_target::TargetInfo::default_x86_64(), // This is just type-checking for docs, so "target" doesn't matter roc_reporting::report::RenderTarget::ColorTerminal, diff --git a/crates/repl_eval/src/gen.rs b/crates/repl_eval/src/gen.rs index 24efacca36..07ba4e644e 100644 --- a/crates/repl_eval/src/gen.rs +++ b/crates/repl_eval/src/gen.rs @@ -1,7 +1,7 @@ use bumpalo::Bump; use roc_load::Threading; use roc_reporting::report::Palette; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use roc_fmt::annotation::Formattable; use roc_fmt::annotation::{Newlines, Parens}; @@ -49,7 +49,7 @@ pub fn compile_to_mono<'a>( palette: Palette, ) -> Result, Vec> { let filename = PathBuf::from(""); - let src_dir = Path::new("fake/test/path"); + let src_dir = PathBuf::from("fake/test/path"); let module_src = arena.alloc(promote_expr_to_module(src)); diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index df051983fd..bb8dca4f68 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -86,7 +86,7 @@ mod test_reporting { let result = roc_load::load_and_typecheck( arena, full_file_path, - dir.path(), + dir.path().to_path_buf(), exposed_types, roc_target::TargetInfo::default_x86_64(), RenderTarget::Generic,