Merge branch 'main' into inline-imports

This commit is contained in:
Agus Zubiaga 2024-04-20 12:01:11 -03:00
commit d5a38a26db
No known key found for this signature in database
667 changed files with 22300 additions and 14562 deletions

View file

@ -1,6 +1,6 @@
app "quicksort" provides [swap, partition, partitionHelp, quicksort] to "./platform"
quicksort : List (Num a), Nat, Nat -> List (Num a)
quicksort : List (Num a), U64, U64 -> List (Num a)
quicksort = \list, low, high ->
when partition low high list is
Pair partitionIndex partitioned ->
@ -9,7 +9,7 @@ quicksort = \list, low, high ->
|> quicksort (partitionIndex + 1) high
swap : Nat, Nat, List a -> List a
swap : U64, U64, List a -> List a
swap = \i, j, list ->
when Pair (List.get list i) (List.get list j) is
Pair (Ok atI) (Ok atJ) ->
@ -21,7 +21,7 @@ swap = \i, j, list ->
[]
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
partition : U64, U64, List (Num a) -> [Pair U64 (List (Num a))]
partition = \low, high, initialList ->
when List.get initialList high is
Ok pivot ->
@ -33,7 +33,7 @@ partition = \low, high, initialList ->
Pair (low - 1) initialList
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [Pair Nat (List (Num a))]
partitionHelp : U64, U64, List (Num a), U64, (Num a) -> [Pair U64 (List (Num a))]
partitionHelp = \i, j, list, high, pivot ->
if j < high then
when List.get list j is

View file

@ -1,6 +1,6 @@
app "quicksort" provides [quicksort] to "./platform"
quicksortHelp : List (Num a), Nat, Nat -> List (Num a)
quicksortHelp : List (Num a), U64, U64 -> List (Num a)
quicksortHelp = \list, low, high ->
if low < high then
when partition low high list is
@ -12,7 +12,7 @@ quicksortHelp = \list, low, high ->
list
swap : Nat, Nat, List a -> List a
swap : U64, U64, List a -> List a
swap = \i, j, list ->
when Pair (List.get list i) (List.get list j) is
Pair (Ok atI) (Ok atJ) ->
@ -23,7 +23,7 @@ swap = \i, j, list ->
_ ->
[]
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
partition : U64, U64, List (Num a) -> [Pair U64 (List (Num a))]
partition = \low, high, initialList ->
when List.get initialList high is
Ok pivot ->
@ -35,7 +35,7 @@ partition = \low, high, initialList ->
Pair (low - 1) initialList
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [Pair Nat (List (Num a))]
partitionHelp : U64, U64, List (Num a), U64, (Num a) -> [Pair U64 (List (Num a))]
partitionHelp = \i, j, list, high, pivot ->
if j < high then
when List.get list j is

View file

@ -2,7 +2,7 @@ interface Quicksort
exposes [swap, partition, quicksort]
imports []
quicksort : List (Num a), Nat, Nat -> List (Num a)
quicksort : List (Num a), U64, U64 -> List (Num a)
quicksort = \list, low, high ->
when partition low high list is
Pair partitionIndex partitioned ->
@ -11,7 +11,7 @@ quicksort = \list, low, high ->
|> quicksort (partitionIndex + 1) high
swap : Nat, Nat, List a -> List a
swap : U64, U64, List a -> List a
swap = \i, j, list ->
when Pair (List.get list i) (List.get list j) is
Pair (Ok atI) (Ok atJ) ->
@ -23,7 +23,7 @@ swap = \i, j, list ->
[]
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
partition : U64, U64, List (Num a) -> [Pair U64 (List (Num a))]
partition = \low, high, initialList ->
when List.get initialList high is
Ok pivot ->
@ -35,7 +35,7 @@ partition = \low, high, initialList ->
Pair (low - 1) initialList
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [Pair Nat (List (Num a))]
partitionHelp : U64, U64, List (Num a), U64, (Num a) -> [Pair U64 (List (Num a))]
partitionHelp = \i, j, list, high, pivot ->
if j < high then
when List.get list j is

View file

@ -0,0 +1,20 @@
## An interface for docs tests
interface Docs
exposes [makeUser, getNameExposed]
imports []
## This is a user
User : { name : Str }
## Makes a user
##
## Takes a name Str.
makeUser : Str -> User
makeUser = \name ->
{ name }
## Gets the user's name
getName = \a -> a.name
getNameExposed = getName

View file

@ -17,6 +17,7 @@ mod helpers;
use crate::helpers::fixtures_dir;
use bumpalo::Bump;
use roc_can::module::ExposedByModule;
use roc_load_internal::docs::DocDef;
use roc_load_internal::file::{
ExecutionMode, LoadConfig, LoadResult, LoadStart, LoadingProblem, Threading,
};
@ -26,11 +27,12 @@ use roc_module::symbol::{Interns, ModuleId};
use roc_packaging::cache::RocCacheDir;
use roc_problem::can::Problem;
use roc_region::all::LineInfo;
use roc_reporting::report::RenderTarget;
use roc_reporting::report::RocDocAllocator;
use roc_reporting::report::{can_problem, DEFAULT_PALETTE};
use roc_reporting::report::{strip_colors, RenderTarget};
use roc_solve::FunctionKind;
use roc_target::TargetInfo;
use roc_target::Target;
use roc_test_utils_dir::TmpDir;
use roc_types::pretty_print::name_and_print_var;
use roc_types::pretty_print::DebugPrint;
use std::collections::HashMap;
@ -40,7 +42,7 @@ fn load_and_typecheck(
arena: &Bump,
filename: PathBuf,
exposed_types: ExposedByModule,
target_info: TargetInfo,
target: Target,
function_kind: FunctionKind,
) -> Result<LoadedModule, LoadingProblem> {
use LoadResult::*;
@ -53,7 +55,7 @@ fn load_and_typecheck(
DEFAULT_PALETTE,
)?;
let load_config = LoadConfig {
target_info,
target,
function_kind,
render: RenderTarget::Generic,
palette: DEFAULT_PALETTE,
@ -74,7 +76,7 @@ fn load_and_typecheck(
}
}
const TARGET_INFO: roc_target::TargetInfo = roc_target::TargetInfo::default_x86_64();
const TARGET: Target = Target::LinuxX64;
// HELPERS
@ -152,7 +154,7 @@ fn multiple_modules_help<'a>(
// We can't have all tests use "tmp" because tests run in parallel,
// so append the test name to the tmp path.
let tmp = format!("tmp/{subdir}");
let dir = roc_test_utils::TmpDir::new(&tmp);
let dir = TmpDir::new(&tmp);
let app_module = files.pop().unwrap();
@ -183,7 +185,7 @@ fn multiple_modules_help<'a>(
arena,
full_file_path,
Default::default(),
TARGET_INFO,
TARGET,
FunctionKind::LambdaSet,
)
};
@ -203,7 +205,7 @@ fn load_fixture(
&arena,
filename,
subs_by_module,
TARGET_INFO,
TARGET,
FunctionKind::LambdaSet,
);
let mut loaded_module = match loaded {
@ -334,7 +336,7 @@ fn import_transitive_alias() {
// with variables in the importee
let modules = vec![
(
"RBTree",
"RBTree.roc",
indoc!(
r"
interface RBTree exposes [RedBlackTree, empty] imports []
@ -352,7 +354,7 @@ fn import_transitive_alias() {
),
),
(
"Other",
"Other.roc",
indoc!(
r"
interface Other exposes [empty] imports []
@ -379,7 +381,7 @@ fn interface_with_deps() {
&arena,
filename,
subs_by_module,
TARGET_INFO,
TARGET,
FunctionKind::LambdaSet,
);
@ -436,6 +438,53 @@ fn load_unit() {
);
}
#[test]
fn load_docs() {
let subs_by_module = Default::default();
let loaded_module = load_fixture("no_deps", "Docs", subs_by_module);
let module_docs = loaded_module
.docs_by_module
.get(&loaded_module.module_id)
.expect("module should have docs");
let all_docs = module_docs
.entries
.iter()
.map(|a| match a {
roc_load_internal::docs::DocEntry::DocDef(DocDef { name, docs, .. }) => {
(Some(name.clone()), docs.clone().map(|a| a.to_string()))
}
roc_load_internal::docs::DocEntry::ModuleDoc(docs)
| roc_load_internal::docs::DocEntry::DetachedDoc(docs) => (None, Some(docs.clone())),
})
.collect::<Vec<_>>();
let expected = vec![
(None, Some("An interface for docs tests\n")),
(Some("User"), Some("This is a user\n")),
(
Some("makeUser"),
Some("Makes a user\n\nTakes a name Str.\n"),
),
(Some("getName"), Some("Gets the user's name\n")),
(Some("getNameExposed"), None),
]
.into_iter()
.map(|(ident_str_opt, doc_str_opt)| {
(
ident_str_opt.map(|a| a.to_string()),
doc_str_opt.map(|b| b.to_string()),
)
})
.collect::<Vec<_>>();
// let has_all_docs = expected.map(|a| docs.contains(&a)).all(|a| a);
// assert!(has_all_docs, "Some of the expected docs were not created")
assert_eq!(expected, all_docs);
}
#[test]
fn import_alias() {
let subs_by_module = Default::default();
@ -514,10 +563,10 @@ fn iface_quicksort() {
expect_types(
loaded_module,
hashmap! {
"swap" => "Nat, Nat, List a -> List a",
"partition" => "Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]",
"partitionHelp" => "Nat, Nat, List (Num a), Nat, Num a -> [Pair Nat (List (Num a))]",
"quicksort" => "List (Num a), Nat, Nat -> List (Num a)",
"swap" => "U64, U64, List a -> List a",
"partition" => "U64, U64, List (Num a) -> [Pair U64 (List (Num a))]",
"partitionHelp" => "U64, U64, List (Num a), U64, Num a -> [Pair U64 (List (Num a))]",
"quicksort" => "List (Num a), U64, U64 -> List (Num a)",
},
);
}
@ -530,10 +579,10 @@ fn quicksort_one_def() {
expect_types(
loaded_module,
hashmap! {
"swap" => "Nat, Nat, List a -> List a",
"partition" => "Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]",
"partitionHelp" => "Nat, Nat, List (Num a), Nat, Num a -> [Pair Nat (List (Num a))]",
"quicksortHelp" => "List (Num a), Nat, Nat -> List (Num a)",
"swap" => "U64, U64, List a -> List a",
"partition" => "U64, U64, List (Num a) -> [Pair U64 (List (Num a))]",
"partitionHelp" => "U64, U64, List (Num a), U64, Num a -> [Pair U64 (List (Num a))]",
"quicksortHelp" => "List (Num a), U64, U64 -> List (Num a)",
"quicksort" => "List (Num a) -> List (Num a)",
},
);
@ -547,10 +596,10 @@ fn app_quicksort() {
expect_types(
loaded_module,
hashmap! {
"swap" => "Nat, Nat, List a -> List a",
"partition" => "Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]",
"partitionHelp" => "Nat, Nat, List (Num a), Nat, Num a -> [Pair Nat (List (Num a))]",
"quicksort" => "List (Num a), Nat, Nat -> List (Num a)",
"swap" => "U64, U64, List a -> List a",
"partition" => "U64, U64, List (Num a) -> [Pair U64 (List (Num a))]",
"partitionHelp" => "U64, U64, List (Num a), U64, Num a -> [Pair U64 (List (Num a))]",
"quicksort" => "List (Num a), U64, U64 -> List (Num a)",
},
);
}
@ -676,7 +725,7 @@ fn ingested_file_bytes() {
#[test]
fn parse_problem() {
let modules = vec![(
"Main",
"Main.roc",
indoc!(
r"
interface Main exposes [main] imports []
@ -691,7 +740,7 @@ fn parse_problem() {
report,
indoc!(
"
UNFINISHED LIST in tmp/parse_problem/Main
UNFINISHED LIST in tmp/parse_problem/Main.roc
I am partway through started parsing a list, but I got stuck here:
@ -757,7 +806,7 @@ fn ingested_file_not_found() {
#[test]
fn platform_does_not_exist() {
let modules = vec![(
"Main",
"main.roc",
indoc!(
r#"
app "example"
@ -803,7 +852,7 @@ fn platform_parse_error() {
),
),
(
"Main",
"main.roc",
indoc!(
r#"
app "hello-world"
@ -847,7 +896,7 @@ fn platform_exposes_main_return_by_pointer_issue() {
),
),
(
"Main",
"main.roc",
indoc!(
r#"
app "hello-world"
@ -868,7 +917,7 @@ fn platform_exposes_main_return_by_pointer_issue() {
fn opaque_wrapped_unwrapped_outside_defining_module() {
let modules = vec![
(
"Age",
"Age.roc",
indoc!(
r"
interface Age exposes [Age] imports []
@ -878,7 +927,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
),
),
(
"Main",
"Main.roc",
indoc!(
r"
interface Main exposes [twenty, readAge] imports []
@ -899,7 +948,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
err,
indoc!(
r"
OPAQUE TYPE DECLARED OUTSIDE SCOPE in ...apped_outside_defining_module/Main
OPAQUE TYPE DECLARED OUTSIDE SCOPE in ...d_outside_defining_module/Main.roc
The unwrapped opaque type Age referenced here:
@ -913,7 +962,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
Note: Opaque types can only be wrapped and unwrapped in the module they are defined in!
OPAQUE TYPE DECLARED OUTSIDE SCOPE in ...apped_outside_defining_module/Main
OPAQUE TYPE DECLARED OUTSIDE SCOPE in ...d_outside_defining_module/Main.roc
The unwrapped opaque type Age referenced here:
@ -927,7 +976,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
Note: Opaque types can only be wrapped and unwrapped in the module they are defined in!
UNUSED IMPORT in tmp/opaque_wrapped_unwrapped_outside_defining_module/Main
UNUSED IMPORT in ...aque_wrapped_unwrapped_outside_defining_module/Main.roc
Age is imported but not used.
@ -946,7 +995,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
fn unused_imports() {
let modules = vec![
(
"Dep1",
"Dep1.roc",
indoc!(
r#"
interface Dep1 exposes [one] imports []
@ -955,7 +1004,7 @@ fn unused_imports() {
),
),
(
"Dep2",
"Dep2.roc",
indoc!(
r#"
interface Dep2 exposes [two] imports []
@ -964,7 +1013,7 @@ fn unused_imports() {
),
),
(
"Dep3",
"Dep3.roc",
indoc!(
r#"
interface Dep3 exposes [Three, three] imports []
@ -976,7 +1025,7 @@ fn unused_imports() {
),
),
(
"Main",
"Main.roc",
indoc!(
r#"
interface Main exposes [usedModule, unusedModule, unusedExposed, usingThreeValue] imports []
@ -1008,7 +1057,7 @@ fn unused_imports() {
err,
indoc!(
r"
UNUSED IMPORT in tmp/unused_imports/Main
UNUSED IMPORT in tmp/unused_imports/Main.roc
Dep2 is imported but not used.
@ -1017,7 +1066,7 @@ fn unused_imports() {
Since Dep2 isn't used, you don't need to import it.
UNUSED IMPORT in tmp/unused_imports/Main
UNUSED IMPORT in tmp/unused_imports/Main.roc
Dep2 is imported but not used.
@ -1026,7 +1075,7 @@ fn unused_imports() {
Since Dep2 isn't used, you don't need to import it.
UNUSED IMPORT in tmp/unused_imports/Main
UNUSED IMPORT in tmp/unused_imports/Main.roc
Dep1 is imported but not used.
@ -1035,7 +1084,7 @@ fn unused_imports() {
Since Dep1 isn't used, you don't need to import it.
UNUSED IMPORT in tmp/unused_imports/Main
UNUSED IMPORT in tmp/unused_imports/Main.roc
`Dep3.Three` is not used in this module.
@ -1070,7 +1119,7 @@ fn issue_2863_module_type_does_not_exist() {
),
),
(
"Main",
"main.roc",
indoc!(
r#"
app "test"
@ -1090,7 +1139,7 @@ fn issue_2863_module_type_does_not_exist() {
report,
indoc!(
"
UNRECOGNIZED NAME in tmp/issue_2863_module_type_does_not_exist/Main
UNRECOGNIZED NAME in tmp/issue_2863_module_type_does_not_exist/main.roc
Nothing is named `DoesNotExist` in this scope.
@ -1133,7 +1182,7 @@ fn import_builtin_in_platform_and_check_app() {
),
),
(
"Main",
"main.roc",
indoc!(
r#"
app "test"
@ -1153,7 +1202,7 @@ fn import_builtin_in_platform_and_check_app() {
#[test]
fn module_doesnt_match_file_path() {
let modules = vec![(
"Age",
"Age.roc",
indoc!(
r"
interface NotAge exposes [Age] imports []
@ -1168,7 +1217,7 @@ fn module_doesnt_match_file_path() {
err,
indoc!(
r"
WEIRD MODULE NAME in tmp/module_doesnt_match_file_path/Age
WEIRD MODULE NAME in tmp/module_doesnt_match_file_path/Age.roc
This module name does not correspond with the file path it is defined
in:
@ -1188,7 +1237,7 @@ fn module_doesnt_match_file_path() {
#[test]
fn module_cyclic_import_itself() {
let modules = vec![(
"Age",
"Age.roc",
indoc!(
r"
interface Age exposes [] imports []
@ -1203,7 +1252,7 @@ fn module_cyclic_import_itself() {
err,
indoc!(
r"
IMPORT CYCLE in tmp/module_cyclic_import_itself/Age
IMPORT CYCLE in tmp/module_cyclic_import_itself/Age.roc
I can't compile Age because it depends on itself through the following
chain of module imports:
@ -1226,7 +1275,7 @@ fn module_cyclic_import_itself() {
fn module_cyclic_import_transitive() {
let modules = vec![
(
"Age",
"Age.roc",
indoc!(
r"
interface Age exposes [] imports []
@ -1235,7 +1284,7 @@ fn module_cyclic_import_transitive() {
),
),
(
"Person",
"Person.roc",
indoc!(
r"
interface Person exposes [] imports []
@ -1271,3 +1320,62 @@ fn module_cyclic_import_transitive() {
err
);
}
#[test]
fn non_roc_file_extension() {
let modules = vec![(
"main.md",
indoc!(
r"
# Not a roc file
"
),
)];
let expected = indoc!(
r"
NOT A ROC FILE in tmp/non_roc_file_extension/main.md
I expected a file with extension `.roc` or without extension.
Instead I received a file with extension `.md`."
);
let err = strip_colors(&multiple_modules("non_roc_file_extension", modules).unwrap_err());
assert_eq!(err, expected, "\n{}", err);
}
#[test]
fn roc_file_no_extension() {
let modules = vec![(
"main",
indoc!(
r#"
app "helloWorld"
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" }
imports [pf.Stdout]
provides [main] to pf
main =
Stdout.line "Hello, World!"
"#
),
)];
let expected = indoc!(
r"
NOT A ROC FILE in tmp/roc_file_no_extension/main
I expected a file with either:
- extension `.roc`
- no extension and a roc shebang as the first line, e.g.
`#!/home/username/bin/roc_nightly/roc`
The provided file did not start with a shebang `#!` containing the
string `roc`. Is tmp/roc_file_no_extension/main a Roc file?"
);
let err = strip_colors(&multiple_modules("roc_file_no_extension", modules).unwrap_err());
assert_eq!(err, expected, "\n{}", err);
}