mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-01 13:34:15 +00:00
Merge remote-tracking branch 'origin/main' into abilities-syntax
This commit is contained in:
commit
2da41be29f
524 changed files with 47536 additions and 15089 deletions
|
|
@ -11,16 +11,19 @@ use roc_mono::{
|
|||
use tempfile::tempdir;
|
||||
use test_solve_helpers::format_problems;
|
||||
|
||||
use crate::CompilerSettings;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MonoOptions {
|
||||
pub(crate) struct MonoOptions {
|
||||
pub no_check: bool,
|
||||
}
|
||||
|
||||
pub fn write_compiled_ir<'a>(
|
||||
pub(crate) fn write_compiled_ir<'a>(
|
||||
writer: &mut impl io::Write,
|
||||
test_module: &str,
|
||||
dependencies: impl IntoIterator<Item = (&'a str, &'a str)>,
|
||||
options: MonoOptions,
|
||||
compiler_settings: CompilerSettings,
|
||||
allow_can_errors: bool,
|
||||
) -> io::Result<()> {
|
||||
use roc_packaging::cache::RocCacheDir;
|
||||
|
|
@ -41,6 +44,7 @@ pub fn write_compiled_ir<'a>(
|
|||
|
||||
let load_config = LoadConfig {
|
||||
target_info: roc_target::TargetInfo::default_x86_64(),
|
||||
function_kind: compiler_settings.function_kind,
|
||||
threading: Threading::Single,
|
||||
render: roc_reporting::report::RenderTarget::Generic,
|
||||
palette: roc_reporting::report::DEFAULT_PALETTE,
|
||||
|
|
@ -60,10 +64,10 @@ pub fn write_compiled_ir<'a>(
|
|||
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
||||
report,
|
||||
))) => {
|
||||
println!("{}", report);
|
||||
println!("{report}");
|
||||
panic!();
|
||||
}
|
||||
Err(e) => panic!("{:?}", e),
|
||||
Err(e) => panic!("{e:?}"),
|
||||
};
|
||||
|
||||
use roc_load::MonomorphizedModule;
|
||||
|
|
@ -146,9 +150,9 @@ fn write_procedures<'a>(
|
|||
let mut procs = procs_strings.iter().peekable();
|
||||
while let Some(proc) = procs.next() {
|
||||
if procs.peek().is_some() {
|
||||
writeln!(writer, "{}", proc)?;
|
||||
writeln!(writer, "{proc}")?;
|
||||
} else {
|
||||
write!(writer, "{}", proc)?;
|
||||
write!(writer, "{proc}")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use libtest_mimic::{run, Arguments, Failed, Trial};
|
|||
use mono::MonoOptions;
|
||||
use regex::Regex;
|
||||
use roc_collections::VecMap;
|
||||
use roc_solve::FunctionKind;
|
||||
use test_solve_helpers::{
|
||||
infer_queries, Elaboration, InferOptions, InferredProgram, InferredQuery, MUTLILINE_MARKER,
|
||||
};
|
||||
|
|
@ -36,6 +37,10 @@ lazy_static! {
|
|||
.join("uitest")
|
||||
.join("tests");
|
||||
|
||||
/// # +set <setting>
|
||||
static ref RE_SETTING: Regex =
|
||||
Regex::new(r#"# \+set (?P<setting>.*?)=(?P<value>.*)"#).unwrap();
|
||||
|
||||
/// # +opt can:<opt>
|
||||
static ref RE_OPT_CAN: Regex =
|
||||
Regex::new(r#"# \+opt can:(?P<opt>.*)"#).unwrap();
|
||||
|
|
@ -94,6 +99,7 @@ fn into_test(path: PathBuf) -> io::Result<Trial> {
|
|||
fn run_test(path: PathBuf) -> Result<(), Failed> {
|
||||
let data = std::fs::read_to_string(&path)?;
|
||||
let TestCase {
|
||||
compiler_settings,
|
||||
can_options,
|
||||
infer_options,
|
||||
emit_options,
|
||||
|
|
@ -109,6 +115,7 @@ fn run_test(path: PathBuf) -> Result<(), Failed> {
|
|||
.map(|(md, src)| (&**md, &**src)),
|
||||
infer_options,
|
||||
can_options.allow_errors,
|
||||
compiler_settings.function_kind,
|
||||
)?;
|
||||
|
||||
{
|
||||
|
|
@ -121,6 +128,7 @@ fn run_test(path: PathBuf) -> Result<(), Failed> {
|
|||
&mut fd,
|
||||
program,
|
||||
inferred_program,
|
||||
compiler_settings,
|
||||
can_options,
|
||||
mono_options,
|
||||
emit_options,
|
||||
|
|
@ -141,6 +149,7 @@ struct Modules<'a> {
|
|||
}
|
||||
|
||||
struct TestCase<'a> {
|
||||
compiler_settings: CompilerSettings,
|
||||
can_options: CanOptions,
|
||||
infer_options: InferOptions,
|
||||
mono_options: MonoOptions,
|
||||
|
|
@ -148,6 +157,18 @@ struct TestCase<'a> {
|
|||
program: Modules<'a>,
|
||||
}
|
||||
|
||||
struct CompilerSettings {
|
||||
function_kind: FunctionKind,
|
||||
}
|
||||
|
||||
impl Default for CompilerSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
function_kind: FunctionKind::LambdaSet,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct CanOptions {
|
||||
allow_errors: bool,
|
||||
|
|
@ -166,6 +187,7 @@ impl<'a> TestCase<'a> {
|
|||
data = data[..drop_at].trim_end();
|
||||
}
|
||||
|
||||
let compiler_settings = Self::parse_compiler_settings(data)?;
|
||||
let can_options = Self::parse_can_options(data)?;
|
||||
let infer_options = Self::parse_infer_options(data)?;
|
||||
let mono_options = Self::parse_mono_options(data)?;
|
||||
|
|
@ -174,6 +196,7 @@ impl<'a> TestCase<'a> {
|
|||
let program = Self::parse_modules(data);
|
||||
|
||||
Ok(TestCase {
|
||||
compiler_settings,
|
||||
can_options,
|
||||
infer_options,
|
||||
mono_options,
|
||||
|
|
@ -229,6 +252,26 @@ impl<'a> TestCase<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_compiler_settings(data: &str) -> Result<CompilerSettings, Failed> {
|
||||
let mut settings = CompilerSettings::default();
|
||||
|
||||
let found_settings = RE_SETTING.captures_iter(data);
|
||||
for set in found_settings {
|
||||
let setting = set.name("setting").unwrap().as_str();
|
||||
let value = set.name("value").unwrap().as_str();
|
||||
match setting.trim() {
|
||||
"function_kind" => match value.trim() {
|
||||
"lambda_set" => settings.function_kind = FunctionKind::LambdaSet,
|
||||
"erased" => settings.function_kind = FunctionKind::Erased,
|
||||
other => return Err(format!("unknown function kind: {other:?}").into()),
|
||||
},
|
||||
other => return Err(format!("unknown compiler setting: {other:?}").into()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(settings)
|
||||
}
|
||||
|
||||
fn parse_can_options(data: &str) -> Result<CanOptions, Failed> {
|
||||
let mut can_opts = CanOptions::default();
|
||||
|
||||
|
|
@ -321,6 +364,7 @@ fn assemble_query_output(
|
|||
writer: &mut impl io::Write,
|
||||
program: Modules<'_>,
|
||||
inferred_program: InferredProgram,
|
||||
compiler_settings: CompilerSettings,
|
||||
can_options: CanOptions,
|
||||
mono_options: MonoOptions,
|
||||
emit_options: EmitOptions,
|
||||
|
|
@ -337,7 +381,7 @@ fn assemble_query_output(
|
|||
|
||||
for (module, source) in other_modules.iter() {
|
||||
writeln!(writer, "## module {module}")?;
|
||||
writeln!(writer, "{}\n", source)?;
|
||||
writeln!(writer, "{source}\n")?;
|
||||
}
|
||||
|
||||
if !other_modules.is_empty() {
|
||||
|
|
@ -369,6 +413,7 @@ fn assemble_query_output(
|
|||
test_module,
|
||||
other_modules,
|
||||
mono_options,
|
||||
compiler_settings,
|
||||
can_options.allow_errors,
|
||||
)?;
|
||||
}
|
||||
|
|
@ -393,7 +438,7 @@ fn write_source_with_answers<W: io::Write>(
|
|||
Some(InferredQuery {
|
||||
source_line_column,
|
||||
..
|
||||
}) if source_line_column.line == i as _
|
||||
}) if source_line_column.line == i as u32
|
||||
) {
|
||||
let inferred = sorted_queries.pop().unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@ main =
|
|||
s2 = Set.empty {}
|
||||
|
||||
Bool.isEq s1 s1 && Bool.isEq s2 s2
|
||||
# ^^^^^^^^^ Set#Bool.isEq(17): Set Str, Set Str -[[Set.isEq(17)]]-> Bool
|
||||
# ^^^^^^^^^ Set#Bool.isEq(17): Set U8, Set U8 -[[Set.isEq(17)]]-> Bool
|
||||
# ^^^^^^^^^ Set#Bool.isEq(20): Set Str, Set Str -[[Set.isEq(20)]]-> Bool
|
||||
# ^^^^^^^^^ Set#Bool.isEq(20): Set U8, Set U8 -[[Set.isEq(20)]]-> Bool
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
# +set function_kind=erased
|
||||
# +emit:mono
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
f = \s ->
|
||||
if Bool.true
|
||||
then \{} -> ""
|
||||
# ^^^^^^^^^ {}* -?-> Str
|
||||
else \{} -> s
|
||||
# ^^^^^^^^ {}* -?-> Str
|
||||
|
||||
main = (f "") {}
|
||||
# ^^^^ {} -?-> Str
|
||||
|
||||
# -emit:mono
|
||||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Test.1 (Test.2):
|
||||
let Test.34 : Int1 = CallByName Bool.2;
|
||||
if Test.34 then
|
||||
dec Test.2;
|
||||
let Test.38 : FunPtr(({}) -> Str) = FunctionPointer Test.3;
|
||||
let Test.35 : ?Erased = ErasedMake { value: <null>, callee: Test.38 };
|
||||
ret Test.35;
|
||||
else
|
||||
let Test.33 : {Str} = Struct {Test.2};
|
||||
let Test.31 : [<rnu><null>, C {Str}] = TagId(0) Test.33;
|
||||
let Test.32 : FunPtr(({}, ?Erased) -> Str) = FunctionPointer Test.4;
|
||||
let Test.26 : ?Erased = ErasedMake { value: Test.31, callee: Test.32 };
|
||||
ret Test.26;
|
||||
|
||||
procedure Test.3 (Test.36):
|
||||
let Test.37 : Str = "";
|
||||
ret Test.37;
|
||||
|
||||
procedure Test.4 (Test.27, #Attr.12):
|
||||
let Test.29 : [<rnu><null>, C {Str}] = ErasedLoad #Attr.12 .Value;
|
||||
let Test.30 : {Str} = UnionAtIndex (Id 0) (Index 0) Test.29;
|
||||
joinpoint #Derived_gen.0:
|
||||
let Test.2 : Str = StructAtIndex 0 Test.30;
|
||||
ret Test.2;
|
||||
in
|
||||
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.29;
|
||||
if #Derived_gen.1 then
|
||||
free Test.29;
|
||||
jump #Derived_gen.0;
|
||||
else
|
||||
inc Test.30;
|
||||
decref Test.29;
|
||||
jump #Derived_gen.0;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.6 : {} = Struct {};
|
||||
let Test.16 : Str = "";
|
||||
let Test.39 : FunPtr((Str) -> ?Erased) = FunctionPointer Test.1;
|
||||
let Test.17 : ?Erased = ErasedMake { value: <null>, callee: Test.39 };
|
||||
joinpoint Test.18 Test.7:
|
||||
joinpoint Test.8 Test.5:
|
||||
ret Test.5;
|
||||
in
|
||||
let Test.9 : Ptr([]) = ErasedLoad Test.7 .ValuePtr;
|
||||
let Test.11 : Ptr([]) = NullPointer;
|
||||
let Test.10 : Int1 = lowlevel Eq Test.9 Test.11;
|
||||
if Test.10 then
|
||||
dec Test.7;
|
||||
let Test.12 : FunPtr(({}) -> Str) = ErasedLoad Test.7 .Callee;
|
||||
let Test.13 : Str = CallByPtr Test.12 Test.6;
|
||||
jump Test.8 Test.13;
|
||||
else
|
||||
let Test.14 : FunPtr(({}, ?Erased) -> Str) = ErasedLoad Test.7 .Callee;
|
||||
let Test.15 : Str = CallByPtr Test.14 Test.6 Test.7;
|
||||
jump Test.8 Test.15;
|
||||
in
|
||||
let Test.19 : Ptr([]) = ErasedLoad Test.17 .ValuePtr;
|
||||
let Test.21 : Ptr([]) = NullPointer;
|
||||
let Test.20 : Int1 = lowlevel Eq Test.19 Test.21;
|
||||
if Test.20 then
|
||||
dec Test.17;
|
||||
let Test.22 : FunPtr((Str) -> ?Erased) = ErasedLoad Test.17 .Callee;
|
||||
let Test.23 : ?Erased = CallByPtr Test.22 Test.16;
|
||||
jump Test.18 Test.23;
|
||||
else
|
||||
let Test.24 : FunPtr((Str, ?Erased) -> ?Erased) = ErasedLoad Test.17 .Callee;
|
||||
let Test.25 : ?Erased = CallByPtr Test.24 Test.16 Test.17;
|
||||
jump Test.18 Test.25;
|
||||
|
|
@ -3,22 +3,22 @@
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
f = \{} ->
|
||||
#^{-1} <1599><116>{} -<119>[[f(1)]]-> <115>[Ok <1607>{}]<79>*
|
||||
#^{-1} <1600><117>{} -<120>[[f(1)]]-> <116>[Ok <1608>{}]<80>*
|
||||
when g {} is
|
||||
# ^ <1589><1607>{} -<1597>[[g(2)]]-> <71>[Ok <1607>{}]<101>*
|
||||
# ^ <1590><1608>{} -<1598>[[g(2)]]-> <72>[Ok <1608>{}]<102>*
|
||||
_ -> Ok {}
|
||||
|
||||
g = \{} ->
|
||||
#^{-1} <1589><1607>{} -<1597>[[g(2)]]-> <71>[Ok <1607>{}]<101>*
|
||||
#^{-1} <1590><1608>{} -<1598>[[g(2)]]-> <72>[Ok <1608>{}]<102>*
|
||||
when h {} is
|
||||
# ^ <1594><1607>{} -<1602>[[h(3)]]-> <93>[Ok <1607>{}]<123>*
|
||||
# ^ <1595><1608>{} -<1603>[[h(3)]]-> <94>[Ok <1608>{}]<124>*
|
||||
_ -> Ok {}
|
||||
|
||||
h = \{} ->
|
||||
#^{-1} <1594><1607>{} -<1602>[[h(3)]]-> <93>[Ok <1607>{}]<123>*
|
||||
#^{-1} <1595><1608>{} -<1603>[[h(3)]]-> <94>[Ok <1608>{}]<124>*
|
||||
when f {} is
|
||||
# ^ <1599><116>{} -<119>[[f(1)]]-> <115>[Ok <1607>{}]<79>*
|
||||
# ^ <1600><117>{} -<120>[[f(1)]]-> <116>[Ok <1608>{}]<80>*
|
||||
_ -> Ok {}
|
||||
|
||||
main = f {}
|
||||
# ^ <1609><132>{} -<135>[[f(1)]]-> <137>[Ok <1607>{}]<1608>w_a
|
||||
# ^ <1610><133>{} -<136>[[f(1)]]-> <138>[Ok <1608>{}]<1609>w_a
|
||||
|
|
|
|||
19
crates/compiler/uitest/tests/recursive_type/issue_5476.txt
Normal file
19
crates/compiler/uitest/tests/recursive_type/issue_5476.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
interface Test exposes [main] imports []
|
||||
|
||||
Term : [
|
||||
Bar Term,
|
||||
Foo,
|
||||
]
|
||||
|
||||
f = \list ->
|
||||
when list is
|
||||
# ^^^^ List ([Bar [Bar a]*, Foo]* as a)
|
||||
[] -> Foo
|
||||
[b] -> b
|
||||
[b, ..] -> Bar (Bar b)
|
||||
|
||||
whatever : Term -> Str
|
||||
whatever = \_ -> "done"
|
||||
|
||||
main = whatever (f [])
|
||||
# ^^ List ([Bar a, Foo] as a)
|
||||
Loading…
Add table
Add a link
Reference in a new issue