diff --git a/compiler/fmt/src/expr.rs b/compiler/fmt/src/expr.rs index f5cad3cc34..b54ff826b2 100644 --- a/compiler/fmt/src/expr.rs +++ b/compiler/fmt/src/expr.rs @@ -117,6 +117,7 @@ impl<'a> Formattable for Expr<'a> { ) { use self::Expr::*; + //dbg!(self); let format_newlines = newlines == Newlines::Yes; let apply_needs_parens = parens == Parens::InApply; @@ -453,14 +454,17 @@ fn fmt_bin_ops<'a, 'buf>( || (&loc_right_side.value).is_multiline() || lefts.iter().any(|(expr, _)| expr.value.is_multiline()); + let mut curr_indent = indent; + for (loc_left_side, loc_bin_op) in lefts { let bin_op = loc_bin_op.value; - loc_left_side.format_with_options(buf, apply_needs_parens, Newlines::No, indent); + loc_left_side.format_with_options(buf, apply_needs_parens, Newlines::No, curr_indent); if is_multiline { buf.newline(); - buf.indent(indent + INDENT); + curr_indent = indent + INDENT; + buf.indent(curr_indent); } else { buf.spaces(1); } diff --git a/compiler/fmt/tests/test_fmt.rs b/compiler/fmt/tests/test_fmt.rs index 72034e879e..c5bde106a7 100644 --- a/compiler/fmt/tests/test_fmt.rs +++ b/compiler/fmt/tests/test_fmt.rs @@ -2595,7 +2595,7 @@ mod test_fmt { } #[test] - fn pipline_apply_lambda() { + fn pipline_apply_lambda_1() { expr_formats_same(indoc!( r#" shout @@ -2606,6 +2606,19 @@ mod test_fmt { )); } + #[test] + fn pipline_apply_lambda_2() { + expr_formats_same(indoc!( + r#" + shout + |> List.map + xs + (\i -> i) + |> List.join + "# + )); + } + // MODULES #[test] diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index 20ead798d2..92c62194c0 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -24,7 +24,7 @@ use crate::llvm::build_str::{ }; use crate::llvm::compare::{generic_eq, generic_neq}; use crate::llvm::convert::{ - self, basic_type_from_builtin, basic_type_from_layout, basic_type_from_layout_1, + self, argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, block_of_memory_slices, }; use crate::llvm::refcounting::{ @@ -2605,6 +2605,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>( let align_bytes = layout.alignment_bytes(env.target_info); if align_bytes > 0 { + debug_assert!(value.is_pointer_value(), "{:?}\n{:?}", value, layout); let value_ptr = value.into_pointer_value(); // We can only do this if the function itself writes data into this @@ -4249,7 +4250,7 @@ fn build_proc_header<'a, 'ctx, 'env>( let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena); for (layout, _) in args.iter() { - let arg_type = basic_type_from_layout_1(env, layout); + let arg_type = argument_type_from_layout(env, layout); arg_basic_types.push(arg_type); } diff --git a/compiler/gen_llvm/src/llvm/build_hash.rs b/compiler/gen_llvm/src/llvm/build_hash.rs index 1c3a4b439d..94ffe8b28a 100644 --- a/compiler/gen_llvm/src/llvm/build_hash.rs +++ b/compiler/gen_llvm/src/llvm/build_hash.rs @@ -4,7 +4,7 @@ use crate::llvm::build::tag_pointer_clear_tag_id; use crate::llvm::build::Env; use crate::llvm::build::{get_tag_id, FAST_CALL_CONV, TAG_DATA_INDEX}; use crate::llvm::build_str; -use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1}; +use crate::llvm::convert::basic_type_from_layout; use bumpalo::collections::Vec; use inkwell::values::{ BasicValue, BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue, @@ -13,6 +13,8 @@ use roc_builtins::bitcode; use roc_module::symbol::Symbol; use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout}; +use super::convert::argument_type_from_union_layout; + #[derive(Clone, Debug)] enum WhenRecursive<'a> { Unreachable, @@ -68,9 +70,7 @@ fn build_hash_layout<'a, 'ctx, 'env>( when_recursive, ), - Layout::Union(union_layout) => { - build_hash_tag(env, layout_ids, layout, union_layout, seed, val) - } + Layout::Union(union_layout) => build_hash_tag(env, layout_ids, union_layout, seed, val), Layout::Boxed(_inner_layout) => { // build_hash_box(env, layout_ids, layout, inner_layout, seed, val) @@ -92,14 +92,7 @@ fn build_hash_layout<'a, 'ctx, 'env>( .build_bitcast(val, bt, "i64_to_opaque") .into_pointer_value(); - build_hash_tag( - env, - layout_ids, - &layout, - &union_layout, - seed, - field_cast.into(), - ) + build_hash_tag(env, layout_ids, &union_layout, seed, field_cast.into()) } }, } @@ -313,7 +306,6 @@ fn hash_struct<'a, 'ctx, 'env>( fn build_hash_tag<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, layout_ids: &mut LayoutIds<'a>, - layout: &Layout<'a>, union_layout: &UnionLayout<'a>, seed: IntValue<'ctx>, value: BasicValueEnum<'ctx>, @@ -323,7 +315,7 @@ fn build_hash_tag<'a, 'ctx, 'env>( let symbol = Symbol::GENERIC_HASH; let fn_name = layout_ids - .get(symbol, layout) + .get(symbol, &Layout::Union(*union_layout)) .to_symbol_string(symbol, &env.interns); let function = match env.module.get_function(fn_name.as_str()) { @@ -331,7 +323,7 @@ fn build_hash_tag<'a, 'ctx, 'env>( None => { let seed_type = env.context.i64_type(); - let arg_type = basic_type_from_layout_1(env, layout); + let arg_type = argument_type_from_union_layout(env, union_layout); let function_value = crate::llvm::refcounting::build_header_help( env, @@ -810,7 +802,7 @@ fn hash_ptr_to_struct<'a, 'ctx, 'env>( ) -> IntValue<'ctx> { use inkwell::types::BasicType; - let wrapper_type = basic_type_from_layout_1(env, &Layout::Union(*union_layout)); + let wrapper_type = argument_type_from_union_layout(env, union_layout); // cast the opaque pointer to a pointer of the correct shape let wrapper_ptr = env diff --git a/compiler/gen_llvm/src/llvm/build_list.rs b/compiler/gen_llvm/src/llvm/build_list.rs index dca6e49466..0f7a601e7f 100644 --- a/compiler/gen_llvm/src/llvm/build_list.rs +++ b/compiler/gen_llvm/src/llvm/build_list.rs @@ -43,7 +43,7 @@ fn pass_element_as_opaque<'a, 'ctx, 'env>( env.builder.build_bitcast( element_ptr, env.context.i8_type().ptr_type(AddressSpace::Generic), - "to_opaque", + "pass_element_as_opaque", ) } @@ -75,7 +75,7 @@ pub fn pass_as_opaque<'a, 'ctx, 'env>( env.builder.build_bitcast( ptr, env.context.i8_type().ptr_type(AddressSpace::Generic), - "to_opaque", + "pass_as_opaque", ) } @@ -407,10 +407,19 @@ pub fn list_walk_generic<'a, 'ctx, 'env>( ListWalk::WalkBackwardsUntil => todo!(), }; - let default_ptr = builder.build_alloca(default.get_type(), "default_ptr"); - env.builder.build_store(default_ptr, default); + let default_ptr = if default_layout.is_passed_by_reference() { + debug_assert!(default.is_pointer_value()); + default.into_pointer_value() + } else { + let default_ptr = builder.build_alloca(default.get_type(), "default_ptr"); + env.builder.build_store(default_ptr, default); + default_ptr + }; - let result_ptr = env.builder.build_alloca(default.get_type(), "result"); + let result_ptr = { + let basic_type = basic_type_from_layout(env, default_layout); + env.builder.build_alloca(basic_type, "result") + }; match variant { ListWalk::Walk | ListWalk::WalkBackwards => { @@ -467,7 +476,11 @@ pub fn list_walk_generic<'a, 'ctx, 'env>( } } - env.builder.build_load(result_ptr, "load_result") + if default_layout.is_passed_by_reference() { + result_ptr.into() + } else { + env.builder.build_load(result_ptr, "load_result") + } } /// List.range : Int a, Int a -> List (Int a) diff --git a/compiler/gen_llvm/src/llvm/compare.rs b/compiler/gen_llvm/src/llvm/compare.rs index 55c99f17c7..6ea0d2e308 100644 --- a/compiler/gen_llvm/src/llvm/compare.rs +++ b/compiler/gen_llvm/src/llvm/compare.rs @@ -2,7 +2,7 @@ use crate::llvm::bitcode::call_bitcode_fn; use crate::llvm::build::{get_tag_id, tag_pointer_clear_tag_id, Env, FAST_CALL_CONV}; use crate::llvm::build_list::{list_len, load_list_ptr}; use crate::llvm::build_str::str_equal; -use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1}; +use crate::llvm::convert::basic_type_from_layout; use bumpalo::collections::Vec; use inkwell::types::BasicType; use inkwell::values::{ @@ -15,6 +15,7 @@ use roc_module::symbol::Symbol; use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout}; use super::build::load_roc_value; +use super::convert::argument_type_from_union_layout; #[derive(Clone, Debug)] enum WhenRecursive<'a> { @@ -176,7 +177,6 @@ fn build_eq<'a, 'ctx, 'env>( env, layout_ids, when_recursive, - lhs_layout, union_layout, lhs_val, rhs_val, @@ -217,7 +217,6 @@ fn build_eq<'a, 'ctx, 'env>( env, layout_ids, WhenRecursive::Loop(union_layout), - &layout, &union_layout, field1_cast.into(), field2_cast.into(), @@ -361,7 +360,6 @@ fn build_neq<'a, 'ctx, 'env>( env, layout_ids, when_recursive, - lhs_layout, union_layout, lhs_val, rhs_val, @@ -792,7 +790,6 @@ fn build_tag_eq<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, layout_ids: &mut LayoutIds<'a>, when_recursive: WhenRecursive<'a>, - tag_layout: &Layout<'a>, union_layout: &UnionLayout<'a>, tag1: BasicValueEnum<'ctx>, tag2: BasicValueEnum<'ctx>, @@ -800,15 +797,16 @@ fn build_tag_eq<'a, 'ctx, 'env>( let block = env.builder.get_insert_block().expect("to be in a function"); let di_location = env.builder.get_current_debug_location().unwrap(); + let tag_layout = Layout::Union(*union_layout); let symbol = Symbol::GENERIC_EQ; let fn_name = layout_ids - .get(symbol, tag_layout) + .get(symbol, &tag_layout) .to_symbol_string(symbol, &env.interns); let function = match env.module.get_function(fn_name.as_str()) { Some(function_value) => function_value, None => { - let arg_type = basic_type_from_layout_1(env, tag_layout); + let arg_type = argument_type_from_union_layout(env, union_layout); let function_value = crate::llvm::refcounting::build_header_help( env, diff --git a/compiler/gen_llvm/src/llvm/convert.rs b/compiler/gen_llvm/src/llvm/convert.rs index 56ea50f143..6bc0bd0416 100644 --- a/compiler/gen_llvm/src/llvm/convert.rs +++ b/compiler/gen_llvm/src/llvm/convert.rs @@ -1,3 +1,4 @@ +use crate::llvm::build::Env; use bumpalo::collections::Vec; use inkwell::context::Context; use inkwell::types::{BasicType, BasicTypeEnum, FloatType, IntType, StructType}; @@ -7,7 +8,7 @@ use roc_mono::layout::{Builtin, Layout, UnionLayout}; use roc_target::TargetInfo; fn basic_type_from_record<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, + env: &Env<'a, 'ctx, 'env>, fields: &[Layout<'_>], ) -> BasicTypeEnum<'ctx> { let mut field_types = Vec::with_capacity_in(fields.len(), env.arena); @@ -22,7 +23,7 @@ fn basic_type_from_record<'a, 'ctx, 'env>( } pub fn basic_type_from_layout<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, + env: &Env<'a, 'ctx, 'env>, layout: &Layout<'_>, ) -> BasicTypeEnum<'ctx> { use Layout::*; @@ -38,69 +39,32 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>( inner_type.ptr_type(AddressSpace::Generic).into() } - Union(union_layout) => { - use UnionLayout::*; - - let tag_id_type = basic_type_from_layout(env, &union_layout.tag_id_layout()); - - match union_layout { - NonRecursive(tags) => { - let data = block_of_memory_slices(env.context, tags, env.target_info); - - env.context.struct_type(&[data, tag_id_type], false).into() - } - Recursive(tags) - | NullableWrapped { - other_tags: tags, .. - } => { - let data = block_of_memory_slices(env.context, tags, env.target_info); - - if union_layout.stores_tag_id_as_data(env.target_info) { - env.context - .struct_type(&[data, tag_id_type], false) - .ptr_type(AddressSpace::Generic) - .into() - } else { - data.ptr_type(AddressSpace::Generic).into() - } - } - NullableUnwrapped { other_fields, .. } => { - let block = - block_of_memory_slices(env.context, &[other_fields], env.target_info); - block.ptr_type(AddressSpace::Generic).into() - } - NonNullableUnwrapped(fields) => { - let block = block_of_memory_slices(env.context, &[fields], env.target_info); - block.ptr_type(AddressSpace::Generic).into() - } - } - } - RecursivePointer => { - // TODO make this dynamic - env.context - .i64_type() - .ptr_type(AddressSpace::Generic) - .as_basic_type_enum() - } + Union(union_layout) => basic_type_from_union_layout(env, union_layout), + RecursivePointer => env + .context + .i64_type() + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), Builtin(builtin) => basic_type_from_builtin(env, builtin), } } -pub fn basic_type_from_layout_1<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, - layout: &Layout<'_>, +pub fn basic_type_from_union_layout<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + union_layout: &UnionLayout<'_>, ) -> BasicTypeEnum<'ctx> { - use Layout::*; + use UnionLayout::*; - match layout { - Struct { - field_layouts: sorted_fields, - .. - } => basic_type_from_record(env, sorted_fields), - LambdaSet(lambda_set) => { - basic_type_from_layout_1(env, &lambda_set.runtime_representation()) + let tag_id_type = basic_type_from_layout(env, &union_layout.tag_id_layout()); + + match union_layout { + NonRecursive(tags) => { + let data = block_of_memory_slices(env.context, tags, env.target_info); + + env.context.struct_type(&[data, tag_id_type], false).into() } +<<<<<<< HEAD Boxed(inner_layout) => { let inner_type = basic_type_from_layout_1(env, inner_layout); @@ -142,22 +106,36 @@ pub fn basic_type_from_layout_1<'a, 'ctx, 'env>( let block = block_of_memory_slices(env.context, &[fields], env.target_info); block.ptr_type(AddressSpace::Generic).into() } +======= + Recursive(tags) + | NullableWrapped { + other_tags: tags, .. + } => { + let data = block_of_memory_slices(env.context, tags, env.target_info); + + if union_layout.stores_tag_id_as_data(env.target_info) { + env.context + .struct_type(&[data, tag_id_type], false) + .ptr_type(AddressSpace::Generic) + .into() + } else { + data.ptr_type(AddressSpace::Generic).into() +>>>>>>> origin/trunk } } - RecursivePointer => { - // TODO make this dynamic - env.context - .i64_type() - .ptr_type(AddressSpace::Generic) - .as_basic_type_enum() + NullableUnwrapped { other_fields, .. } => { + let block = block_of_memory_slices(env.context, &[other_fields], env.target_info); + block.ptr_type(AddressSpace::Generic).into() + } + NonNullableUnwrapped(fields) => { + let block = block_of_memory_slices(env.context, &[fields], env.target_info); + block.ptr_type(AddressSpace::Generic).into() } - - Builtin(builtin) => basic_type_from_builtin(env, builtin), } } pub fn basic_type_from_builtin<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, + env: &Env<'a, 'ctx, 'env>, builtin: &Builtin<'_>, ) -> BasicTypeEnum<'ctx> { use Builtin::*; @@ -176,8 +154,48 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>( } } +/// Turn a layout into a BasicType that we use in LLVM function arguments. +/// +/// This makes it possible to pass values as something different from how they are typically stored. +/// Current differences +/// +/// - tag unions are passed by-reference. That means that +/// * `f : [ Some I64, None ] -> I64` is typed `{ { i64, i8 }, i64 }* -> i64` +/// * `f : { x : [ Some I64, None ] } -> I64 is typed `{ { { i64, i8 }, i64 } } -> i64` +/// +/// Ideas exist to have (bigger than 2 register) records also be passed by-reference, but this +/// is not currently implemented +pub fn argument_type_from_layout<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + layout: &Layout<'_>, +) -> BasicTypeEnum<'ctx> { + use Layout::*; + + match layout { + LambdaSet(lambda_set) => { + argument_type_from_layout(env, &lambda_set.runtime_representation()) + } + Union(union_layout) => argument_type_from_union_layout(env, union_layout), + other => basic_type_from_layout(env, other), + } +} + +/// Non-recursive tag unions are stored on the stack, but passed by-reference +pub fn argument_type_from_union_layout<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + union_layout: &UnionLayout<'_>, +) -> BasicTypeEnum<'ctx> { + let heap_type = basic_type_from_union_layout(env, union_layout); + + if let UnionLayout::NonRecursive(_) = union_layout { + heap_type.ptr_type(AddressSpace::Generic).into() + } else { + heap_type + } +} + pub fn int_type_from_int_width<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, + env: &Env<'a, 'ctx, 'env>, int_width: IntWidth, ) -> IntType<'ctx> { use IntWidth::*; @@ -192,7 +210,7 @@ pub fn int_type_from_int_width<'a, 'ctx, 'env>( } pub fn float_type_from_float_width<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, + env: &Env<'a, 'ctx, 'env>, float_width: FloatWidth, ) -> FloatType<'ctx> { use FloatWidth::*; @@ -277,33 +295,23 @@ pub fn str_list_int(ctx: &Context, target_info: TargetInfo) -> IntType<'_> { } } -pub fn zig_dict_type<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, -) -> StructType<'ctx> { +pub fn zig_dict_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { env.module.get_struct_type("dict.RocDict").unwrap() } -pub fn zig_list_type<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, -) -> StructType<'ctx> { +pub fn zig_list_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { env.module.get_struct_type("list.RocList").unwrap() } -pub fn zig_str_type<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, -) -> StructType<'ctx> { +pub fn zig_str_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { env.module.get_struct_type("str.RocStr").unwrap() } -pub fn zig_has_tag_id_type<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, -) -> StructType<'ctx> { +pub fn zig_has_tag_id_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { env.module.get_struct_type("list.HasTagId").unwrap() } -pub fn zig_with_overflow_roc_dec<'a, 'ctx, 'env>( - env: &crate::llvm::build::Env<'a, 'ctx, 'env>, -) -> StructType<'ctx> { +pub fn zig_with_overflow_roc_dec<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { env.module .get_struct_type("utils.WithOverflow(dec.RocDec)") .unwrap() diff --git a/compiler/gen_llvm/src/llvm/refcounting.rs b/compiler/gen_llvm/src/llvm/refcounting.rs index b8343a41d1..ccfd5dda9a 100644 --- a/compiler/gen_llvm/src/llvm/refcounting.rs +++ b/compiler/gen_llvm/src/llvm/refcounting.rs @@ -5,7 +5,7 @@ use crate::llvm::build::{ FAST_CALL_CONV, TAG_DATA_INDEX, TAG_ID_INDEX, }; use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list}; -use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1}; +use crate::llvm::convert::basic_type_from_layout; use bumpalo::collections::Vec; use inkwell::basic_block::BasicBlock; use inkwell::context::Context; @@ -20,6 +20,8 @@ use roc_module::symbol::Symbol; use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout}; use roc_target::TargetInfo; +use super::convert::argument_type_from_union_layout; + /// "Infinite" reference count, for static values /// Ref counts are encoded as negative numbers where isize::MIN represents 1 pub const REFCOUNT_MAX: usize = 0_usize; @@ -1694,7 +1696,8 @@ fn modify_refcount_union<'a, 'ctx, 'env>( when_recursive: &WhenRecursive<'a>, fields: &'a [&'a [Layout<'a>]], ) -> FunctionValue<'ctx> { - let layout = Layout::Union(UnionLayout::NonRecursive(fields)); + let union_layout = UnionLayout::NonRecursive(fields); + let layout = Layout::Union(union_layout); let block = env.builder.get_insert_block().expect("to be in a function"); let di_location = env.builder.get_current_debug_location().unwrap(); @@ -1711,7 +1714,7 @@ fn modify_refcount_union<'a, 'ctx, 'env>( let function = match env.module.get_function(fn_name.as_str()) { Some(function_value) => function_value, None => { - let basic_type = basic_type_from_layout_1(env, &layout); + let basic_type = argument_type_from_union_layout(env, &union_layout); let function_value = build_header(env, basic_type, mode, &fn_name); modify_refcount_union_help( diff --git a/compiler/test_gen/src/gen_list.rs b/compiler/test_gen/src/gen_list.rs index 41635ea927..dd870a6192 100644 --- a/compiler/test_gen/src/gen_list.rs +++ b/compiler/test_gen/src/gen_list.rs @@ -798,6 +798,34 @@ fn list_walk_until_sum() { ); } +#[test] +#[cfg(any(feature = "gen-llvm"))] +fn list_walk_imlements_position() { + assert_evals_to!( + r#" + Option a : [ Some a, None ] + + find : List a, a -> Option Nat + find = \list, needle -> + findHelp list needle + |> .v + + findHelp = \list, needle -> + List.walkUntil list { n: 0, v: None } \{ n, v }, element -> + if element == needle then + Stop { n, v: Some n } + else + Continue { n: n + 1, v } + + when find [ 1, 2, 3 ] 3 is + None -> 0 + Some v -> v + "#, + 2, + i64 + ); +} + #[test] #[cfg(any(feature = "gen-llvm"))] fn list_walk_until_even_prefix_sum() { diff --git a/examples/benchmarks/AStar.roc b/examples/benchmarks/AStar.roc index f4bd5ed452..4f5a8e0fa1 100644 --- a/examples/benchmarks/AStar.roc +++ b/examples/benchmarks/AStar.roc @@ -25,14 +25,14 @@ cheapestOpen = \costFn, model -> model.openSet |> Set.toList |> List.keepOks - (\position -> - when Dict.get model.costs position is - Err _ -> - Err {} + (\position -> + when Dict.get model.costs position is + Err _ -> + Err {} - Ok cost -> - Ok { cost: cost + costFn position, position } - ) + Ok cost -> + Ok { cost: cost + costFn position, position } + ) |> Quicksort.sortBy .cost |> List.first |> Result.map .position diff --git a/examples/interactive/echo.roc b/examples/interactive/echo.roc index 4eefae59f5..84ca8c668d 100644 --- a/examples/interactive/echo.roc +++ b/examples/interactive/echo.roc @@ -23,11 +23,11 @@ echo = \shout -> shout |> Str.toUtf8 |> List.mapWithIndex - (\_, i -> - length = (List.len (Str.toUtf8 shout) - i) - phrase = (List.split (Str.toUtf8 shout) length).before + (\_, i -> + length = (List.len (Str.toUtf8 shout) - i) + phrase = (List.split (Str.toUtf8 shout) length).before - List.concat (silence (if i == 0 then 2 * length else length)) phrase) + List.concat (silence (if i == 0 then 2 * length else length)) phrase) |> List.join |> Str.fromUtf8 |> Result.withDefault ""