diff --git a/Cargo.lock b/Cargo.lock index e712bf547f..1e72c321e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -612,17 +612,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "confy" -version = "0.5.1" -source = "git+https://github.com/rust-cli/confy#d5abd6cce9b936130832cfb4e1ed8afd7e1c488b" -dependencies = [ - "directories", - "serde", - "serde_yaml", - "thiserror", -] - [[package]] name = "console" version = "0.15.5" @@ -1035,15 +1024,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "directories" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" -dependencies = [ - "dirs-sys", -] - [[package]] name = "dirs-next" version = "2.0.0" @@ -1054,17 +1034,6 @@ dependencies = [ "dirs-sys-next", ] -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -3395,7 +3364,6 @@ dependencies = [ "bytemuck", "cgmath", "colored", - "confy", "copypasta", "fs_extra", "futures", @@ -4286,18 +4254,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_yaml" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" -dependencies = [ - "indexmap", - "ryu", - "serde", - "yaml-rust", -] - [[package]] name = "serial_test" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 9dbe115f5d..c48925055b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,7 +84,6 @@ capstone = { version = "0.11.0", default-features = false } cgmath = "0.18.0" clap = { version = "4.2.7", default-features = false, features = ["std", "color", "suggestions", "help", "usage", "error-context"] } colored = "2.0.0" -confy = { git = 'https://github.com/rust-cli/confy', features = ["yaml_conf"], default-features = false } console_error_panic_hook = "0.1.7" const_format = { version = "0.2.30", features = ["const_generics"] } copypasta = "0.8.2" diff --git a/crates/compiler/builtins/bitcode/src/dec.zig b/crates/compiler/builtins/bitcode/src/dec.zig index 8170c135ab..e439db7a98 100644 --- a/crates/compiler/builtins/bitcode/src/dec.zig +++ b/crates/compiler/builtins/bitcode/src/dec.zig @@ -44,6 +44,8 @@ pub const RocDec = extern struct { return ret; } + // TODO: If Str.toDec eventually supports more error types, return errors here. + // For now, just return null which will give the default error. pub fn fromStr(roc_str: RocStr) ?RocDec { if (roc_str.isEmpty()) { return null; @@ -79,7 +81,8 @@ pub const RocDec = extern struct { var after_str_len = (length - 1) - pi; if (after_str_len > decimal_places) { - @panic("TODO runtime exception for too many decimal places!"); + // TODO: runtime exception for too many decimal places! + return null; } var diff_decimal_places = decimal_places - after_str_len; @@ -96,7 +99,8 @@ pub const RocDec = extern struct { var result: i128 = undefined; var overflowed = @mulWithOverflow(i128, before, one_point_zero_i128, &result); if (overflowed) { - @panic("TODO runtime exception for overflow!"); + // TODO: runtime exception for overflow! + return null; } before_val_i128 = result; } @@ -107,7 +111,8 @@ pub const RocDec = extern struct { var result: i128 = undefined; var overflowed = @addWithOverflow(i128, before, after, &result); if (overflowed) { - @panic("TODO runtime exception for overflow!"); + // TODO: runtime exception for overflow! + return null; } break :blk .{ .num = result }; } else { @@ -184,7 +189,7 @@ pub const RocDec = extern struct { position += 1; const trailing_zeros: u6 = count_trailing_zeros_base10(num); - if (trailing_zeros == decimal_places) { + if (trailing_zeros >= decimal_places) { // add just a single zero if all decimal digits are zero str_bytes[position] = '0'; position += 1; @@ -851,6 +856,14 @@ test "fromStr: .123.1" { try expectEqual(dec, null); } +test "toStr: 100.00" { + var dec: RocDec = .{ .num = 100000000000000000000 }; + var res_roc_str = dec.toStr(); + + const res_slice: []const u8 = "100.0"[0..]; + try expectEqualSlices(u8, res_slice, res_roc_str.asSlice()); +} + test "toStr: 123.45" { var dec: RocDec = .{ .num = 123450000000000000000 }; var res_roc_str = dec.toStr(); diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index 485ef24364..097b094210 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -95,7 +95,7 @@ Dict k v := { # TODO: define Eq and Hash that are unordered. Only if value has hash/eq? metadata : List I8, dataIndices : List Nat, - data : List (T k v), + data : List (k, v), size : Nat, } | k has Hash & Eq has [ @@ -175,12 +175,12 @@ single = \k, v -> ## |> Dict.insert 2 "Two" ## |> Dict.insert 3 "Three" ## |> Dict.insert 4 "Four" -## |> Bool.isEq (Dict.fromList [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"]) +## |> Bool.isEq (Dict.fromList [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]) ## ``` -fromList : List (T k v) -> Dict k v | k has Hash & Eq +fromList : List (k, v) -> Dict k v | k has Hash & Eq fromList = \data -> # TODO: make this efficient. Should just set data and then set all indicies in the hashmap. - List.walk data (empty {}) (\dict, T k v -> insert dict k v) + List.walk data (empty {}) (\dict, (k, v) -> insert dict k v) ## Returns the number of values in the dictionary. ## ``` @@ -238,7 +238,7 @@ clear = \@Dict { metadata, dataIndices, data } -> ## ``` walk : Dict k v, state, (state, k, v -> state) -> state | k has Hash & Eq walk = \@Dict { data }, initialState, transform -> - List.walk data initialState (\state, T k v -> transform state k v) + List.walk data initialState (\state, (k, v) -> transform state k v) ## Same as [Dict.walk], except you can stop walking early. ## @@ -270,7 +270,7 @@ walk = \@Dict { data }, initialState, transform -> ## ``` walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state | k has Hash & Eq walkUntil = \@Dict { data }, initialState, transform -> - List.walkUntil data initialState (\state, T k v -> transform state k v) + List.walkUntil data initialState (\state, (k, v) -> transform state k v) ## Get the value for a given key. If there is a value for the specified key it ## will return [Ok value], otherwise return [Err KeyNotFound]. @@ -296,7 +296,7 @@ get = \@Dict { metadata, dataIndices, data }, key -> when findIndexHelper metadata dataIndices data h2Key key probe 0 is Ok index -> dataIndex = listGetUnsafe dataIndices index - (T _ v) = listGetUnsafe data dataIndex + (_, v) = listGetUnsafe data dataIndex Ok v @@ -353,7 +353,7 @@ insert = \@Dict { metadata, dataIndices, data, size }, key, value -> @Dict { metadata, dataIndices, - data: List.set data dataIndex (T key value), + data: List.set data dataIndex (key, value), size, } @@ -447,9 +447,9 @@ update = \dict, key, alter -> ## |> Dict.insert 3 "Three" ## |> Dict.insert 4 "Four" ## |> Dict.toList -## |> Bool.isEq [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"] +## |> Bool.isEq [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")] ## ``` -toList : Dict k v -> List (T k v) | k has Hash & Eq +toList : Dict k v -> List (k, v) | k has Hash & Eq toList = \@Dict { data } -> data @@ -466,7 +466,7 @@ toList = \@Dict { data } -> ## ``` keys : Dict k v -> List k | k has Hash & Eq keys = \@Dict { data } -> - List.map data (\T k _ -> k) + List.map data (\(k, _) -> k) ## Returns the values of a dictionary as a [List]. ## This requires allocating a temporary [List], prefer using [Dict.toList] or [Dict.walk] instead. @@ -481,7 +481,7 @@ keys = \@Dict { data } -> ## ``` values : Dict k v -> List v | k has Hash & Eq values = \@Dict { data } -> - List.map data (\T _ v -> v) + List.map data (\(_, v) -> v) ## Combine two dictionaries by keeping the [union](https://en.wikipedia.org/wiki/Union_(set_theory)) ## of all the key-value pairs. This means that all the key-value pairs in @@ -567,7 +567,7 @@ removeAll = \xs, ys -> swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v | k has Hash & Eq swapAndUpdateDataIndex = \@Dict { metadata, dataIndices, data, size }, removedIndex, lastIndex -> - (T key _) = listGetUnsafe data lastIndex + (key, _) = listGetUnsafe data lastIndex hashKey = createLowLevelHasher PseudoRandSeed |> Hash.hash key @@ -603,7 +603,7 @@ insertNotFoundHelper = \@Dict { metadata, dataIndices, data, size }, key, value, probe = newProbe h1Key (div8 (List.len metadata)) index = nextEmptyOrDeletedHelper metadata probe 0 dataIndex = List.len data - nextData = List.append data (T key value) + nextData = List.append data (key, value) @Dict { metadata: List.set metadata index h2Key, @@ -629,7 +629,7 @@ nextEmptyOrDeletedHelper = \metadata, probe, offset -> # TODO: investigate if this needs to be split into more specific helper functions. # There is a chance that returning specific sub-info like the value would be faster. -findIndexHelper : List I8, List Nat, List (T k v), I8, k, Probe, Nat -> Result Nat [NotFound] | k has Hash & Eq +findIndexHelper : List I8, List Nat, List (k, v), I8, k, Probe, Nat -> Result Nat [NotFound] | k has Hash & Eq findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset -> # For finding a value, we must search past all deleted element tombstones. index = Num.addWrap (mul8 probe.slotIndex) offset @@ -642,7 +642,7 @@ findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset -> else if md == h2Key then # Potentially matching slot, check if the key is a match. dataIndex = listGetUnsafe dataIndices index - (T k _) = listGetUnsafe data dataIndex + (k, _) = listGetUnsafe data dataIndex if k == key then # We have a match, return its index. @@ -687,7 +687,7 @@ rehash = \@Dict { metadata, dataIndices, data, size } -> rehashHelper newDict metadata dataIndices data 0 -rehashHelper : Dict k v, List I8, List Nat, List (T k v), Nat -> Dict k v | k has Hash & Eq +rehashHelper : Dict k v, List I8, List Nat, List (k, v), Nat -> Dict k v | k has Hash & Eq rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index -> when List.get oldMetadata index is Ok md -> @@ -695,7 +695,7 @@ rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index -> if md >= 0 then # We have an actual element here dataIndex = listGetUnsafe oldDataIndices index - (T k _) = listGetUnsafe oldData dataIndex + (k, _) = listGetUnsafe oldData dataIndex insertForRehash dict k dataIndex else @@ -731,8 +731,6 @@ emptySlot = -128 deletedSlot : I8 deletedSlot = -2 -T k v : [T k v] - # Capacity must be a power of 2. # We still will use slots of 8 even though this version has no true slots. # We just move an element at a time. @@ -869,7 +867,7 @@ expect expect dict = - fromList [T 1u8 1u8, T 2 2, T 3 3] + fromList [(1u8, 1u8), (2, 2), (3, 3)] |> remove 1 |> remove 3 @@ -877,7 +875,7 @@ expect expect list = - fromList [T 1u8 1u8, T 2u8 2u8, T 3 3] + fromList [(1u8, 1u8), (2u8, 2u8), (3, 3)] |> remove 1 |> insert 0 0 |> remove 3 diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 6bd3289525..2424efb9a4 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -3115,7 +3115,6 @@ fn update<'a>( &mut layout_interner, module_id, ident_ids, - state.target_info, &mut state.procedures, ); diff --git a/crates/compiler/mono/src/drop_specialization.rs b/crates/compiler/mono/src/drop_specialization.rs index 5330499262..dda4959678 100644 --- a/crates/compiler/mono/src/drop_specialization.rs +++ b/crates/compiler/mono/src/drop_specialization.rs @@ -15,11 +15,10 @@ use bumpalo::collections::CollectIn; use roc_module::low_level::LowLevel; use roc_module::symbol::{IdentIds, ModuleId, Symbol}; -use roc_target::TargetInfo; use crate::ir::{ - BranchInfo, Call, CallType, Expr, JoinPointId, Literal, ModifyRc, Proc, ProcLayout, Stmt, - UpdateModeId, + BranchInfo, Call, CallType, Expr, JoinPointId, ListLiteralElement, Literal, ModifyRc, Proc, + ProcLayout, Stmt, UpdateModeId, }; use crate::layout::{ Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout, @@ -27,7 +26,7 @@ use crate::layout::{ use bumpalo::Bump; -use roc_collections::{MutMap, MutSet}; +use roc_collections::MutMap; /** Try to find increments of symbols followed by decrements of the symbol they were indexed out of (their parent). @@ -38,12 +37,10 @@ pub fn specialize_drops<'a, 'i>( layout_interner: &'i mut STLayoutInterner<'a>, home: ModuleId, ident_ids: &'i mut IdentIds, - target_info: TargetInfo, procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>, ) { for ((_symbol, proc_layout), proc) in procs.iter_mut() { - let mut environment = - DropSpecializationEnvironment::new(arena, home, proc_layout.result, target_info); + let mut environment = DropSpecializationEnvironment::new(arena, home, proc_layout.result); specialize_drops_proc(arena, layout_interner, ident_ids, &mut environment, proc); } } @@ -104,7 +101,7 @@ fn specialize_drops_stmt<'a, 'i>( _ => unreachable!("List get should have two arguments"), }; - environment.add_list_child(*structure, *binding, index); + environment.add_list_child_symbol(*structure, *binding, index); alloc_let_with_continuation!(environment) } @@ -114,9 +111,18 @@ fn specialize_drops_stmt<'a, 'i>( RC::NoRc => alloc_let_with_continuation!(environment), // We probably should not pass the increments to the continuation. RC::Rc | RC::Uknown => { - let mut new_environment = environment.clone_without_incremented(); + let incremented_symbols = environment.incremented_symbols.drain(); - alloc_let_with_continuation!(&mut new_environment) + let new_stmt = alloc_let_with_continuation!(environment); + + // The new_environment might have inserted increments that were set to 0 before. We need to add th + for (symbol, increment) in incremented_symbols.map.into_iter() { + environment + .incremented_symbols + .insert_count(symbol, increment); + } + + new_stmt } }, _ => { @@ -127,16 +133,62 @@ fn specialize_drops_stmt<'a, 'i>( // the parent might be deallocated before the function can use it. // Thus forget everything about any increments. - let mut new_environment = environment.clone_without_incremented(); + let incremented_symbols = environment.incremented_symbols.drain(); - alloc_let_with_continuation!(&mut new_environment) + let new_stmt = alloc_let_with_continuation!(environment); + + // The new_environment might have inserted increments that were set to 0 before. We need to add th + for (symbol, increment) in incremented_symbols.map.into_iter() { + environment + .incremented_symbols + .insert_count(symbol, increment); + } + + new_stmt } } } - Expr::Tag { tag_id, .. } => { + Expr::Tag { + tag_id, + arguments: children, + .. + } => { environment.symbol_tag.insert(*binding, *tag_id); + for (index, child) in children.iter().enumerate() { + environment.add_union_child(*binding, *child, *tag_id, index as u64); + } + + alloc_let_with_continuation!(environment) + } + Expr::Struct(children) => { + for (index, child) in children.iter().enumerate() { + environment.add_struct_child(*binding, *child, index as u64); + } + + alloc_let_with_continuation!(environment) + } + Expr::ExprBox { symbol: child } => { + environment.add_box_child(*binding, *child); + + alloc_let_with_continuation!(environment) + } + Expr::Array { + elems: children, .. + } => { + for (index, child) in + children + .iter() + .enumerate() + .filter_map(|(index, child)| match child { + ListLiteralElement::Literal(_) => None, + ListLiteralElement::Symbol(s) => Some((index, s)), + }) + { + environment.add_list_child(*binding, *child, index as u64); + } + alloc_let_with_continuation!(environment) } Expr::StructAtIndex { @@ -188,13 +240,10 @@ fn specialize_drops_stmt<'a, 'i>( } alloc_let_with_continuation!(environment) } - Expr::Struct(_) - | Expr::RuntimeErrorFunction(_) - | Expr::ExprBox { .. } + Expr::RuntimeErrorFunction(_) | Expr::NullPointer | Expr::GetTagId { .. } - | Expr::EmptyArray - | Expr::Array { .. } => { + | Expr::EmptyArray => { // Does nothing relevant to drop specialization. So we can just continue. alloc_let_with_continuation!(environment) } @@ -283,10 +332,12 @@ fn specialize_drops_stmt<'a, 'i>( }; // Find the lowest symbol count for each symbol in each branch, and update the environment to match. - for (symbol, count) in environment.incremented_symbols.iter_mut() { + for (symbol, count) in environment.incremented_symbols.map.iter_mut() { let consumed = branch_envs .iter() - .map(|branch_env| branch_env.incremented_symbols.get(symbol).unwrap_or(&0)) + .map(|branch_env| { + branch_env.incremented_symbols.map.get(symbol).unwrap_or(&0) + }) .min() .unwrap(); @@ -300,10 +351,14 @@ fn specialize_drops_stmt<'a, 'i>( let symbol_differences = environment .incremented_symbols + .map .iter() .filter_map(|(symbol, count)| { - let branch_count = - $branch_env.incremented_symbols.get(symbol).unwrap_or(&0); + let branch_count = $branch_env + .incremented_symbols + .map + .get(symbol) + .unwrap_or(&0); match branch_count - count { 0 => None, @@ -338,11 +393,6 @@ fn specialize_drops_stmt<'a, 'i>( (info.clone(), new_branch) }; - // Remove all 0 counts as cleanup. - environment - .incremented_symbols - .retain(|_, count| *count > 0); - arena.alloc(Stmt::Switch { cond_symbol: *cond_symbol, cond_layout: *cond_layout, @@ -354,10 +404,12 @@ fn specialize_drops_stmt<'a, 'i>( Stmt::Ret(symbol) => arena.alloc(Stmt::Ret(*symbol)), Stmt::Refcounting(rc, continuation) => match rc { ModifyRc::Inc(symbol, count) => { - let any = environment.any_incremented(symbol); + let inc_before = environment.incremented_symbols.contains(symbol); // Add a symbol for every increment performed. - environment.add_incremented(*symbol, *count); + environment + .incremented_symbols + .insert_count(*symbol, *count); let new_continuation = specialize_drops_stmt( arena, @@ -367,12 +419,17 @@ fn specialize_drops_stmt<'a, 'i>( continuation, ); - if any { + if inc_before { // There were increments before this one, best to let the first one do the increments. // Or there are no increments left, so we can just continue. new_continuation } else { - match environment.get_incremented(symbol) { + match environment + .incremented_symbols + .map + .remove(symbol) + .unwrap_or(0) + { // This is the first increment, but all increments are consumed. So don't insert any. 0 => new_continuation, // We still need to do some increments. @@ -393,7 +450,7 @@ fn specialize_drops_stmt<'a, 'i>( // dec a // dec b - if environment.pop_incremented(symbol) { + if environment.incremented_symbols.pop(symbol) { // This decremented symbol was incremented before, so we can remove it. specialize_drops_stmt( arena, @@ -411,10 +468,10 @@ fn specialize_drops_stmt<'a, 'i>( // As a might get dropped as a result of the decrement of b. let mut incremented_children = { let mut todo_children = bumpalo::vec![in arena; *symbol]; - let mut incremented_children = MutSet::default(); + let mut incremented_children = CountingMap::new(); while let Some(child) = todo_children.pop() { - if environment.pop_incremented(&child) { + if environment.incremented_symbols.pop(&child) { incremented_children.insert(child); } else { todo_children.extend(environment.get_children(&child)); @@ -485,8 +542,10 @@ fn specialize_drops_stmt<'a, 'i>( }; // Add back the increments for the children to the environment. - for child_symbol in incremented_children.iter() { - environment.add_incremented(*child_symbol, 1) + for (child_symbol, symbol_count) in incremented_children.map.into_iter() { + environment + .incremented_symbols + .insert_count(child_symbol, symbol_count) } updated_stmt @@ -565,7 +624,8 @@ fn specialize_drops_stmt<'a, 'i>( body, remainder, } => { - let mut new_environment = environment.clone_without_incremented(); + let mut new_environment = environment.clone(); + new_environment.incremented_symbols.clear(); for param in parameters.iter() { new_environment.add_symbol_layout(param.symbol, param.layout); @@ -604,7 +664,7 @@ fn specialize_struct<'a, 'i>( environment: &mut DropSpecializationEnvironment<'a>, symbol: &Symbol, struct_layout: &'a [InLayout], - incremented_children: &mut MutSet, + incremented_children: &mut CountingMap, continuation: &'a Stmt<'a>, ) -> &'a Stmt<'a> { match environment.struct_children.get(symbol) { @@ -620,7 +680,7 @@ fn specialize_struct<'a, 'i>( for (index, _layout) in struct_layout.iter().enumerate() { for (child, _i) in children_clone.iter().filter(|(_, i)| *i == index as u64) { - let removed = incremented_children.remove(child); + let removed = incremented_children.pop(child); index_symbols.insert(index, (*child, removed)); if removed { @@ -693,7 +753,7 @@ fn specialize_union<'a, 'i>( environment: &mut DropSpecializationEnvironment<'a>, symbol: &Symbol, union_layout: UnionLayout<'a>, - incremented_children: &mut MutSet, + incremented_children: &mut CountingMap, continuation: &'a Stmt<'a>, ) -> &'a Stmt<'a> { let current_tag = environment.symbol_tag.get(symbol).copied(); @@ -736,7 +796,7 @@ fn specialize_union<'a, 'i>( { debug_assert_eq!(tag, *t); - let removed = incremented_children.remove(child); + let removed = incremented_children.pop(child); index_symbols.insert(index, (*child, removed)); if removed { @@ -898,14 +958,14 @@ fn specialize_boxed<'a, 'i>( layout_interner: &'i mut STLayoutInterner<'a>, ident_ids: &'i mut IdentIds, environment: &mut DropSpecializationEnvironment<'a>, - incremented_children: &mut MutSet, + incremented_children: &mut CountingMap, symbol: &Symbol, continuation: &'a Stmt<'a>, ) -> &'a Stmt<'a> { - let removed = match incremented_children.iter().next() { - Some(s) => { + let removed = match incremented_children.map.iter().next() { + Some((s, _)) => { let s = *s; - incremented_children.remove(&s); + incremented_children.pop(&s); Some(s) } None => None, @@ -924,23 +984,20 @@ fn specialize_boxed<'a, 'i>( *symbol, // If the symbol is unique: // - free the box - |_, _, _| { + |_, _, continuation| { arena.alloc(Stmt::Refcounting( // TODO can be replaced by free if ever added to the IR. ModifyRc::DecRef(*symbol), - new_continuation, + continuation, )) }, // If the symbol is not unique: // - increment the child // - decref the box - |_, _, _| { + |_, _, continuation| { arena.alloc(Stmt::Refcounting( ModifyRc::Inc(s, 1), - arena.alloc(Stmt::Refcounting( - ModifyRc::DecRef(*symbol), - new_continuation, - )), + arena.alloc(Stmt::Refcounting(ModifyRc::DecRef(*symbol), continuation)), )) }, new_continuation, @@ -958,7 +1015,7 @@ fn specialize_list<'a, 'i>( layout_interner: &'i mut STLayoutInterner<'a>, ident_ids: &'i mut IdentIds, environment: &mut DropSpecializationEnvironment<'a>, - incremented_children: &mut MutSet, + incremented_children: &mut CountingMap, symbol: &Symbol, item_layout: InLayout, continuation: &'a Stmt<'a>, @@ -993,7 +1050,7 @@ fn specialize_list<'a, 'i>( for (child, i) in children_clone.iter().filter(|(_child, i)| *i == index) { debug_assert!(length > *i); - let removed = incremented_children.remove(child); + let removed = incremented_children.pop(child); index_symbols.insert(index, (*child, removed)); if removed { @@ -1214,7 +1271,6 @@ struct DropSpecializationEnvironment<'a> { arena: &'a Bump, home: ModuleId, layout: InLayout<'a>, - target_info: TargetInfo, symbol_layouts: MutMap>, @@ -1231,7 +1287,7 @@ struct DropSpecializationEnvironment<'a> { list_children: MutMap>, // Keeps track of all incremented symbols. - incremented_symbols: MutMap, + incremented_symbols: CountingMap, // Map containing the current known tag of a layout. symbol_tag: MutMap, @@ -1244,42 +1300,23 @@ struct DropSpecializationEnvironment<'a> { } impl<'a> DropSpecializationEnvironment<'a> { - fn new(arena: &'a Bump, home: ModuleId, layout: InLayout<'a>, target_info: TargetInfo) -> Self { + fn new(arena: &'a Bump, home: ModuleId, layout: InLayout<'a>) -> Self { Self { arena, home, layout, - target_info, symbol_layouts: MutMap::default(), struct_children: MutMap::default(), union_children: MutMap::default(), box_children: MutMap::default(), list_children: MutMap::default(), - incremented_symbols: MutMap::default(), + incremented_symbols: CountingMap::new(), symbol_tag: MutMap::default(), symbol_index: MutMap::default(), list_length: MutMap::default(), } } - fn clone_without_incremented(&self) -> Self { - Self { - arena: self.arena, - home: self.home, - layout: self.layout, - target_info: self.target_info, - symbol_layouts: self.symbol_layouts.clone(), - struct_children: self.struct_children.clone(), - union_children: self.union_children.clone(), - box_children: self.box_children.clone(), - list_children: self.list_children.clone(), - incremented_symbols: MutMap::default(), - symbol_tag: self.symbol_tag.clone(), - symbol_index: self.symbol_index.clone(), - list_length: self.list_length.clone(), - } - } - fn create_symbol<'i>(&self, ident_ids: &'i mut IdentIds, debug_name: &str) -> Symbol { let ident_id = ident_ids.add_str(debug_name); Symbol::new(self.home, ident_id) @@ -1316,12 +1353,16 @@ impl<'a> DropSpecializationEnvironment<'a> { .push(child); } - fn add_list_child(&mut self, parent: Parent, child: Child, index: &Symbol) { + fn add_list_child(&mut self, parent: Parent, child: Child, index: u64) { + self.list_children + .entry(parent) + .or_insert_with(|| Vec::new_in(self.arena)) + .push((child, index)); + } + + fn add_list_child_symbol(&mut self, parent: Parent, child: Child, index: &Symbol) { if let Some(index) = self.symbol_index.get(index) { - self.list_children - .entry(parent) - .or_insert_with(|| Vec::new_in(self.arena)) - .push((child, *index)); + self.add_list_child(parent, child, *index) } } @@ -1346,39 +1387,6 @@ impl<'a> DropSpecializationEnvironment<'a> { res } - - /** - Add a symbol for every increment performed. - */ - fn add_incremented(&mut self, symbol: Symbol, count: u64) { - self.incremented_symbols - .entry(symbol) - .and_modify(|c| *c += count) - .or_insert(count); - } - - fn any_incremented(&self, symbol: &Symbol) -> bool { - self.incremented_symbols.contains_key(symbol) - } - - /** - Return the amount of times a symbol still has to be incremented. - Accounting for later consumtion and removal of the increment. - */ - fn get_incremented(&mut self, symbol: &Symbol) -> u64 { - self.incremented_symbols.remove(symbol).unwrap_or(0) - } - - fn pop_incremented(&mut self, symbol: &Symbol) -> bool { - match self.incremented_symbols.get_mut(symbol) { - Some(0) => false, - Some(c) => { - *c -= 1; - true - } - None => false, - } - } } /** @@ -1490,3 +1498,59 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC { } } } + +/// Map that contains a count for each key. +/// Keys with a count of 0 are kept around, so that it can be seen that they were once present. +#[derive(Clone)] +struct CountingMap { + map: MutMap, +} + +impl CountingMap +where + K: Eq + std::hash::Hash + Clone, +{ + fn new() -> Self { + Self { + map: MutMap::default(), + } + } + + fn insert(&mut self, key: K) { + self.insert_count(key, 1); + } + + fn insert_count(&mut self, key: K, count: u64) { + self.map + .entry(key) + .and_modify(|c| *c += count) + .or_insert(count); + } + + fn pop(&mut self, key: &K) -> bool { + match self.map.get_mut(key) { + Some(0) => false, + Some(c) => { + *c -= 1; + true + } + None => false, + } + } + + fn contains(&self, symbol: &K) -> bool { + self.map.contains_key(symbol) + } + + fn drain(&mut self) -> Self { + let res = self.clone(); + for (_, v) in self.map.iter_mut() { + *v = 0; + } + res + } + + fn clear(&mut self) { + self.map.clear(); + } +} diff --git a/crates/compiler/test_mono/generated/dict.txt b/crates/compiler/test_mono/generated/dict.txt index a549ce50c7..ea2ba420a3 100644 --- a/crates/compiler/test_mono/generated/dict.txt +++ b/crates/compiler/test_mono/generated/dict.txt @@ -1,28 +1,28 @@ -procedure Dict.1 (Dict.547): - let Dict.556 : List {[], []} = Array []; - let Dict.563 : U64 = 0i64; - let Dict.564 : U64 = 8i64; - let Dict.557 : List U64 = CallByName List.11 Dict.563 Dict.564; - let Dict.560 : I8 = CallByName Dict.37; - let Dict.561 : U64 = 8i64; - let Dict.558 : List I8 = CallByName List.11 Dict.560 Dict.561; - let Dict.559 : U64 = 0i64; - let Dict.555 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.556, Dict.557, Dict.558, Dict.559}; - ret Dict.555; +procedure Dict.1 (Dict.537): + let Dict.546 : List {[], []} = Array []; + let Dict.553 : U64 = 0i64; + let Dict.554 : U64 = 8i64; + let Dict.547 : List U64 = CallByName List.11 Dict.553 Dict.554; + let Dict.550 : I8 = CallByName Dict.36; + let Dict.551 : U64 = 8i64; + let Dict.548 : List I8 = CallByName List.11 Dict.550 Dict.551; + let Dict.549 : U64 = 0i64; + let Dict.545 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.546, Dict.547, Dict.548, Dict.549}; + ret Dict.545; -procedure Dict.37 (): - let Dict.562 : I8 = -128i64; - ret Dict.562; +procedure Dict.36 (): + let Dict.552 : I8 = -128i64; + ret Dict.552; -procedure Dict.4 (Dict.553): - let Dict.99 : U64 = StructAtIndex 3 Dict.553; - let #Derived_gen.2 : List {[], []} = StructAtIndex 0 Dict.553; +procedure Dict.4 (Dict.543): + let Dict.97 : U64 = StructAtIndex 3 Dict.543; + let #Derived_gen.2 : List {[], []} = StructAtIndex 0 Dict.543; dec #Derived_gen.2; - let #Derived_gen.1 : List U64 = StructAtIndex 1 Dict.553; + let #Derived_gen.1 : List U64 = StructAtIndex 1 Dict.543; dec #Derived_gen.1; - let #Derived_gen.0 : List I8 = StructAtIndex 2 Dict.553; + let #Derived_gen.0 : List I8 = StructAtIndex 2 Dict.543; dec #Derived_gen.0; - ret Dict.99; + ret Dict.97; procedure List.11 (List.115, List.116): let List.495 : List I8 = CallByName List.68 List.116; diff --git a/crates/compiler/test_mono/generated/drop_specialize_after_struct.txt b/crates/compiler/test_mono/generated/drop_specialize_after_struct.txt new file mode 100644 index 0000000000..e0b69a232d --- /dev/null +++ b/crates/compiler/test_mono/generated/drop_specialize_after_struct.txt @@ -0,0 +1,6 @@ +procedure Test.0 (): + let Test.2 : Str = "value"; + let Test.3 : {Str, Str} = Struct {Test.2, Test.2}; + dec Test.2; + let Test.4 : Str = "result"; + ret Test.4; diff --git a/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt b/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt index 43ef33a492..ccef4a274f 100644 --- a/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt @@ -697,8 +697,8 @@ procedure Json.25 (Json.183): let Json.1906 : List U8 = CallByName List.8 Json.1907 Json.1908; ret Json.1906; else - let Json.1948 : U64 = StructAtIndex 0 Json.186; inc Json.184; + let Json.1948 : U64 = StructAtIndex 0 Json.186; let Json.1947 : {List U8, List U8} = CallByName List.52 Json.184 Json.1948; let Json.210 : List U8 = StructAtIndex 0 Json.1947; let Json.212 : List U8 = StructAtIndex 1 Json.1947; diff --git a/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt b/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt index 09eb6c8aea..eb0e2fa779 100644 --- a/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt @@ -623,8 +623,8 @@ procedure Json.25 (Json.183): let Json.1532 : List U8 = CallByName List.8 Json.1533 Json.1534; ret Json.1532; else - let Json.1574 : U64 = StructAtIndex 0 Json.186; inc Json.184; + let Json.1574 : U64 = StructAtIndex 0 Json.186; let Json.1573 : {List U8, List U8} = CallByName List.52 Json.184 Json.1574; let Json.210 : List U8 = StructAtIndex 0 Json.1573; let Json.212 : List U8 = StructAtIndex 1 Json.1573; diff --git a/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt b/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt index 28038830e7..b8615bf0eb 100644 --- a/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt +++ b/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt @@ -630,8 +630,8 @@ procedure Json.25 (Json.183): let Json.1532 : List U8 = CallByName List.8 Json.1533 Json.1534; ret Json.1532; else - let Json.1574 : U64 = StructAtIndex 0 Json.186; inc Json.184; + let Json.1574 : U64 = StructAtIndex 0 Json.186; let Json.1573 : {List U8, List U8} = CallByName List.52 Json.184 Json.1574; let Json.210 : List U8 = StructAtIndex 0 Json.1573; let Json.212 : List U8 = StructAtIndex 1 Json.1573; diff --git a/crates/compiler/test_mono/generated/encode_derived_string.txt b/crates/compiler/test_mono/generated/encode_derived_string.txt index 969f6eedd7..08dc7f69bb 100644 --- a/crates/compiler/test_mono/generated/encode_derived_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_string.txt @@ -118,8 +118,8 @@ procedure Json.25 (Json.183): let Json.1179 : List U8 = CallByName List.8 Json.1180 Json.1181; ret Json.1179; else - let Json.1221 : U64 = StructAtIndex 0 Json.186; inc Json.184; + let Json.1221 : U64 = StructAtIndex 0 Json.186; let Json.1220 : {List U8, List U8} = CallByName List.52 Json.184 Json.1221; let Json.210 : List U8 = StructAtIndex 0 Json.1220; let Json.212 : List U8 = StructAtIndex 1 Json.1220; diff --git a/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt b/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt index 63b59f013f..fcad92aee9 100644 --- a/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt @@ -147,8 +147,8 @@ procedure Json.25 (Json.183): let Json.1220 : List U8 = CallByName List.8 Json.1221 Json.1222; ret Json.1220; else - let Json.1262 : U64 = StructAtIndex 0 Json.186; inc Json.184; + let Json.1262 : U64 = StructAtIndex 0 Json.186; let Json.1261 : {List U8, List U8} = CallByName List.52 Json.184 Json.1262; let Json.210 : List U8 = StructAtIndex 0 Json.1261; let Json.212 : List U8 = StructAtIndex 1 Json.1261; diff --git a/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt b/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt index c6817419be..fe755e729e 100644 --- a/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt @@ -150,8 +150,8 @@ procedure Json.25 (Json.183): let Json.1220 : List U8 = CallByName List.8 Json.1221 Json.1222; ret Json.1220; else - let Json.1262 : U64 = StructAtIndex 0 Json.186; inc Json.184; + let Json.1262 : U64 = StructAtIndex 0 Json.186; let Json.1261 : {List U8, List U8} = CallByName List.52 Json.184 Json.1262; let Json.210 : List U8 = StructAtIndex 0 Json.1261; let Json.212 : List U8 = StructAtIndex 1 Json.1261; diff --git a/crates/compiler/test_mono/generated/issue_4749.txt b/crates/compiler/test_mono/generated/issue_4749.txt index 0c79e8f4d8..9a5d0685da 100644 --- a/crates/compiler/test_mono/generated/issue_4749.txt +++ b/crates/compiler/test_mono/generated/issue_4749.txt @@ -179,8 +179,8 @@ procedure Json.60 (Json.540): let Json.1336 : U8 = GetTagId Json.1327; let Json.1337 : Int1 = lowlevel Eq Json.1335 Json.1336; if Json.1337 then - let Json.542 : U64 = UnionAtIndex (Id 2) (Index 0) Json.1327; inc Json.540; + let Json.542 : U64 = UnionAtIndex (Id 2) (Index 0) Json.1327; let Json.1329 : List U8 = CallByName List.29 Json.540 Json.542; let Json.1332 : U64 = 0i64; let Json.1331 : {U64, U64} = Struct {Json.542, Json.1332}; @@ -532,18 +532,15 @@ procedure Json.68 (): procedure Json.69 (Json.1467): joinpoint Json.1197 Json.1165: let Json.599 : List U8 = StructAtIndex 0 Json.1165; - inc Json.599; + inc 4 Json.599; let Json.600 : List U8 = StructAtIndex 1 Json.1165; let Json.1315 : U64 = 0i64; let Json.601 : [C {}, C U8] = CallByName List.2 Json.599 Json.1315; let Json.1314 : U64 = 1i64; - inc Json.599; let Json.602 : [C {}, C U8] = CallByName List.2 Json.599 Json.1314; let Json.1313 : U64 = 2i64; - inc Json.599; let Json.603 : List U8 = CallByName List.29 Json.599 Json.1313; let Json.1312 : U64 = 6i64; - inc Json.599; let Json.604 : List U8 = CallByName List.29 Json.599 Json.1312; let Json.1198 : {[C {}, C U8], [C {}, C U8]} = Struct {Json.601, Json.602}; joinpoint Json.1277: @@ -832,7 +829,7 @@ procedure Test.3 (): let Test.7 : Str = "Roc"; let Test.6 : [C [C List U8, C ], C Str] = TagId(1) Test.7; let Test.5 : Int1 = CallByName Bool.11 Test.1 Test.6; - dec Test.6; + dec Test.7; expect Test.5; dec Test.0; dec Test.1; diff --git a/crates/compiler/test_mono/generated/issue_4772_weakened_monomorphic_destructure.txt b/crates/compiler/test_mono/generated/issue_4772_weakened_monomorphic_destructure.txt index f73033c8ad..95b540c91e 100644 --- a/crates/compiler/test_mono/generated/issue_4772_weakened_monomorphic_destructure.txt +++ b/crates/compiler/test_mono/generated/issue_4772_weakened_monomorphic_destructure.txt @@ -153,8 +153,8 @@ procedure Json.60 (Json.540): let Json.1336 : U8 = GetTagId Json.1327; let Json.1337 : Int1 = lowlevel Eq Json.1335 Json.1336; if Json.1337 then - let Json.542 : U64 = UnionAtIndex (Id 2) (Index 0) Json.1327; inc Json.540; + let Json.542 : U64 = UnionAtIndex (Id 2) (Index 0) Json.1327; let Json.1329 : List U8 = CallByName List.29 Json.540 Json.542; let Json.1332 : U64 = 0i64; let Json.1331 : {U64, U64} = Struct {Json.542, Json.1332}; @@ -506,18 +506,15 @@ procedure Json.68 (): procedure Json.69 (Json.1467): joinpoint Json.1197 Json.1165: let Json.599 : List U8 = StructAtIndex 0 Json.1165; - inc Json.599; + inc 4 Json.599; let Json.600 : List U8 = StructAtIndex 1 Json.1165; let Json.1315 : U64 = 0i64; let Json.601 : [C {}, C U8] = CallByName List.2 Json.599 Json.1315; let Json.1314 : U64 = 1i64; - inc Json.599; let Json.602 : [C {}, C U8] = CallByName List.2 Json.599 Json.1314; let Json.1313 : U64 = 2i64; - inc Json.599; let Json.603 : List U8 = CallByName List.29 Json.599 Json.1313; let Json.1312 : U64 = 6i64; - inc Json.599; let Json.604 : List U8 = CallByName List.29 Json.599 Json.1312; let Json.1198 : {[C {}, C U8], [C {}, C U8]} = Struct {Json.601, Json.602}; joinpoint Json.1277: @@ -865,7 +862,7 @@ procedure Test.12 (): let Test.16 : {List U8, I64} = Struct {Test.17, Test.18}; let Test.15 : [C Str, C {List U8, I64}] = TagId(1) Test.16; let Test.14 : Int1 = CallByName Bool.11 Test.10 Test.15; - dec Test.15; + dec Test.16; expect Test.14; dec Test.10; let Test.13 : {} = Struct {}; diff --git a/crates/compiler/test_mono/generated/list_one_vs_one_spread_issue_4685.txt b/crates/compiler/test_mono/generated/list_one_vs_one_spread_issue_4685.txt index e28549e81b..29f55a6889 100644 --- a/crates/compiler/test_mono/generated/list_one_vs_one_spread_issue_4685.txt +++ b/crates/compiler/test_mono/generated/list_one_vs_one_spread_issue_4685.txt @@ -5,7 +5,8 @@ procedure Test.0 (): let Test.9 : U64 = 1i64; let Test.10 : Int1 = lowlevel Eq Test.8 Test.9; if Test.10 then - dec Test.1; + dec Test.11; + decref Test.1; let Test.3 : Str = "B"; ret Test.3; else diff --git a/crates/compiler/test_mono/generated/peano1.txt b/crates/compiler/test_mono/generated/peano1.txt index 3e2bea837b..1d291bf98f 100644 --- a/crates/compiler/test_mono/generated/peano1.txt +++ b/crates/compiler/test_mono/generated/peano1.txt @@ -5,11 +5,20 @@ procedure Test.0 (): let Test.2 : [, C *self] = TagId(0) Test.13; let Test.10 : U8 = 1i64; let Test.11 : U8 = GetTagId Test.2; - dec Test.2; - let Test.12 : Int1 = lowlevel Eq Test.10 Test.11; - if Test.12 then - let Test.8 : I64 = 0i64; - ret Test.8; + joinpoint #Derived_gen.0: + let Test.12 : Int1 = lowlevel Eq Test.10 Test.11; + if Test.12 then + let Test.8 : I64 = 0i64; + ret Test.8; + else + let Test.9 : I64 = 1i64; + ret Test.9; + in + let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2; + if #Derived_gen.1 then + dec Test.13; + decref Test.2; + jump #Derived_gen.0; else - let Test.9 : I64 = 1i64; - ret Test.9; + decref Test.2; + jump #Derived_gen.0; diff --git a/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt b/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt index a84391b0ba..8984da0b47 100644 --- a/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt +++ b/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt @@ -30,6 +30,15 @@ procedure Test.0 (): let Test.16 : Str = ""; let Test.15 : [C List *self, C Str] = TagId(1) Test.16; let Test.13 : Int1 = CallByName Bool.11 Test.14 Test.15; - dec Test.15; - dec Test.14; - ret Test.13; + joinpoint #Derived_gen.0: + dec Test.14; + ret Test.13; + in + let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.15; + if #Derived_gen.1 then + dec Test.16; + decref Test.15; + jump #Derived_gen.0; + else + decref Test.15; + jump #Derived_gen.0; diff --git a/crates/compiler/test_mono/generated/quicksort_swap.txt b/crates/compiler/test_mono/generated/quicksort_swap.txt index add16507b3..5960c829d3 100644 --- a/crates/compiler/test_mono/generated/quicksort_swap.txt +++ b/crates/compiler/test_mono/generated/quicksort_swap.txt @@ -45,10 +45,9 @@ procedure Num.22 (#Attr.2, #Attr.3): procedure Test.1 (Test.2): let Test.28 : U64 = 0i64; - inc Test.2; + inc 2 Test.2; let Test.26 : [C {}, C I64] = CallByName List.2 Test.2 Test.28; let Test.27 : U64 = 0i64; - inc Test.2; let Test.25 : [C {}, C I64] = CallByName List.2 Test.2 Test.27; let Test.8 : {[C {}, C I64], [C {}, C I64]} = Struct {Test.25, Test.26}; joinpoint Test.22: diff --git a/crates/compiler/test_mono/generated/rigids.txt b/crates/compiler/test_mono/generated/rigids.txt index 613e31d8ee..a64759f07a 100644 --- a/crates/compiler/test_mono/generated/rigids.txt +++ b/crates/compiler/test_mono/generated/rigids.txt @@ -44,9 +44,8 @@ procedure Num.22 (#Attr.2, #Attr.3): ret Num.283; procedure Test.1 (Test.2, Test.3, Test.4): - inc Test.4; + inc 2 Test.4; let Test.29 : [C {}, C I64] = CallByName List.2 Test.4 Test.3; - inc Test.4; let Test.28 : [C {}, C I64] = CallByName List.2 Test.4 Test.2; let Test.13 : {[C {}, C I64], [C {}, C I64]} = Struct {Test.28, Test.29}; joinpoint Test.25: diff --git a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt index d8b5ebb53d..86b5b51e0b 100644 --- a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt +++ b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt @@ -136,8 +136,8 @@ procedure Json.25 (Json.183): let Json.1223 : List U8 = CallByName List.8 Json.1224 Json.1225; ret Json.1223; else - let Json.1265 : U64 = StructAtIndex 0 Json.186; inc Json.184; + let Json.1265 : U64 = StructAtIndex 0 Json.186; let Json.1264 : {List U8, List U8} = CallByName List.52 Json.184 Json.1265; let Json.210 : List U8 = StructAtIndex 0 Json.1264; let Json.212 : List U8 = StructAtIndex 1 Json.1264; diff --git a/crates/compiler/test_mono/src/tests.rs b/crates/compiler/test_mono/src/tests.rs index 5806a409ef..b17d9c9ad3 100644 --- a/crates/compiler/test_mono/src/tests.rs +++ b/crates/compiler/test_mono/src/tests.rs @@ -3050,3 +3050,19 @@ fn specialize_after_match() { "# ) } + +#[mono_test] +fn drop_specialize_after_struct() { + indoc!( + r#" + app "test" provides [main] to "./platform" + + Tuple a b : { left : a, right : b } + + main = + v = "value" + t = { left: v, right: v } + "result" + "# + ) +} diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index 10966b1ccc..b4fc930952 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -7,12 +7,6 @@ edition.workspace = true license.workspace = true version.workspace = true -[package.metadata.cargo-udeps.ignore] -# confy is currently unused but should not be removed -normal = ["confy"] -#development = [] -#build = [] - [features] default = [] @@ -40,7 +34,6 @@ bumpalo.workspace = true bytemuck.workspace = true cgmath.workspace = true colored.workspace = true -confy.workspace = true copypasta.workspace = true fs_extra.workspace = true futures.workspace = true diff --git a/default.nix b/default.nix index c6bab66358..5c8e8cbeea 100644 --- a/default.nix +++ b/default.nix @@ -23,7 +23,6 @@ rustPlatform.buildRustPackage { cargoLock = { lockFile = ./Cargo.lock; outputHashes = { - "confy-0.5.1" = "sha256-KML/uoze2djsFhYk488QAtauethDaC+0aZ3q56yAhuY="; "criterion-0.3.5" = "sha256-+FibPQGiR45g28xCHcM0pMN+C+Q8gO8206Wb5fiTy+k="; "inkwell-0.1.0" = "sha256-1kpvY3naS33B99nuu5ZYhb7mdddAyG+DkbUl/RG1Ptg="; "plotters-0.3.1" = "sha256-noy/RSjoEPZZbOJTZw1yxGcX5S+2q/7mxnUrzDyxOFw="; diff --git a/examples/gui/breakout/platform/Cargo.toml b/examples/gui/breakout/platform/Cargo.toml index 8590583a5b..ec0b370ed8 100644 --- a/examples/gui/breakout/platform/Cargo.toml +++ b/examples/gui/breakout/platform/Cargo.toml @@ -21,7 +21,6 @@ page_size = "0.4.2" roc_std = { path = "../../../../crates/roc_std" } cgmath = "0.18.0" colored = "2.0.0" -confy = { git = 'https://github.com/rust-cli/confy', features = ["yaml_conf"], default-features = false } copypasta = "0.7.1" fs_extra = "1.2.0" futures = "0.3.17" @@ -38,12 +37,6 @@ wgpu = { git = "https://github.com/gfx-rs/wgpu", rev = "0545e36" } wgpu_glyph = { git = "https://github.com/Anton-4/wgpu_glyph", rev = "257d109" } winit = "0.26.1" -[package.metadata.cargo-udeps.ignore] -# confy is currently unused but should not be removed -normal = ["confy"] -#development = [] -#build = [] - [features] default = [] diff --git a/examples/gui/platform/Cargo.toml b/examples/gui/platform/Cargo.toml index 0ac7d2812e..3f312012bf 100644 --- a/examples/gui/platform/Cargo.toml +++ b/examples/gui/platform/Cargo.toml @@ -22,7 +22,6 @@ page_size = "0.4.2" roc_std = { path = "../../../crates/roc_std" } cgmath = "0.18.0" colored = "2.0.0" -confy = { git = 'https://github.com/rust-cli/confy', features = ["yaml_conf"], default-features = false } copypasta = "0.7.1" fs_extra = "1.2.0" futures = "0.3.17" @@ -39,12 +38,6 @@ wgpu = { git = "https://github.com/gfx-rs/wgpu", rev = "0545e36" } wgpu_glyph = { git = "https://github.com/Anton-4/wgpu_glyph", rev = "257d109" } winit = "0.26.1" -[package.metadata.cargo-udeps.ignore] -# confy is currently unused but should not be removed -normal = ["confy"] -#development = [] -#build = [] - [features] default = [] diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc index c69ed2ce67..73ac783263 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc @@ -656,49 +656,11 @@ nextNodeId = \rendered -> eqRenderedTree : RenderedTree state, RenderedTree state -> Bool eqRenderedTree = \a, b -> (a.root == b.root) - && eqRenderedNodes a.nodes b.nodes + && (a.nodes == b.nodes) && (List.len a.handlers == List.len b.handlers) && (a.deletedNodeCache == b.deletedNodeCache) && (a.deletedHandlerCache == b.deletedHandlerCache) -eqRenderedNodes : List (Result RenderedNode [DeletedNode]), List (Result RenderedNode [DeletedNode]) -> Bool -eqRenderedNodes = \a, b -> - List.map2 a b Tuple - |> List.all - (\t -> - when t is - Tuple (Ok x) (Ok y) -> eqRenderedNode x y - Tuple (Err x) (Err y) -> x == y - _ -> Bool.false) - -eqRenderedNode : RenderedNode, RenderedNode -> Bool -eqRenderedNode = \a, b -> - when { a, b } is - { a: RenderedNone, b: RenderedNone } -> - Bool.true - - { a: RenderedText aStr, b: RenderedText bStr } -> - aStr == bStr - - { a: RenderedElement aName aAttrs aChildren, b: RenderedElement bName bAttrs bChildren } -> - (aName == bName) - && (aChildren == bChildren) # good enough for testing! - && eqRenderedAttrs aAttrs bAttrs - - _ -> Bool.false - -eqRenderedAttrs : RenderedAttributes, RenderedAttributes -> Bool -eqRenderedAttrs = \a, b -> - eqAttrDict a.eventListeners b.eventListeners - && eqAttrDict a.htmlAttrs b.htmlAttrs - && eqAttrDict a.domProps b.domProps - && eqAttrDict a.styles b.styles - -eqAttrDict : Dict Str v, Dict Str v -> Bool | v has Eq -eqAttrDict = \a, b -> - Dict.keys a - |> List.all \k -> Dict.get a k == Dict.get b k - # indexNodes expect html : Html {} @@ -713,12 +675,12 @@ expect expected = { nodes: [ RenderedText "Roc", - RenderedElement "a" { emptyRenderedAttrs & htmlAttrs: Dict.fromList [T "href" "https://www.roc-lang.org/"] } [0], + RenderedElement "a" { emptyRenderedAttrs & htmlAttrs: Dict.fromList [("href", "https://www.roc-lang.org/")] } [0], ], siblingIds: [1], } - (List.map2 actual.nodes expected.nodes eqRenderedNode |> List.walk Bool.true Bool.and) + (actual.nodes == expected.nodes) && (actual.siblingIds == expected.siblingIds) # diff @@ -822,7 +784,7 @@ expect Ok (RenderedText "The app"), Ok (RenderedElement "h1" emptyRenderedAttrs [0]), Ok (RenderedText "The answer is 42"), - Ok (RenderedElement "div" { emptyRenderedAttrs & eventListeners: Dict.fromList [T "click" { accessors: [], handlerId: 0 }] } [2]), + Ok (RenderedElement "div" { emptyRenderedAttrs & eventListeners: Dict.fromList [("click", { accessors: [], handlerId: 0 })] } [2]), Ok (RenderedElement "body" emptyRenderedAttrs [1, 3]), ], deletedNodeCache: [],