diff --git a/FAQ.md b/FAQ.md index ff7fcfa6cd..ff00856f08 100644 --- a/FAQ.md +++ b/FAQ.md @@ -188,23 +188,19 @@ would be unable to infer a type—and you'd have to write a type annotation. Thi situations where the editor would not be able to reliably tell you the type of part of your program, unlike today where it can accurately tell you the type of anything, even if you have no type annotations in your entire code base. -### Arbitrary-rank types +assuming that's right, here is a proposed new FAQ entry: -Unlike arbitrary-rank (aka "Rank-N") types, both Rank-1 and Rank-2 type systems are compatible with principal -type inference. Roc currently uses Rank-1 types, and the benefits of Rank-N over Rank-2 don't seem worth -sacrificing principal type inference to attain, so let's focus on the trade-offs between Rank-1 and Rank-2. - -Supporting Rank-2 types in Roc has been discussed before, but it has several important downsides: +### Higher-rank types +Roc uses a Rank-1 type system. Other languages, like Haskell, support Rank-2 or even arbitrary-rank (aka "Rank-N") types. Supporting higher-rank types in Roc has been discussed before, but it has several important downsides: + +- It would remove principal decidable type inference. (Only Rank-1 types are compatible with principal decidable type inference; Rank-2 types are decidable but the inferred types are not principal, and Rank 3+ types are not even fully decidable.) - It would increase the complexity of the language. - It would make some compiler error messages more confusing (e.g. they might mention `forall` because that was the most general type that could be inferred, even if that wasn't helpful or related to the actual problem). - It would substantially increase the complexity of the type checker, which would necessarily slow it down. +- Most significantly, it would make the runtime slower, because Roc compiles programs by fully specializing all function calls to their type instances (this is sometimes called monomorphization). It's unclear how we could fully specialize programs containing Rank-2 types, which means compiling programs that included Rank-2 types (or higher) would require losing specialization in general—which would substantially degrade runtime performance. -No implementation of Rank-2 types can remove any of these downsides. Thus far, we've been able to come up -with sufficiently nice APIs that only require Rank-1 types, and we haven't seen a really compelling use case -where the gap between the Rank-2 and Rank-1 designs was big enough to justify switching to Rank-2. - -As such, the plan is for Roc to stick with Rank-1 types indefinitely. In Roc's case, the benefits of Rank-1's faster compilation with nicer error messages and a simpler type system outweigh Rank-2's benefits of expanded API options. +As such, the plan is for Roc to stick with Rank-1 types indefinitely. ### Higher-kinded polymorphism diff --git a/crates/ast/src/constrain.rs b/crates/ast/src/constrain.rs index eb2d8080df..630ad41b9a 100644 --- a/crates/ast/src/constrain.rs +++ b/crates/ast/src/constrain.rs @@ -1959,8 +1959,8 @@ pub mod test_constrain { }; use indoc::indoc; - fn run_solve<'a>( - arena: &'a Bump, + fn run_solve( + arena: &Bump, mempool: &mut Pool, aliases: MutMap, rigid_variables: MutMap, diff --git a/crates/ast/src/mem_pool/pool.rs b/crates/ast/src/mem_pool/pool.rs index e28dbc33bd..f280f65af4 100644 --- a/crates/ast/src/mem_pool/pool.rs +++ b/crates/ast/src/mem_pool/pool.rs @@ -183,7 +183,7 @@ impl Pool { } } - pub fn get<'a, 'b, T>(&'a self, node_id: NodeId) -> &'b T { + pub fn get<'b, T>(&self, node_id: NodeId) -> &'b T { unsafe { let node_ptr = self.get_ptr(node_id) as *const T; diff --git a/crates/cli/src/format.rs b/crates/cli/src/format.rs index d8b0d3947d..7200109d61 100644 --- a/crates/cli/src/format.rs +++ b/crates/cli/src/format.rs @@ -100,11 +100,11 @@ pub fn format(files: std::vec::Vec, mode: FormatMode) -> Result<(), Str let mut before_file = file.clone(); before_file.set_extension("roc-format-failed-ast-before"); - std::fs::write(&before_file, &format!("{:#?}\n", ast_normalized)).unwrap(); + std::fs::write(&before_file, format!("{:#?}\n", ast_normalized)).unwrap(); let mut after_file = file.clone(); after_file.set_extension("roc-format-failed-ast-after"); - std::fs::write(&after_file, &format!("{:#?}\n", reparsed_ast_normalized)).unwrap(); + std::fs::write(&after_file, format!("{:#?}\n", reparsed_ast_normalized)).unwrap(); internal_error!( "Formatting bug; formatting didn't reparse as the same tree\n\n\ diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 4db1a3707c..7b8c93b7f8 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -1234,9 +1234,10 @@ fn run_wasm, S: AsRef<[u8]>>(_wasm_path: &std::path::Path, println!("Running wasm files is not supported on this target."); } -#[derive(Debug, Copy, Clone, EnumIter, IntoStaticStr, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, EnumIter, IntoStaticStr, PartialEq, Eq, Default)] pub enum Target { #[strum(serialize = "system")] + #[default] System, #[strum(serialize = "linux32")] Linux32, @@ -1248,12 +1249,6 @@ pub enum Target { Wasm32, } -impl Default for Target { - fn default() -> Self { - Target::System - } -} - impl Target { pub fn to_triple(self) -> Triple { use Target::*; diff --git a/crates/code_markup/src/markup/convert/from_ast.rs b/crates/code_markup/src/markup/convert/from_ast.rs index 4c3d470b04..18f3f14532 100644 --- a/crates/code_markup/src/markup/convert/from_ast.rs +++ b/crates/code_markup/src/markup/convert/from_ast.rs @@ -13,8 +13,8 @@ use crate::{ slow_pool::{MarkNodeId, SlowPool}, }; -pub fn ast_to_mark_nodes<'a>( - env: &mut Env<'a>, +pub fn ast_to_mark_nodes( + env: &mut Env<'_>, ast: &AST, mark_node_pool: &mut SlowPool, interns: &Interns, diff --git a/crates/code_markup/src/markup/convert/from_def2.rs b/crates/code_markup/src/markup/convert/from_def2.rs index 5e7e2ce818..c1d84a0d34 100644 --- a/crates/code_markup/src/markup/convert/from_def2.rs +++ b/crates/code_markup/src/markup/convert/from_def2.rs @@ -35,8 +35,8 @@ pub fn add_node( mark_node_id } -pub fn def2_to_markup<'a>( - env: &mut Env<'a>, +pub fn def2_to_markup( + env: &mut Env<'_>, def2: &Def2, def2_node_id: DefId, mark_node_pool: &mut SlowPool, diff --git a/crates/code_markup/src/markup/convert/from_expr2.rs b/crates/code_markup/src/markup/convert/from_expr2.rs index 17a8659570..04e5ee5d22 100644 --- a/crates/code_markup/src/markup/convert/from_expr2.rs +++ b/crates/code_markup/src/markup/convert/from_expr2.rs @@ -35,8 +35,8 @@ use roc_module::{module_err::ModuleResult, symbol::Interns}; use super::from_def2::add_node; // make Markup Nodes: generate String representation, assign Highlighting Style -pub fn expr2_to_markup<'a>( - env: &Env<'a>, +pub fn expr2_to_markup( + env: &Env<'_>, expr2: &Expr2, expr2_node_id: ExprId, mark_node_pool: &mut SlowPool, diff --git a/crates/code_markup/src/markup/nodes.rs b/crates/code_markup/src/markup/nodes.rs index 4ff045dea4..fc394530a4 100644 --- a/crates/code_markup/src/markup/nodes.rs +++ b/crates/code_markup/src/markup/nodes.rs @@ -258,7 +258,7 @@ pub fn make_nested_mn(children_ids: Vec, newlines_at_end: usize) -> } } -pub fn get_string<'a>(env: &Env<'a>, pool_str: &PoolStr) -> String { +pub fn get_string(env: &Env<'_>, pool_str: &PoolStr) -> String { pool_str.as_str(env.pool).to_owned() } diff --git a/crates/code_markup/src/markup/top_level_def.rs b/crates/code_markup/src/markup/top_level_def.rs index 3fbea9fe76..69119f750f 100644 --- a/crates/code_markup/src/markup/top_level_def.rs +++ b/crates/code_markup/src/markup/top_level_def.rs @@ -19,13 +19,13 @@ use super::{ }; // represents for example: `main = "Hello, World!"` -pub fn assignment_mark_node<'a>( +pub fn assignment_mark_node( identifier_id: IdentId, expr_mark_node_id: MarkNodeId, ast_node_id: ASTNodeId, mark_node_pool: &mut SlowPool, mark_id_ast_id_map: &mut MarkIdAstIdMap, - env: &Env<'a>, + env: &Env<'_>, ) -> ASTResult { let val_name = env.ident_ids.get_name_str_res(identifier_id)?; diff --git a/crates/compiler/alias_analysis/src/lib.rs b/crates/compiler/alias_analysis/src/lib.rs index 4533aa60d4..6dd850a27b 100644 --- a/crates/compiler/alias_analysis/src/lib.rs +++ b/crates/compiler/alias_analysis/src/lib.rs @@ -487,9 +487,9 @@ impl<'a> Env<'a> { } } -fn apply_refcount_operation<'a>( +fn apply_refcount_operation( builder: &mut FuncDefBuilder, - env: &mut Env<'a>, + env: &mut Env<'_>, block: BlockId, modify_rc: &ModifyRc, ) -> Result<()> { diff --git a/crates/compiler/build/src/link.rs b/crates/compiler/build/src/link.rs index 3cfad4a100..6009affe98 100644 --- a/crates/compiler/build/src/link.rs +++ b/crates/compiler/build/src/link.rs @@ -719,7 +719,7 @@ pub fn rebuild_host( if matches!(opt_level, OptLevel::Optimize) { rustc_cmd.arg("-O"); } else if matches!(opt_level, OptLevel::Size) { - rustc_cmd.arg("-C opt-level=s"); + rustc_cmd.args(["-C", "opt-level=s"]); } run_build_command(rustc_cmd, "host.rs", 0); @@ -1100,7 +1100,7 @@ fn link_linux( // Keep NIX_ env vars .envs( env::vars() - .filter(|&(ref k, _)| k.starts_with("NIX_")) + .filter(|(k, _)| k.starts_with("NIX_")) .collect::>(), ) .args([ diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index cc616af3d6..39394da39d 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -34,6 +34,7 @@ interface Num Binary32, Binary64, abs, + absDiff, neg, add, sub, @@ -643,6 +644,27 @@ toFrac : Num * -> Frac * ## Calling this on an unsigned integer (like [U32] or [U64]) never does anything. abs : Num a -> Num a +## Return the absolute difference between two numbers. +## +## ``` +## Num.absDiff 5 3 +## +## Num.absDiff -3 5 +## +## Num.absDiff 3.0 5.0 +## ``` +## +## If the answer to this operation can't fit in the return value (e.g. an +## [I8] answer that's higher than 127 or lower than -128), the result is an +## *overflow*. For [F64] and [F32], overflow results in an answer of either +## ∞ or -∞. For all other number types, overflow results in a panic. +absDiff : Num a, Num a -> Num a +absDiff = \a, b -> + if a > b then + a - b + else + b - a + ## Return a negative number when given a positive one, and vice versa. ## ``` ## Num.neg 5 diff --git a/crates/compiler/can/src/annotation.rs b/crates/compiler/can/src/annotation.rs index 473fcdbc24..f9a096f3d4 100644 --- a/crates/compiler/can/src/annotation.rs +++ b/crates/compiler/can/src/annotation.rs @@ -1134,7 +1134,7 @@ fn canonicalize_has_clause( } #[allow(clippy::too_many_arguments)] -fn can_extension_type<'a>( +fn can_extension_type( env: &mut Env, pol: CanPolarity, scope: &mut Scope, @@ -1142,7 +1142,7 @@ fn can_extension_type<'a>( introduced_variables: &mut IntroducedVariables, local_aliases: &mut VecMap, references: &mut VecSet, - opt_ext: &Option<&Loc>>, + opt_ext: &Option<&Loc>>, ext_problem_kind: roc_problem::can::ExtensionTypeKind, ) -> (Type, ExtImplicitOpenness) { fn valid_record_ext_type(typ: &Type) -> bool { @@ -1451,10 +1451,10 @@ fn can_assigned_fields<'a>( // TODO trim down these arguments! #[allow(clippy::too_many_arguments)] -fn can_assigned_tuple_elems<'a>( +fn can_assigned_tuple_elems( env: &mut Env, pol: CanPolarity, - elems: &&[Loc>], + elems: &&[Loc>], scope: &mut Scope, var_store: &mut VarStore, introduced_variables: &mut IntroducedVariables, diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index ee0879f180..581f4d080f 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -1050,9 +1050,7 @@ fn canonicalize_value_defs<'a>( let mut symbol_to_index: Vec<(IdentId, u32)> = Vec::with_capacity(pending_value_defs.len()); for (def_index, pending_def) in pending_value_defs.iter().enumerate() { - let mut new_bindings = BindingsFromPattern::new(pending_def.loc_pattern()) - .into_iter() - .peekable(); + let mut new_bindings = BindingsFromPattern::new(pending_def.loc_pattern()).peekable(); if new_bindings.peek().is_none() { env.problem(Problem::NoIdentifiersIntroduced( @@ -1339,8 +1337,8 @@ fn canonicalize_type_defs<'a>( /// Resolve all pending abilities, to add them to scope. #[allow(clippy::too_many_arguments)] -fn resolve_abilities<'a>( - env: &mut Env<'a>, +fn resolve_abilities( + env: &mut Env<'_>, output: &mut Output, var_store: &mut VarStore, scope: &mut Scope, @@ -2813,8 +2811,8 @@ fn to_pending_value_def<'a>( } /// Make aliases recursive -fn correct_mutual_recursive_type_alias<'a>( - env: &mut Env<'a>, +fn correct_mutual_recursive_type_alias( + env: &mut Env<'_>, original_aliases: VecMap, var_store: &mut VarStore, ) -> VecMap { @@ -3022,8 +3020,8 @@ fn correct_mutual_recursive_type_alias<'a>( unsafe { VecMap::zip(symbols_introduced, aliases) } } -fn make_tag_union_of_alias_recursive<'a>( - env: &mut Env<'a>, +fn make_tag_union_of_alias_recursive( + env: &mut Env<'_>, alias_name: Symbol, alias: &mut Alias, others: Vec, @@ -3215,8 +3213,8 @@ fn make_tag_union_recursive_help<'a, 'b>( } } -fn mark_cyclic_alias<'a>( - env: &mut Env<'a>, +fn mark_cyclic_alias( + env: &mut Env<'_>, typ: &mut Type, symbol: Symbol, alias_kind: AliasKind, diff --git a/crates/compiler/can/src/module.rs b/crates/compiler/can/src/module.rs index 105c7b0950..2f8eb3dd11 100644 --- a/crates/compiler/can/src/module.rs +++ b/crates/compiler/can/src/module.rs @@ -195,11 +195,11 @@ enum GeneratedInfo { } impl GeneratedInfo { - fn from_header_type<'a>( + fn from_header_type( env: &mut Env, scope: &mut Scope, var_store: &mut VarStore, - header_type: &HeaderType<'a>, + header_type: &HeaderType<'_>, ) -> Self { match header_type { HeaderType::Hosted { diff --git a/crates/compiler/can/src/pattern.rs b/crates/compiler/can/src/pattern.rs index 195957969f..b04802f10f 100644 --- a/crates/compiler/can/src/pattern.rs +++ b/crates/compiler/can/src/pattern.rs @@ -321,8 +321,8 @@ pub fn canonicalize_def_header_pattern<'a>( #[derive(PartialEq, Eq, Clone, Copy)] pub struct PermitShadows(pub bool); -fn canonicalize_pattern_symbol<'a>( - env: &mut Env<'a>, +fn canonicalize_pattern_symbol( + env: &mut Env<'_>, scope: &mut Scope, output: &mut Output, region: Region, diff --git a/crates/compiler/can/src/traverse.rs b/crates/compiler/can/src/traverse.rs index e2c657fff8..c22096ea72 100644 --- a/crates/compiler/can/src/traverse.rs +++ b/crates/compiler/can/src/traverse.rs @@ -122,7 +122,7 @@ pub fn walk_decls(visitor: &mut V, decls: &Declarations) { None => Pattern::Identifier(loc_symbol.value), }; - let function_def = &decls.function_bodies[function_index.index() as usize]; + let function_def = &decls.function_bodies[function_index.index()]; DeclarationInfo::Function { loc_symbol, @@ -133,7 +133,7 @@ pub fn walk_decls(visitor: &mut V, decls: &Declarations) { } } Destructure(destructure_index) => { - let destructure = &decls.destructs[destructure_index.index() as usize]; + let destructure = &decls.destructs[destructure_index.index()]; let loc_pattern = &destructure.loc_pattern; let loc_expr = &decls.expressions[index]; diff --git a/crates/compiler/constrain/src/expr.rs b/crates/compiler/constrain/src/expr.rs index f1292387aa..5261cf009c 100644 --- a/crates/compiler/constrain/src/expr.rs +++ b/crates/compiler/constrain/src/expr.rs @@ -2600,7 +2600,7 @@ pub fn constrain_decls( cycle_mark, ); - index += length as usize; + index += length; } } diff --git a/crates/compiler/derive/src/encoding.rs b/crates/compiler/derive/src/encoding.rs index 183d489db1..4073e960a9 100644 --- a/crates/compiler/derive/src/encoding.rs +++ b/crates/compiler/derive/src/encoding.rs @@ -55,7 +55,6 @@ pub(crate) fn derive_to_encoder( // Generalized tuple var so we can reuse this impl between many tuples: // if arity = n, this is (t1, ..., tn) for fresh t1, ..., tn. let flex_elems = (0..arity) - .into_iter() .map(|idx| (idx as usize, env.subs.fresh_unnamed_flex_var())) .collect::>(); let elems = TupleElems::insert_into_subs(env.subs, flex_elems); diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index 1f597f2dda..f01a28eac2 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -131,7 +131,6 @@ fn hash_tuple(env: &mut Env<'_>, fn_name: Symbol, arity: u32) -> (Variable, Expr // TODO: avoid an allocation here by pre-allocating the indices and variables `TupleElems` // will be instantiated with. let flex_elems: Vec<_> = (0..arity) - .into_iter() .map(|i| (i as usize, env.subs.fresh_unnamed_flex_var())) .collect(); let elems = TupleElems::insert_into_subs(env.subs, flex_elems); diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 1091b81458..8be46e1a3d 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -65,15 +65,15 @@ impl Newlines { pub trait Formattable { fn is_multiline(&self) -> bool; - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, ); - fn format<'buf>(&self, buf: &mut Buf<'buf>, indent: u16) { + fn format(&self, buf: &mut Buf<'_>, indent: u16) { self.format_with_options(buf, Parens::NotNeeded, Newlines::No, indent); } } @@ -87,9 +87,9 @@ where (*self).is_multiline() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -97,7 +97,7 @@ where (*self).format_with_options(buf, parens, newlines, indent) } - fn format<'buf>(&self, buf: &mut Buf<'buf>, indent: u16) { + fn format(&self, buf: &mut Buf<'_>, indent: u16) { (*self).format(buf, indent) } } @@ -120,9 +120,9 @@ where self.value.is_multiline() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -131,7 +131,7 @@ where .format_with_options(buf, parens, newlines, indent) } - fn format<'buf>(&self, buf: &mut Buf<'buf>, indent: u16) { + fn format(&self, buf: &mut Buf<'_>, indent: u16) { self.value.format(buf, indent) } } @@ -141,9 +141,9 @@ impl<'a> Formattable for UppercaseIdent<'a> { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, _indent: u16, @@ -206,9 +206,9 @@ impl<'a> Formattable for TypeAnnotation<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -424,9 +424,9 @@ impl<'a> Formattable for AssignedField<'a, TypeAnnotation<'a>> { is_multiline_assigned_field_help(self) } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, newlines: Newlines, indent: u16, @@ -441,9 +441,9 @@ impl<'a> Formattable for AssignedField<'a, Expr<'a>> { is_multiline_assigned_field_help(self) } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, newlines: Newlines, indent: u16, @@ -466,9 +466,9 @@ fn is_multiline_assigned_field_help(afield: &AssignedField<'_, T } } -fn format_assigned_field_help<'a, 'buf, T>( - zelf: &AssignedField<'a, T>, - buf: &mut Buf<'buf>, +fn format_assigned_field_help( + zelf: &AssignedField<'_, T>, + buf: &mut Buf<'_>, indent: u16, separator_spaces: usize, is_multiline: bool, @@ -545,9 +545,9 @@ impl<'a> Formattable for Tag<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -592,9 +592,9 @@ impl<'a> Formattable for HasClause<'a> { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -623,9 +623,9 @@ impl<'a> Formattable for HasImpls<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -662,9 +662,9 @@ impl<'a> Formattable for HasAbility<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -703,9 +703,9 @@ impl<'a> Formattable for HasAbilities<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, diff --git a/crates/compiler/fmt/src/def.rs b/crates/compiler/fmt/src/def.rs index d45e37b733..f1011906fd 100644 --- a/crates/compiler/fmt/src/def.rs +++ b/crates/compiler/fmt/src/def.rs @@ -15,9 +15,9 @@ impl<'a> Formattable for Defs<'a> { !self.tags.is_empty() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -57,9 +57,9 @@ impl<'a> Formattable for TypeDef<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, newlines: Newlines, indent: u16, @@ -171,9 +171,9 @@ impl<'a> Formattable for TypeHeader<'a> { self.vars.iter().any(|v| v.is_multiline()) } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -205,9 +205,9 @@ impl<'a> Formattable for ValueDef<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, newlines: Newlines, indent: u16, @@ -314,8 +314,8 @@ fn should_outdent(mut rhs: &TypeAnnotation) -> bool { } } -fn fmt_dbg_in_def<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_dbg_in_def<'a>( + buf: &mut Buf<'_>, condition: &'a Loc>, is_multiline: bool, indent: u16, @@ -335,8 +335,8 @@ fn fmt_dbg_in_def<'a, 'buf>( condition.format(buf, return_indent); } -fn fmt_expect<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_expect<'a>( + buf: &mut Buf<'_>, condition: &'a Loc>, is_multiline: bool, indent: u16, @@ -356,8 +356,8 @@ fn fmt_expect<'a, 'buf>( condition.format(buf, return_indent); } -fn fmt_expect_fx<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_expect_fx<'a>( + buf: &mut Buf<'_>, condition: &'a Loc>, is_multiline: bool, indent: u16, @@ -377,28 +377,19 @@ fn fmt_expect_fx<'a, 'buf>( condition.format(buf, return_indent); } -pub fn fmt_value_def<'a, 'buf>( - buf: &mut Buf<'buf>, - def: &roc_parse::ast::ValueDef<'a>, - indent: u16, -) { +pub fn fmt_value_def(buf: &mut Buf<'_>, def: &roc_parse::ast::ValueDef<'_>, indent: u16) { def.format(buf, indent); } -pub fn fmt_type_def<'a, 'buf>(buf: &mut Buf<'buf>, def: &roc_parse::ast::TypeDef<'a>, indent: u16) { +pub fn fmt_type_def(buf: &mut Buf<'_>, def: &roc_parse::ast::TypeDef<'_>, indent: u16) { def.format(buf, indent); } -pub fn fmt_defs<'a, 'buf>(buf: &mut Buf<'buf>, defs: &Defs<'a>, indent: u16) { +pub fn fmt_defs(buf: &mut Buf<'_>, defs: &Defs<'_>, indent: u16) { defs.format(buf, indent); } -pub fn fmt_body<'a, 'buf>( - buf: &mut Buf<'buf>, - pattern: &'a Pattern<'a>, - body: &'a Expr<'a>, - indent: u16, -) { +pub fn fmt_body<'a>(buf: &mut Buf<'_>, pattern: &'a Pattern<'a>, body: &'a Expr<'a>, indent: u16) { pattern.format_with_options(buf, Parens::InApply, Newlines::No, indent); buf.indent(indent); buf.push_str(" ="); @@ -462,9 +453,9 @@ impl<'a> Formattable for AbilityMember<'a> { self.name.value.is_multiline() || self.typ.is_multiline() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs index b644f185c0..79417726cc 100644 --- a/crates/compiler/fmt/src/expr.rs +++ b/crates/compiler/fmt/src/expr.rs @@ -103,9 +103,9 @@ impl<'a> Formattable for Expr<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -551,7 +551,7 @@ fn starts_with_newline(expr: &Expr) -> bool { } } -fn format_str_segment<'a, 'buf>(seg: &StrSegment<'a>, buf: &mut Buf<'buf>, indent: u16) { +fn format_str_segment(seg: &StrSegment<'_>, buf: &mut Buf<'_>, indent: u16) { use StrSegment::*; match seg { @@ -614,7 +614,7 @@ fn push_op(buf: &mut Buf, op: BinOp) { } } -pub fn fmt_str_literal<'buf>(buf: &mut Buf<'buf>, literal: StrLiteral, indent: u16) { +pub fn fmt_str_literal(buf: &mut Buf<'_>, literal: StrLiteral, indent: u16) { use roc_parse::ast::StrLiteral::*; match literal { @@ -673,8 +673,8 @@ pub fn fmt_str_literal<'buf>(buf: &mut Buf<'buf>, literal: StrLiteral, indent: u } } -fn fmt_binops<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_binops<'a>( + buf: &mut Buf<'_>, lefts: &'a [(Loc>, Loc)], loc_right_side: &'a Loc>, part_of_multi_line_binops: bool, @@ -704,9 +704,9 @@ fn fmt_binops<'a, 'buf>( loc_right_side.format_with_options(buf, Parens::InOperator, Newlines::Yes, indent); } -fn format_spaces<'a, 'buf>( - buf: &mut Buf<'buf>, - spaces: &[CommentOrNewline<'a>], +fn format_spaces( + buf: &mut Buf<'_>, + spaces: &[CommentOrNewline<'_>], newlines: Newlines, indent: u16, ) { @@ -738,8 +738,8 @@ fn is_when_patterns_multiline(when_branch: &WhenBranch) -> bool { is_multiline_patterns } -fn fmt_when<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_when<'a>( + buf: &mut Buf<'_>, loc_condition: &'a Loc>, branches: &[&'a WhenBranch<'a>], indent: u16, @@ -920,8 +920,8 @@ fn fmt_when<'a, 'buf>( } } -fn fmt_dbg<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_dbg<'a>( + buf: &mut Buf<'_>, condition: &'a Loc>, continuation: &'a Loc>, is_multiline: bool, @@ -947,8 +947,8 @@ fn fmt_dbg<'a, 'buf>( continuation.format(buf, indent); } -fn fmt_expect<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_expect<'a>( + buf: &mut Buf<'_>, condition: &'a Loc>, continuation: &'a Loc>, is_multiline: bool, @@ -974,8 +974,8 @@ fn fmt_expect<'a, 'buf>( continuation.format(buf, indent); } -fn fmt_if<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_if<'a>( + buf: &mut Buf<'_>, branches: &'a [(Loc>, Loc>)], final_else: &'a Loc>, is_multiline: bool, @@ -1123,8 +1123,8 @@ fn fmt_if<'a, 'buf>( final_else.format(buf, return_indent); } -fn fmt_closure<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_closure<'a>( + buf: &mut Buf<'_>, loc_patterns: &'a [Loc>], loc_ret: &'a Loc>, indent: u16, @@ -1224,8 +1224,8 @@ fn fmt_closure<'a, 'buf>( } } -fn fmt_backpassing<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_backpassing<'a>( + buf: &mut Buf<'_>, loc_patterns: &'a [Loc>], loc_body: &'a Loc>, loc_ret: &'a Loc>, @@ -1312,8 +1312,8 @@ fn pattern_needs_parens_when_backpassing(pat: &Pattern) -> bool { } } -fn fmt_record<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_record<'a>( + buf: &mut Buf<'_>, update: Option<&'a Loc>>, fields: Collection<'a, Loc>>>, indent: u16, @@ -1404,9 +1404,9 @@ fn fmt_record<'a, 'buf>( } } -fn format_field_multiline<'a, 'buf, T>( - buf: &mut Buf<'buf>, - field: &AssignedField<'a, T>, +fn format_field_multiline( + buf: &mut Buf<'_>, + field: &AssignedField<'_, T>, indent: u16, separator_prefix: &str, ) where diff --git a/crates/compiler/fmt/src/module.rs b/crates/compiler/fmt/src/module.rs index ab818b9ed0..7d39c7b177 100644 --- a/crates/compiler/fmt/src/module.rs +++ b/crates/compiler/fmt/src/module.rs @@ -44,9 +44,9 @@ macro_rules! keywords { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: crate::annotation::Parens, _newlines: Newlines, indent: u16, @@ -86,9 +86,9 @@ impl Formattable for Option { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: crate::annotation::Parens, newlines: Newlines, indent: u16, @@ -111,9 +111,9 @@ impl<'a> Formattable for ProvidesTo<'a> { || self.to_keyword.is_multiline() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: crate::annotation::Parens, _newlines: Newlines, indent: u16, @@ -130,9 +130,9 @@ impl<'a> Formattable for PlatformRequires<'a> { is_collection_multiline(&self.rigids) || self.signature.is_multiline() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: crate::annotation::Parens, _newlines: Newlines, indent: u16, @@ -146,9 +146,9 @@ impl<'a, V: Formattable> Formattable for Spaces<'a, V> { !self.before.is_empty() || !self.after.is_empty() || self.item.is_multiline() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: crate::annotation::Parens, newlines: Newlines, indent: u16, @@ -164,9 +164,9 @@ impl<'a, K: Formattable, V: Formattable> Formattable for KeywordItem<'a, K, V> { self.keyword.is_multiline() || self.item.is_multiline() } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, @@ -177,7 +177,7 @@ impl<'a, K: Formattable, V: Formattable> Formattable for KeywordItem<'a, K, V> { } } -pub fn fmt_interface_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a InterfaceHeader<'a>) { +pub fn fmt_interface_header<'a>(buf: &mut Buf<'_>, header: &'a InterfaceHeader<'a>) { buf.indent(0); buf.push_str("interface"); let indent = INDENT; @@ -193,7 +193,7 @@ pub fn fmt_interface_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a Interface fmt_imports(buf, header.imports.item, indent); } -pub fn fmt_hosted_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a HostedHeader<'a>) { +pub fn fmt_hosted_header<'a>(buf: &mut Buf<'_>, header: &'a HostedHeader<'a>) { buf.indent(0); buf.push_str("hosted"); let indent = INDENT; @@ -210,7 +210,7 @@ pub fn fmt_hosted_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a HostedHeader fmt_exposes(buf, header.generates_with.item, indent); } -pub fn fmt_app_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a AppHeader<'a>) { +pub fn fmt_app_header<'a>(buf: &mut Buf<'_>, header: &'a AppHeader<'a>) { buf.indent(0); buf.push_str("app"); let indent = INDENT; @@ -229,7 +229,7 @@ pub fn fmt_app_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a AppHeader<'a>) header.provides.format(buf, indent); } -pub fn fmt_package_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a PackageHeader<'a>) { +pub fn fmt_package_header<'a>(buf: &mut Buf<'_>, header: &'a PackageHeader<'a>) { buf.indent(0); buf.push_str("package"); let indent = INDENT; @@ -243,7 +243,7 @@ pub fn fmt_package_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a PackageHead fmt_packages(buf, header.packages.item, indent); } -pub fn fmt_platform_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a PlatformHeader<'a>) { +pub fn fmt_platform_header<'a>(buf: &mut Buf<'_>, header: &'a PlatformHeader<'a>) { buf.indent(0); buf.push_str("platform"); let indent = INDENT; @@ -262,7 +262,7 @@ pub fn fmt_platform_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a PlatformHe fmt_provides(buf, header.provides.item, None, indent); } -fn fmt_requires<'a, 'buf>(buf: &mut Buf<'buf>, requires: &PlatformRequires<'a>, indent: u16) { +fn fmt_requires(buf: &mut Buf<'_>, requires: &PlatformRequires<'_>, indent: u16) { fmt_collection(buf, indent, Braces::Curly, requires.rigids, Newlines::No); buf.push_str(" {"); @@ -276,9 +276,9 @@ impl<'a> Formattable for TypedIdent<'a> { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -293,7 +293,7 @@ impl<'a> Formattable for TypedIdent<'a> { } } -fn fmt_package_name<'buf>(buf: &mut Buf<'buf>, name: PackageName, indent: u16) { +fn fmt_package_name(buf: &mut Buf<'_>, name: PackageName, indent: u16) { buf.indent(indent); buf.push('"'); buf.push_str_allow_spaces(name.to_str()); @@ -312,9 +312,9 @@ impl<'a, T: Formattable> Formattable for Spaced<'a, T> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: crate::annotation::Parens, newlines: Newlines, indent: u16, @@ -335,16 +335,16 @@ impl<'a, T: Formattable> Formattable for Spaced<'a, T> { } } -fn fmt_imports<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_imports<'a>( + buf: &mut Buf<'_>, loc_entries: Collection<'a, Loc>>>, indent: u16, ) { fmt_collection(buf, indent, Braces::Square, loc_entries, Newlines::No) } -fn fmt_provides<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_provides<'a>( + buf: &mut Buf<'_>, loc_exposed_names: Collection<'a, Loc>>>, loc_provided_types: Option>>>>, indent: u16, @@ -356,7 +356,7 @@ fn fmt_provides<'a, 'buf>( } } -fn fmt_to<'buf>(buf: &mut Buf<'buf>, to: To, indent: u16) { +fn fmt_to(buf: &mut Buf<'_>, to: To, indent: u16) { match to { To::ExistingPackage(name) => { buf.push_str(name); @@ -365,8 +365,8 @@ fn fmt_to<'buf>(buf: &mut Buf<'buf>, to: To, indent: u16) { } } -fn fmt_exposes<'buf, N: Formattable + Copy + core::fmt::Debug>( - buf: &mut Buf<'buf>, +fn fmt_exposes( + buf: &mut Buf<'_>, loc_entries: Collection<'_, Loc>>, indent: u16, ) { @@ -374,17 +374,17 @@ fn fmt_exposes<'buf, N: Formattable + Copy + core::fmt::Debug>( } pub trait FormatName { - fn format<'buf>(&self, buf: &mut Buf<'buf>); + fn format(&self, buf: &mut Buf<'_>); } impl<'a> FormatName for &'a str { - fn format<'buf>(&self, buf: &mut Buf<'buf>) { + fn format(&self, buf: &mut Buf<'_>) { buf.push_str(self) } } impl<'a> FormatName for ModuleName<'a> { - fn format<'buf>(&self, buf: &mut Buf<'buf>) { + fn format(&self, buf: &mut Buf<'_>) { buf.push_str(self.as_str()); } } @@ -394,9 +394,9 @@ impl<'a> Formattable for ModuleName<'a> { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, _indent: u16, @@ -410,9 +410,9 @@ impl<'a> Formattable for ExposedName<'a> { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -423,13 +423,13 @@ impl<'a> Formattable for ExposedName<'a> { } impl<'a> FormatName for ExposedName<'a> { - fn format<'buf>(&self, buf: &mut Buf<'buf>) { + fn format(&self, buf: &mut Buf<'_>) { buf.push_str(self.as_str()); } } -fn fmt_packages<'a, 'buf>( - buf: &mut Buf<'buf>, +fn fmt_packages<'a>( + buf: &mut Buf<'_>, loc_entries: Collection<'a, Loc>>>, indent: u16, ) { @@ -441,9 +441,9 @@ impl<'a> Formattable for PackageEntry<'a> { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -457,9 +457,9 @@ impl<'a> Formattable for ImportsEntry<'a> { false } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -467,14 +467,14 @@ impl<'a> Formattable for ImportsEntry<'a> { fmt_imports_entry(buf, self, indent); } } -fn fmt_packages_entry<'a, 'buf>(buf: &mut Buf<'buf>, entry: &PackageEntry<'a>, indent: u16) { +fn fmt_packages_entry(buf: &mut Buf<'_>, entry: &PackageEntry<'_>, indent: u16) { buf.push_str(entry.shorthand); buf.push(':'); fmt_default_spaces(buf, entry.spaces_after_shorthand, indent); fmt_package_name(buf, entry.package_name.value, indent); } -fn fmt_imports_entry<'a, 'buf>(buf: &mut Buf<'buf>, entry: &ImportsEntry<'a>, indent: u16) { +fn fmt_imports_entry(buf: &mut Buf<'_>, entry: &ImportsEntry<'_>, indent: u16) { use roc_parse::header::ImportsEntry::*; buf.indent(indent); diff --git a/crates/compiler/fmt/src/pattern.rs b/crates/compiler/fmt/src/pattern.rs index e1d4265569..517b0a684f 100644 --- a/crates/compiler/fmt/src/pattern.rs +++ b/crates/compiler/fmt/src/pattern.rs @@ -4,12 +4,7 @@ use crate::spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT}; use crate::Buf; use roc_parse::ast::{Base, CommentOrNewline, Pattern, PatternAs}; -pub fn fmt_pattern<'a, 'buf>( - buf: &mut Buf<'buf>, - pattern: &'a Pattern<'a>, - indent: u16, - parens: Parens, -) { +pub fn fmt_pattern<'a>(buf: &mut Buf<'_>, pattern: &'a Pattern<'a>, indent: u16, parens: Parens) { pattern.format_with_options(buf, parens, Newlines::No, indent); } @@ -18,9 +13,9 @@ impl<'a> Formattable for PatternAs<'a> { self.spaces_before.iter().any(|s| s.is_comment()) } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, _parens: Parens, _newlines: Newlines, indent: u16, @@ -85,9 +80,9 @@ impl<'a> Formattable for Pattern<'a> { } } - fn format_with_options<'buf>( + fn format_with_options( &self, - buf: &mut Buf<'buf>, + buf: &mut Buf<'_>, parens: Parens, newlines: Newlines, indent: u16, diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index 172b7c7d9f..20cea844b8 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -21,22 +21,14 @@ use crate::{Ast, Buf}; /// The number of spaces to indent. pub const INDENT: u16 = 4; -pub fn fmt_default_spaces<'a, 'buf>( - buf: &mut Buf<'buf>, - spaces: &[CommentOrNewline<'a>], - indent: u16, -) { +pub fn fmt_default_spaces(buf: &mut Buf<'_>, spaces: &[CommentOrNewline<'_>], indent: u16) { if spaces.is_empty() { buf.spaces(1); } else { fmt_spaces(buf, spaces.iter(), indent); } } -pub fn fmt_default_newline<'a, 'buf>( - buf: &mut Buf<'buf>, - spaces: &[CommentOrNewline<'a>], - indent: u16, -) { +pub fn fmt_default_newline(buf: &mut Buf<'_>, spaces: &[CommentOrNewline<'_>], indent: u16) { if spaces.is_empty() { buf.newline(); } else { @@ -153,7 +145,7 @@ pub fn fmt_comments_only<'a, 'buf, I>( } } -fn fmt_comment<'buf>(buf: &mut Buf<'buf>, comment: &str) { +fn fmt_comment(buf: &mut Buf<'_>, comment: &str) { // The '#' in a comment should always be preceded by a newline or a space, // unless it's the very beginning of the buffer. if !buf.is_empty() && !buf.ends_with_space() && !buf.ends_with_newline() { @@ -192,7 +184,7 @@ where count } -fn fmt_docs<'buf>(buf: &mut Buf<'buf>, docs: &str) { +fn fmt_docs(buf: &mut Buf<'_>, docs: &str) { // The "##" in a doc comment should always be preceded by a newline or a space, // unless it's the very beginning of the buffer. if !buf.is_empty() && !buf.ends_with_space() && !buf.ends_with_newline() { diff --git a/crates/compiler/gen_dev/src/generic64/aarch64.rs b/crates/compiler/gen_dev/src/generic64/aarch64.rs index 704bfc8285..ce65cf9fc6 100644 --- a/crates/compiler/gen_dev/src/generic64/aarch64.rs +++ b/crates/compiler/gen_dev/src/generic64/aarch64.rs @@ -104,7 +104,40 @@ impl AArch64GeneralReg { #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] #[allow(dead_code)] -pub enum AArch64FloatReg {} +pub enum AArch64FloatReg { + V0 = 0, + V1 = 1, + V2 = 2, + V3 = 3, + V4 = 4, + V5 = 5, + V6 = 6, + V7 = 7, + V8 = 8, + V9 = 9, + V10 = 10, + V11 = 11, + V12 = 12, + V13 = 13, + V14 = 14, + V15 = 15, + V16 = 16, + V17 = 17, + V18 = 18, + V19 = 19, + V20 = 20, + V21 = 21, + V22 = 22, + V23 = 23, + V24 = 24, + V25 = 25, + V26 = 26, + V27 = 27, + V28 = 28, + V29 = 29, + V30 = 30, + V31 = 31, +} impl RegTrait for AArch64FloatReg { fn value(&self) -> u8 { *self as u8 @@ -112,7 +145,51 @@ impl RegTrait for AArch64FloatReg { } impl std::fmt::Display for AArch64FloatReg { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "TODO",) + write!( + f, + "{}", + match self { + AArch64FloatReg::V0 => "v0", + AArch64FloatReg::V1 => "v1", + AArch64FloatReg::V2 => "v2", + AArch64FloatReg::V3 => "v3", + AArch64FloatReg::V4 => "v4", + AArch64FloatReg::V5 => "v5", + AArch64FloatReg::V6 => "v6", + AArch64FloatReg::V7 => "v7", + AArch64FloatReg::V8 => "v8", + AArch64FloatReg::V9 => "v9", + AArch64FloatReg::V10 => "v10", + AArch64FloatReg::V11 => "v11", + AArch64FloatReg::V12 => "v12", + AArch64FloatReg::V13 => "v13", + AArch64FloatReg::V14 => "v14", + AArch64FloatReg::V15 => "v15", + AArch64FloatReg::V16 => "v16", + AArch64FloatReg::V17 => "v17", + AArch64FloatReg::V18 => "v18", + AArch64FloatReg::V19 => "v19", + AArch64FloatReg::V20 => "v20", + AArch64FloatReg::V21 => "v21", + AArch64FloatReg::V22 => "v22", + AArch64FloatReg::V23 => "v23", + AArch64FloatReg::V24 => "v24", + AArch64FloatReg::V25 => "v25", + AArch64FloatReg::V26 => "v26", + AArch64FloatReg::V27 => "v27", + AArch64FloatReg::V28 => "v28", + AArch64FloatReg::V29 => "v29", + AArch64FloatReg::V30 => "v30", + AArch64FloatReg::V31 => "v31", + } + ) + } +} + +impl AArch64FloatReg { + #[inline(always)] + fn id(&self) -> u8 { + *self as u8 } } @@ -308,11 +385,11 @@ impl CallConv for AArch64C } #[inline(always)] - fn load_args<'a, 'r>( + fn load_args<'a>( _buf: &mut Vec<'a, u8>, _storage_manager: &mut StorageManager< 'a, - 'r, + '_, AArch64GeneralReg, AArch64FloatReg, AArch64Assembler, @@ -326,11 +403,11 @@ impl CallConv for AArch64C } #[inline(always)] - fn store_args<'a, 'r>( + fn store_args<'a>( _buf: &mut Vec<'a, u8>, _storage_manager: &mut StorageManager< 'a, - 'r, + '_, AArch64GeneralReg, AArch64FloatReg, AArch64Assembler, @@ -345,11 +422,11 @@ impl CallConv for AArch64C todo!("Storing args for AArch64"); } - fn return_complex_symbol<'a, 'r>( + fn return_complex_symbol<'a>( _buf: &mut Vec<'a, u8>, _storage_manager: &mut StorageManager< 'a, - 'r, + '_, AArch64GeneralReg, AArch64FloatReg, AArch64Assembler, @@ -362,11 +439,11 @@ impl CallConv for AArch64C todo!("Returning complex symbols for AArch64"); } - fn load_returned_complex_symbol<'a, 'r>( + fn load_returned_complex_symbol<'a>( _buf: &mut Vec<'a, u8>, _storage_manager: &mut StorageManager< 'a, - 'r, + '_, AArch64GeneralReg, AArch64FloatReg, AArch64Assembler, @@ -389,12 +466,12 @@ impl Assembler for AArch64Assembler { #[inline(always)] fn abs_freg64_freg64( - _buf: &mut Vec<'_, u8>, + buf: &mut Vec<'_, u8>, _relocs: &mut Vec<'_, Relocation>, - _dst: AArch64FloatReg, - _src: AArch64FloatReg, + dst: AArch64FloatReg, + src: AArch64FloatReg, ) { - todo!("abs_reg64_reg64 for AArch64"); + fabs_freg_freg(buf, FloatWidth::F64, dst, src); } #[inline(always)] @@ -423,21 +500,21 @@ impl Assembler for AArch64Assembler { } #[inline(always)] fn add_freg32_freg32_freg32( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src1: AArch64FloatReg, - _src2: AArch64FloatReg, + buf: &mut Vec<'_, u8>, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, ) { - todo!("adding floats for AArch64"); + fadd_freg_freg_freg(buf, FloatWidth::F32, dst, src1, src2); } #[inline(always)] fn add_freg64_freg64_freg64( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src1: AArch64FloatReg, - _src2: AArch64FloatReg, + buf: &mut Vec<'_, u8>, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, ) { - todo!("adding floats for AArch64"); + fadd_freg_freg_freg(buf, FloatWidth::F64, dst, src1, src2); } #[inline(always)] @@ -455,9 +532,9 @@ impl Assembler for AArch64Assembler { mul_reg64_reg64_reg64(buf, dst, src1, src2); } - fn umul_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn umul_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - _storage_manager: &mut StorageManager<'a, 'r, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, + _storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, dst: AArch64GeneralReg, src1: AArch64GeneralReg, src2: AArch64GeneralReg, @@ -468,9 +545,9 @@ impl Assembler for AArch64Assembler { mul_reg64_reg64_reg64(buf, dst, src1, src2); } - fn idiv_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn idiv_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - _storage_manager: &mut StorageManager<'a, 'r, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, + _storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, dst: AArch64GeneralReg, src1: AArch64GeneralReg, src2: AArch64GeneralReg, @@ -481,9 +558,9 @@ impl Assembler for AArch64Assembler { sdiv_reg64_reg64_reg64(buf, dst, src1, src2); } - fn udiv_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn udiv_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - _storage_manager: &mut StorageManager<'a, 'r, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, + _storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, dst: AArch64GeneralReg, src1: AArch64GeneralReg, src2: AArch64GeneralReg, @@ -496,40 +573,40 @@ impl Assembler for AArch64Assembler { #[inline(always)] fn mul_freg32_freg32_freg32( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src1: AArch64FloatReg, - _src2: AArch64FloatReg, + buf: &mut Vec<'_, u8>, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, ) { - todo!("multiplication for floats for AArch64"); + fmul_freg_freg_freg(buf, FloatWidth::F32, dst, src1, src2); } #[inline(always)] fn mul_freg64_freg64_freg64( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src1: AArch64FloatReg, - _src2: AArch64FloatReg, + buf: &mut Vec<'_, u8>, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, ) { - todo!("multiplication for floats for AArch64"); + fmul_freg_freg_freg(buf, FloatWidth::F64, dst, src1, src2); } #[inline(always)] fn div_freg32_freg32_freg32( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src1: AArch64FloatReg, - _src2: AArch64FloatReg, + buf: &mut Vec<'_, u8>, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, ) { - todo!("division for floats for AArch64"); + fdiv_freg_freg_freg(buf, FloatWidth::F32, dst, src1, src2); } #[inline(always)] fn div_freg64_freg64_freg64( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src1: AArch64FloatReg, - _src2: AArch64FloatReg, + buf: &mut Vec<'_, u8>, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, ) { - todo!("division for floats for AArch64"); + fdiv_freg_freg_freg(buf, FloatWidth::F64, dst, src1, src2); } #[inline(always)] @@ -576,21 +653,45 @@ impl Assembler for AArch64Assembler { #[inline(always)] fn mov_freg32_imm32( - _buf: &mut Vec<'_, u8>, + buf: &mut Vec<'_, u8>, _relocs: &mut Vec<'_, Relocation>, - _dst: AArch64FloatReg, - _imm: f32, + dst: AArch64FloatReg, + imm: f32, ) { - todo!("loading f32 literal for AArch64"); + // See https://stackoverflow.com/a/64608524 + if imm == 0.0 && !imm.is_sign_negative() { + movi_freg_zero(buf, dst); + return; + } + match encode_f32_to_imm8(imm) { + Some(imm8) => { + fmov_freg_imm8(buf, FloatWidth::F32, dst, imm8); + } + None => { + todo!("loading f32 literal over 8 bits for AArch64"); + } + } } #[inline(always)] fn mov_freg64_imm64( - _buf: &mut Vec<'_, u8>, + buf: &mut Vec<'_, u8>, _relocs: &mut Vec<'_, Relocation>, - _dst: AArch64FloatReg, - _imm: f64, + dst: AArch64FloatReg, + imm: f64, ) { - todo!("loading f64 literal for AArch64"); + // See https://stackoverflow.com/a/64608524 + if imm == 0.0 && !imm.is_sign_negative() { + movi_freg_zero(buf, dst); + return; + } + match encode_f64_to_imm8(imm) { + Some(imm8) => { + fmov_freg_imm8(buf, FloatWidth::F64, dst, imm8); + } + None => { + todo!("loading f64 literal over 8 bits for AArch64"); + } + } } #[inline(always)] fn mov_reg64_imm64(buf: &mut Vec<'_, u8>, dst: AArch64GeneralReg, imm: i64) { @@ -610,8 +711,8 @@ impl Assembler for AArch64Assembler { } } #[inline(always)] - fn mov_freg64_freg64(_buf: &mut Vec<'_, u8>, _dst: AArch64FloatReg, _src: AArch64FloatReg) { - todo!("moving data between float registers for AArch64"); + fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) { + fmov_freg_freg(buf, FloatWidth::F64, dst, src); } #[inline(always)] fn mov_reg64_reg64(buf: &mut Vec<'_, u8>, dst: AArch64GeneralReg, src: AArch64GeneralReg) { @@ -899,50 +1000,42 @@ impl Assembler for AArch64Assembler { #[inline(always)] fn cmp_freg_freg_reg64( - _buf: &mut Vec<'_, u8>, - _dst: AArch64GeneralReg, - _src1: AArch64FloatReg, - _src2: AArch64FloatReg, - _width: FloatWidth, - _operation: CompareOperation, + buf: &mut Vec<'_, u8>, + dst: AArch64GeneralReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, + width: FloatWidth, + operation: CompareOperation, ) { - todo!("registers float comparison for AArch64"); + fcmp_freg_freg(buf, width, src1, src2); + + let cond = match operation { + CompareOperation::LessThan => ConditionCode::MI, + CompareOperation::LessThanOrEqual => ConditionCode::LS, + CompareOperation::GreaterThan => ConditionCode::GT, + CompareOperation::GreaterThanOrEqual => ConditionCode::GE, + }; + cset_reg64_cond(buf, dst, cond); } #[inline(always)] - fn to_float_freg64_reg64( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src: AArch64GeneralReg, - ) { - todo!("registers to float for AArch64"); + fn to_float_freg64_reg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64GeneralReg) { + scvtf_freg_reg64(buf, FloatWidth::F64, dst, src); } #[inline(always)] - fn to_float_freg32_reg64( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src: AArch64GeneralReg, - ) { - todo!("registers to float for AArch64"); + fn to_float_freg32_reg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64GeneralReg) { + scvtf_freg_reg64(buf, FloatWidth::F32, dst, src); } #[inline(always)] - fn to_float_freg32_freg64( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src: AArch64FloatReg, - ) { - todo!("registers to float for AArch64"); + fn to_float_freg32_freg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) { + fcvt_freg32_freg64(buf, dst, src); } #[inline(always)] - fn to_float_freg64_freg32( - _buf: &mut Vec<'_, u8>, - _dst: AArch64FloatReg, - _src: AArch64FloatReg, - ) { - todo!("registers to float for AArch64"); + fn to_float_freg64_freg32(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) { + fcvt_freg64_freg32(buf, dst, src); } #[inline(always)] @@ -1003,9 +1096,9 @@ impl Assembler for AArch64Assembler { eor_reg64_reg64_reg64(buf, dst, src1, src2); } - fn shl_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn shl_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - _storage_manager: &mut StorageManager<'a, 'r, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, + _storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, dst: AArch64GeneralReg, src1: AArch64GeneralReg, src2: AArch64GeneralReg, @@ -1016,9 +1109,9 @@ impl Assembler for AArch64Assembler { lsl_reg64_reg64_reg64(buf, dst, src1, src2); } - fn shr_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn shr_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - _storage_manager: &mut StorageManager<'a, 'r, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, + _storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, dst: AArch64GeneralReg, src1: AArch64GeneralReg, src2: AArch64GeneralReg, @@ -1029,9 +1122,9 @@ impl Assembler for AArch64Assembler { lsr_reg64_reg64_reg64(buf, dst, src1, src2); } - fn sar_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn sar_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - _storage_manager: &mut StorageManager<'a, 'r, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, + _storage_manager: &mut StorageManager<'a, '_, AArch64GeneralReg, AArch64FloatReg, ASM, CC>, dst: AArch64GeneralReg, src1: AArch64GeneralReg, src2: AArch64GeneralReg, @@ -1042,12 +1135,12 @@ impl Assembler for AArch64Assembler { asr_reg64_reg64_reg64(buf, dst, src1, src2); } - fn sqrt_freg64_freg64(_buf: &mut Vec<'_, u8>, _dst: AArch64FloatReg, _src: AArch64FloatReg) { - todo!("sqrt") + fn sqrt_freg64_freg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) { + fsqrt_freg_freg(buf, FloatWidth::F64, dst, src); } - fn sqrt_freg32_freg32(_buf: &mut Vec<'_, u8>, _dst: AArch64FloatReg, _src: AArch64FloatReg) { - todo!("sqrt") + fn sqrt_freg32_freg32(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) { + fsqrt_freg_freg(buf, FloatWidth::F32, dst, src); } fn signed_compare_reg64( @@ -1771,11 +1864,324 @@ impl LoadStoreRegisterImmediate { } } -// Below here are the functions for all of the assembly instructions. +#[derive(PackedStruct)] +#[packed_struct(endian = "msb")] +pub struct AdvancedSimdModifiedImmediate { + fixed: bool, + q: bool, + op: bool, + fixed2: Integer>, + a: bool, + b: bool, + c: bool, + cmode: Integer>, + o2: bool, + fixed3: bool, + d: bool, + e: bool, + f: bool, + g: bool, + h: bool, + rd: Integer>, +} + +impl Aarch64Bytes for AdvancedSimdModifiedImmediate {} + +impl AdvancedSimdModifiedImmediate { + #[inline(always)] + fn new(rd: AArch64FloatReg) -> Self { + Self { + fixed: false, + q: false, + op: true, + fixed2: 0b0111100000.into(), + a: false, + b: false, + c: false, + cmode: 0b1110.into(), + o2: false, + fixed3: true, + d: false, + e: false, + f: false, + g: false, + h: false, + rd: rd.id().into(), + } + } +} + +fn encode_float_width(width: FloatWidth) -> u8 { + match width { + FloatWidth::F32 => 0b00, + FloatWidth::F64 => 0b01, + } +} + +#[derive(PackedStruct)] +#[packed_struct(endian = "msb")] +pub struct ConversionBetweenFloatingPointAndInteger { + sf: bool, + fixed: bool, + s: bool, + fixed2: Integer>, + ptype: Integer>, + fixed3: bool, + rmode: Integer>, + opcode: Integer>, + fixed4: Integer>, + rn: Integer>, + rd: Integer>, +} + +impl Aarch64Bytes for ConversionBetweenFloatingPointAndInteger {} + +pub struct ConversionBetweenFloatingPointAndIntegerParams { + ptype: FloatWidth, + rmode: u8, + opcode: u8, + rn: AArch64GeneralReg, + rd: AArch64FloatReg, +} + +impl ConversionBetweenFloatingPointAndInteger { + #[inline(always)] + fn new( + ConversionBetweenFloatingPointAndIntegerParams { + ptype, + rmode, + opcode, + rn, + rd, + }: ConversionBetweenFloatingPointAndIntegerParams, + ) -> Self { + debug_assert!(rmode <= 0b11); + debug_assert!(opcode <= 0b111); + + Self { + sf: true, + fixed: false, + s: false, + fixed2: 0b11110.into(), + ptype: encode_float_width(ptype).into(), + fixed3: true, + rmode: rmode.into(), + opcode: opcode.into(), + fixed4: 0b000000.into(), + rn: rn.id().into(), + rd: rd.id().into(), + } + } +} + +#[derive(PackedStruct)] +#[packed_struct(endian = "msb")] +pub struct FloatingPointDataProcessingOneSource { + m: bool, + fixed: bool, + s: bool, + fixed2: Integer>, + ptype: Integer>, + fixed3: bool, + opcode: Integer>, + fixed4: Integer>, + rn: Integer>, + rd: Integer>, +} + +impl Aarch64Bytes for FloatingPointDataProcessingOneSource {} + +pub struct FloatingPointDataProcessingOneSourceParams { + ptype: FloatWidth, + opcode: u8, + rn: AArch64FloatReg, + rd: AArch64FloatReg, +} + +impl FloatingPointDataProcessingOneSource { + #[inline(always)] + fn new( + FloatingPointDataProcessingOneSourceParams { + ptype, + opcode, + rn, + rd, + }: FloatingPointDataProcessingOneSourceParams, + ) -> Self { + debug_assert!(opcode <= 0b111111); + + Self { + m: false, + fixed: false, + s: false, + fixed2: 0b11110.into(), + ptype: encode_float_width(ptype).into(), + fixed3: true, + opcode: opcode.into(), + fixed4: 0b10000.into(), + rn: rn.id().into(), + rd: rd.id().into(), + } + } +} + +#[derive(PackedStruct)] +#[packed_struct(endian = "msb")] +pub struct FloatingPointCompare { + m: bool, + fixed: bool, + s: bool, + fixed2: Integer>, + ptype: Integer>, + fixed3: bool, + rm: Integer>, + op: Integer>, + fixed4: Integer>, + rn: Integer>, + opcode2: Integer>, +} + +impl Aarch64Bytes for FloatingPointCompare {} + +pub struct FloatingPointCompareParams { + ptype: FloatWidth, + rm: AArch64FloatReg, + rn: AArch64FloatReg, + opcode2: u8, +} + +impl FloatingPointCompare { + #[inline(always)] + fn new( + FloatingPointCompareParams { + ptype, + rm, + rn, + opcode2, + }: FloatingPointCompareParams, + ) -> Self { + debug_assert!(opcode2 <= 0b11111); + + Self { + m: false, + fixed: false, + s: false, + fixed2: 0b11110.into(), + ptype: encode_float_width(ptype).into(), + fixed3: true, + rm: rm.id().into(), + op: 0b00.into(), + fixed4: 0b1000.into(), + rn: rn.id().into(), + opcode2: opcode2.into(), + } + } +} + +#[derive(PackedStruct)] +#[packed_struct(endian = "msb")] +pub struct FloatingPointDataProcessingTwoSource { + m: bool, + fixed: bool, + s: bool, + fixed2: Integer>, + ptype: Integer>, + fixed3: bool, + rm: Integer>, + opcode: Integer>, + fixed4: Integer>, + rn: Integer>, + rd: Integer>, +} + +impl Aarch64Bytes for FloatingPointDataProcessingTwoSource {} + +pub struct FloatingPointDataProcessingTwoSourceParams { + ptype: FloatWidth, + rm: AArch64FloatReg, + opcode: u8, + rn: AArch64FloatReg, + rd: AArch64FloatReg, +} + +impl FloatingPointDataProcessingTwoSource { + #[inline(always)] + fn new( + FloatingPointDataProcessingTwoSourceParams { + ptype, + rm, + opcode, + rn, + rd, + }: FloatingPointDataProcessingTwoSourceParams, + ) -> Self { + debug_assert!(opcode <= 0b1111); + + Self { + m: false, + fixed: false, + s: false, + fixed2: 0b11110.into(), + ptype: encode_float_width(ptype).into(), + fixed3: true, + rm: rm.id().into(), + opcode: opcode.into(), + fixed4: 0b10.into(), + rn: rn.id().into(), + rd: rd.id().into(), + } + } +} + +#[derive(PackedStruct)] +#[packed_struct(endian = "msb")] +pub struct FloatingPointImmediate { + m: bool, + fixed: bool, + s: bool, + fixed2: Integer>, + ptype: Integer>, + fixed3: bool, + imm8: u8, + fixed4: Integer>, + imm5: Integer>, + rd: Integer>, +} + +impl Aarch64Bytes for FloatingPointImmediate {} + +pub struct FloatingPointImmediateParams { + ptype: FloatWidth, + imm8: u8, + rd: AArch64FloatReg, +} + +impl FloatingPointImmediate { + #[inline(always)] + fn new(FloatingPointImmediateParams { ptype, imm8, rd }: FloatingPointImmediateParams) -> Self { + Self { + m: false, + fixed: false, + s: false, + fixed2: 0b11110.into(), + ptype: encode_float_width(ptype).into(), + fixed3: true, + imm8, + fixed4: 0b100.into(), + imm5: 0b00000.into(), + rd: rd.id().into(), + } + } +} + +// Below here are the functions for all of the base assembly instructions. // Their names are based on the instruction and operators combined. // You should call `buf.reserve()` if you push or extend more than once. // Unit tests are added at the bottom of the file to ensure correct asm generation. // Please keep these in alphanumeric order. +// Floating-point (and advanced SIMD) instructions are at the bottom. + +// ARM manual section C6 /// `ADD Xd, Xn, imm12` -> Add Xn and imm12 and place the result into Xd. #[inline(always)] @@ -2302,6 +2708,312 @@ fn udiv_reg64_reg64_reg64( buf.extend(inst.bytes()); } +// Floating point (and advanced SIMD) instructions +// ARM manual section C7 + +/// `FABS Sd/Dd, Sn/Dn` -> Take the absolute value of Sn/Dn and place the result into Sd/Dd. +#[inline(always)] +fn fabs_freg_freg( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + dst: AArch64FloatReg, + src: AArch64FloatReg, +) { + let inst = + FloatingPointDataProcessingOneSource::new(FloatingPointDataProcessingOneSourceParams { + opcode: 0b000001, + ptype: ftype, + rd: dst, + rn: src, + }); + + buf.extend(inst.bytes()); +} + +/// `FADD Sd/Dd, Sn/Dn, Sm/Dm` -> Add Sn/Dn and Sm/Dm and place the result into Sd/Dd. +#[inline(always)] +fn fadd_freg_freg_freg( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, +) { + let inst = + FloatingPointDataProcessingTwoSource::new(FloatingPointDataProcessingTwoSourceParams { + opcode: 0b0010, + ptype: ftype, + rd: dst, + rn: src1, + rm: src2, + }); + + buf.extend(inst.bytes()); +} + +/// `FCMP Sn/Dn, Sm/Dm` -> Compare Sn/Dn and Sm/Dm, setting condition flags. +#[inline(always)] +fn fcmp_freg_freg( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + src1: AArch64FloatReg, + src2: AArch64FloatReg, +) { + let inst = FloatingPointCompare::new(FloatingPointCompareParams { + ptype: ftype, + rn: src1, + rm: src2, + opcode2: 0b00000, + }); + + buf.extend(inst.bytes()); +} + +/// `FCVT Sd, Dn` -> Convert 64-bit float Dn to 32-bit float Sd. +#[inline(always)] +fn fcvt_freg32_freg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) { + let inst = + FloatingPointDataProcessingOneSource::new(FloatingPointDataProcessingOneSourceParams { + opcode: 0b000100, + ptype: FloatWidth::F64, + rd: dst, + rn: src, + }); + + buf.extend(inst.bytes()); +} + +/// `FCVT Dd, Sn` -> Convert 32-bit float Sn to 64-bit float Dd. +#[inline(always)] +fn fcvt_freg64_freg32(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) { + let inst = + FloatingPointDataProcessingOneSource::new(FloatingPointDataProcessingOneSourceParams { + opcode: 0b000101, + ptype: FloatWidth::F32, + rd: dst, + rn: src, + }); + + buf.extend(inst.bytes()); +} + +/// `FDIV Sd/Dd, Sn/Dn, Sm/Dm` -> Divide Sn/Dn by Sm/Dm and place the result into Sd/Dd. +#[inline(always)] +fn fdiv_freg_freg_freg( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, +) { + let inst = + FloatingPointDataProcessingTwoSource::new(FloatingPointDataProcessingTwoSourceParams { + opcode: 0b0001, + ptype: ftype, + rd: dst, + rn: src1, + rm: src2, + }); + + buf.extend(inst.bytes()); +} + +/// `FMOV Sd/Dd, Sn/Dn` -> Move Sn/Dn to Sd/Dd. +#[inline(always)] +fn fmov_freg_freg( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + dst: AArch64FloatReg, + src: AArch64FloatReg, +) { + let inst = + FloatingPointDataProcessingOneSource::new(FloatingPointDataProcessingOneSourceParams { + opcode: 0b000000, + ptype: ftype, + rd: dst, + rn: src, + }); + + buf.extend(inst.bytes()); +} + +/// Encode a 32-bit float into an 8-bit immediate for FMOV. +/// See Table C2-1 in the ARM manual for a table of every float that can be encoded in 8 bits. +/// If the float cannot be encoded, return None. +/// This operation is the inverse of VFPExpandImm in the ARM manual. +#[inline(always)] +fn encode_f32_to_imm8(imm: f32) -> Option { + let n = 32; + let e = 8; // number of exponent bits in a 32-bit float + let f = n - e - 1; // 23: number of fraction bits in a 32-bit float + + let bits = imm.to_bits(); + + let sign = (bits >> (n - 1)) & 1; // bits<31> + let exp = (bits >> f) & ((1 << e) - 1); // bits<30:23> + let frac = bits & ((1 << f) - 1); // bits<22:0> + + let exp_first = (exp >> (e - 1)) & 1; // exp<7> + let exp_middle = (exp >> 2) & ((1 << (e - 3)) - 1); // exp<6:2> + let exp_last = exp & 0b11; // exp<1:0> + if exp_first == 0 && exp_middle != ((1 << (e - 3)) - 1) { + // If exp_first is 0, exp_middle must be all 1s. + return None; + } + if exp_first == 1 && exp_middle != 0 { + // If exp_first is 1, exp_middle must be all 0s. + return None; + } + + let frac_begin = frac >> (f - 4); // frac<22:19> + let frac_end = frac & ((1 << (f - 4)) - 1); // frac<18:0> + if frac_end != 0 { + // frac_end must be all 0s. + return None; + } + + // The sign is the same. + let ret_sign = sign << 7; + // The first bit of the exponent is inverted. + let ret_exp_first = (exp_first ^ 1) << 6; + // The rest of the exponent is the same as the last 2 bits of the original exponent. + let ret_exp_last = exp_last << 4; + // The fraction is the same as the first 4 bits of the original fraction. + let ret_frac = frac_begin; + + Some((ret_sign | ret_exp_first | ret_exp_last | ret_frac) as u8) +} + +/// Encode a 64-bit float into an 8-bit immediate for FMOV. +/// See Table C2-1 in the ARM manual for a table of every float that can be encoded in 8 bits. +/// If the float cannot be encoded, return None. +/// This operation is the inverse of VFPExpandImm in the ARM manual. +#[inline(always)] +fn encode_f64_to_imm8(imm: f64) -> Option { + let n = 64; + let e = 11; // number of exponent bits in a 64-bit float + let f = n - e - 1; // 52: number of fraction bits in a 64-bit float + + let bits = imm.to_bits(); + + let sign = (bits >> (n - 1)) & 1; // bits<63> + let exp = (bits >> f) & ((1 << e) - 1); // bits<62:52> + let frac = bits & ((1 << f) - 1); // bits<51:0> + + let exp_first = (exp >> (e - 1)) & 1; // exp<10> + let exp_middle = (exp >> 2) & ((1 << (e - 3)) - 1); // exp<9:2> + let exp_last = exp & 0b11; // exp<0:1> + if exp_first == 0 && exp_middle != ((1 << (e - 3)) - 1) { + // If exp_first is 0, exp_middle must be all 1s. + return None; + } + if exp_first == 1 && exp_middle != 0 { + // If exp_first is 1, exp_middle must be all 0s. + return None; + } + + let frac_begin = frac >> (f - 4); // frac<51:48> + let frac_end = frac & ((1 << (f - 4)) - 1); // frac<47:0> + if frac_end != 0 { + // frac_end must be all 0s. + return None; + } + + // The sign is the same. + let ret_sign = sign << 7; + // The first bit of the exponent is inverted. + let ret_exp_first = (exp_first ^ 1) << 6; + // The rest of the exponent is the same as the last 2 bits of the original exponent. + let ret_exp_last = exp_last << 4; + // The fraction is the same as the first 4 bits of the original fraction. + let ret_frac = frac_begin; + + Some((ret_sign | ret_exp_first | ret_exp_last | ret_frac) as u8) +} + +/// `FMOV Sd/Dd, imm8` -> Move imm8 to a float register. +/// imm8 is a float encoded using encode_f32_to_imm8 or encode_f64_to_imm8. +#[inline(always)] +fn fmov_freg_imm8(buf: &mut Vec<'_, u8>, ftype: FloatWidth, dst: AArch64FloatReg, imm8: u8) { + let inst = FloatingPointImmediate::new(FloatingPointImmediateParams { + ptype: ftype, + rd: dst, + imm8, + }); + + buf.extend(inst.bytes()); +} + +/// `FMUL Sd/Dd, Sn/Dn, Sm/Dm` -> Multiply Sn/Dn by Sm/Dm and store the result in Sd/Dd. +#[inline(always)] +fn fmul_freg_freg_freg( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + dst: AArch64FloatReg, + src1: AArch64FloatReg, + src2: AArch64FloatReg, +) { + let inst = + FloatingPointDataProcessingTwoSource::new(FloatingPointDataProcessingTwoSourceParams { + opcode: 0b0000, + ptype: ftype, + rd: dst, + rn: src1, + rm: src2, + }); + + buf.extend(inst.bytes()); +} + +/// `FSQRT Sd/Dd, Sn/Dn` -> Compute the square root of Sn/Dn and store the result in Sd/Dd. +#[inline(always)] +fn fsqrt_freg_freg( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + dst: AArch64FloatReg, + src: AArch64FloatReg, +) { + let inst = + FloatingPointDataProcessingOneSource::new(FloatingPointDataProcessingOneSourceParams { + opcode: 0b000011, + ptype: ftype, + rd: dst, + rn: src, + }); + + buf.extend(inst.bytes()); +} + +/// Currently, we're only using MOVI to set a float register to 0.0. +/// `MOVI Dd, #0.0` -> Move 0.0 to Dd +#[inline(always)] +fn movi_freg_zero(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg) { + let inst = AdvancedSimdModifiedImmediate::new(dst); + + buf.extend(inst.bytes()); +} + +/// `SCVTF Sd/Dd, Xn` -> Convert Xn to a float and store the result in Sd/Dd. +#[inline(always)] +fn scvtf_freg_reg64( + buf: &mut Vec<'_, u8>, + ftype: FloatWidth, + dst: AArch64FloatReg, + src: AArch64GeneralReg, +) { + let inst = ConversionBetweenFloatingPointAndInteger::new( + ConversionBetweenFloatingPointAndIntegerParams { + opcode: 0b010, + rmode: 0b00, + ptype: ftype, + rd: dst, + rn: src, + }, + ); + + buf.extend(inst.bytes()); +} + #[cfg(test)] mod tests { use super::*; @@ -2332,6 +3044,15 @@ mod tests { } } + impl AArch64FloatReg { + fn capstone_string(&self, float_type: FloatWidth) -> String { + match float_type { + FloatWidth::F32 => format!("s{}", self.id()), + FloatWidth::F64 => format!("d{}", self.id()), + } + } + } + const TEST_U16: u16 = 0x1234; //const TEST_I32: i32 = 0x12345678; //const TEST_I64: i64 = 0x12345678_9ABCDEF0; @@ -2371,6 +3092,43 @@ mod tests { AArch64GeneralReg::ZRSP, ]; + const ALL_FLOAT_REGS: &[AArch64FloatReg] = &[ + AArch64FloatReg::V0, + AArch64FloatReg::V1, + AArch64FloatReg::V2, + AArch64FloatReg::V3, + AArch64FloatReg::V4, + AArch64FloatReg::V5, + AArch64FloatReg::V6, + AArch64FloatReg::V7, + AArch64FloatReg::V8, + AArch64FloatReg::V9, + AArch64FloatReg::V10, + AArch64FloatReg::V11, + AArch64FloatReg::V12, + AArch64FloatReg::V13, + AArch64FloatReg::V14, + AArch64FloatReg::V15, + AArch64FloatReg::V16, + AArch64FloatReg::V17, + AArch64FloatReg::V18, + AArch64FloatReg::V19, + AArch64FloatReg::V20, + AArch64FloatReg::V21, + AArch64FloatReg::V22, + AArch64FloatReg::V23, + AArch64FloatReg::V24, + AArch64FloatReg::V25, + AArch64FloatReg::V26, + AArch64FloatReg::V27, + AArch64FloatReg::V28, + AArch64FloatReg::V29, + AArch64FloatReg::V30, + AArch64FloatReg::V31, + ]; + + const ALL_FLOAT_TYPES: &[FloatWidth] = &[FloatWidth::F32, FloatWidth::F64]; + const ALL_CONDITIONS: &[ConditionCode] = &[ ConditionCode::EQ, ConditionCode::NE, @@ -3006,4 +3764,331 @@ mod tests { ALL_GENERAL_REGS ); } + + // Float instructions + + #[test] + fn test_fabs_freg_freg() { + disassembler_test!( + fabs_freg_freg, + |ftype: FloatWidth, reg1: AArch64FloatReg, reg2: AArch64FloatReg| format!( + "fabs {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(ftype) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_fadd_freg_freg_freg() { + disassembler_test!( + fadd_freg_freg_freg, + |ftype: FloatWidth, + reg1: AArch64FloatReg, + reg2: AArch64FloatReg, + reg3: AArch64FloatReg| format!( + "fadd {}, {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(ftype), + reg3.capstone_string(ftype) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_fcmp_freg_freg() { + disassembler_test!( + fcmp_freg_freg, + |ftype: FloatWidth, reg1: AArch64FloatReg, reg2: AArch64FloatReg| format!( + "fcmp {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(ftype) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_fcvt_freg32_freg64() { + disassembler_test!( + fcvt_freg32_freg64, + |reg1: AArch64FloatReg, reg2: AArch64FloatReg| format!( + "fcvt {}, {}", + reg1.capstone_string(FloatWidth::F32), + reg2.capstone_string(FloatWidth::F64) + ), + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_fcvt_freg64_freg32() { + disassembler_test!( + fcvt_freg64_freg32, + |reg1: AArch64FloatReg, reg2: AArch64FloatReg| format!( + "fcvt {}, {}", + reg1.capstone_string(FloatWidth::F64), + reg2.capstone_string(FloatWidth::F32) + ), + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_fdiv_freg_freg_freg() { + disassembler_test!( + fdiv_freg_freg_freg, + |ftype: FloatWidth, + reg1: AArch64FloatReg, + reg2: AArch64FloatReg, + reg3: AArch64FloatReg| format!( + "fdiv {}, {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(ftype), + reg3.capstone_string(ftype) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_fmov_freg_freg() { + disassembler_test!( + fmov_freg_freg, + |ftype: FloatWidth, reg1: AArch64FloatReg, reg2: AArch64FloatReg| format!( + "fmov {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(ftype) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + #[allow(clippy::unusual_byte_groupings)] + fn test_encode_f32_to_imm8() { + // See ARM manual Table C2-1: A64 Floating-point modified immediate constants + assert_eq!(encode_f32_to_imm8(2.0), Some(0b0_000_0000)); + assert_eq!(encode_f32_to_imm8(4.0), Some(0b0_001_0000)); + assert_eq!(encode_f32_to_imm8(8.0), Some(0b0_010_0000)); + assert_eq!(encode_f32_to_imm8(16.0), Some(0b0_011_0000)); + assert_eq!(encode_f32_to_imm8(0.125), Some(0b0_100_0000)); + assert_eq!(encode_f32_to_imm8(0.25), Some(0b0_101_0000)); + assert_eq!(encode_f32_to_imm8(0.5), Some(0b0_110_0000)); + assert_eq!(encode_f32_to_imm8(1.0), Some(0b0_111_0000)); + + assert_eq!(encode_f32_to_imm8(2.125), Some(0b0_000_0001)); + assert_eq!(encode_f32_to_imm8(2.25), Some(0b0_000_0010)); + assert_eq!(encode_f32_to_imm8(2.375), Some(0b0_000_0011)); + assert_eq!(encode_f32_to_imm8(2.5), Some(0b0_000_0100)); + assert_eq!(encode_f32_to_imm8(2.625), Some(0b0_000_0101)); + assert_eq!(encode_f32_to_imm8(2.75), Some(0b0_000_0110)); + assert_eq!(encode_f32_to_imm8(2.875), Some(0b0_000_0111)); + assert_eq!(encode_f32_to_imm8(3.0), Some(0b0_000_1000)); + assert_eq!(encode_f32_to_imm8(3.125), Some(0b0_000_1001)); + assert_eq!(encode_f32_to_imm8(3.25), Some(0b0_000_1010)); + assert_eq!(encode_f32_to_imm8(3.375), Some(0b0_000_1011)); + assert_eq!(encode_f32_to_imm8(3.5), Some(0b0_000_1100)); + assert_eq!(encode_f32_to_imm8(3.625), Some(0b0_000_1101)); + assert_eq!(encode_f32_to_imm8(3.75), Some(0b0_000_1110)); + assert_eq!(encode_f32_to_imm8(3.875), Some(0b0_000_1111)); + + assert_eq!(encode_f32_to_imm8(-2.0), Some(0b1_000_0000)); + assert_eq!(encode_f32_to_imm8(-0.25), Some(0b1_101_0000)); + assert_eq!(encode_f32_to_imm8(-2.5), Some(0b1_000_0100)); + assert_eq!(encode_f32_to_imm8(-3.375), Some(0b1_000_1011)); + + assert_eq!(encode_f32_to_imm8(1.9375), Some(0b0_111_1111)); + assert_eq!(encode_f32_to_imm8(-1.9375), Some(0b1_111_1111)); + + assert_eq!(encode_f32_to_imm8(23.0), Some(0b0_011_0111)); + assert_eq!(encode_f32_to_imm8(-23.0), Some(0b1_011_0111)); + + assert_eq!(encode_f32_to_imm8(0.0), None); + assert_eq!(encode_f32_to_imm8(-0.0), None); + assert_eq!(encode_f32_to_imm8(32.0), None); + assert_eq!(encode_f32_to_imm8(-32.0), None); + assert_eq!(encode_f32_to_imm8(0.0625), None); + assert_eq!(encode_f32_to_imm8(-0.0625), None); + assert_eq!(encode_f32_to_imm8(0.3), None); + assert_eq!(encode_f32_to_imm8(-0.3), None); + } + + #[test] + #[allow(clippy::unusual_byte_groupings)] + fn test_encode_f64_to_imm8() { + // See ARM manual Table C2-1: A64 Floating-point modified immediate constants + assert_eq!(encode_f64_to_imm8(2.0), Some(0b0_000_0000)); + assert_eq!(encode_f64_to_imm8(4.0), Some(0b0_001_0000)); + assert_eq!(encode_f64_to_imm8(8.0), Some(0b0_010_0000)); + assert_eq!(encode_f64_to_imm8(16.0), Some(0b0_011_0000)); + assert_eq!(encode_f64_to_imm8(0.125), Some(0b0_100_0000)); + assert_eq!(encode_f64_to_imm8(0.25), Some(0b0_101_0000)); + assert_eq!(encode_f64_to_imm8(0.5), Some(0b0_110_0000)); + assert_eq!(encode_f64_to_imm8(1.0), Some(0b0_111_0000)); + + assert_eq!(encode_f64_to_imm8(2.125), Some(0b0_000_0001)); + assert_eq!(encode_f64_to_imm8(2.25), Some(0b0_000_0010)); + assert_eq!(encode_f64_to_imm8(2.375), Some(0b0_000_0011)); + assert_eq!(encode_f64_to_imm8(2.5), Some(0b0_000_0100)); + assert_eq!(encode_f64_to_imm8(2.625), Some(0b0_000_0101)); + assert_eq!(encode_f64_to_imm8(2.75), Some(0b0_000_0110)); + assert_eq!(encode_f64_to_imm8(2.875), Some(0b0_000_0111)); + assert_eq!(encode_f64_to_imm8(3.0), Some(0b0_000_1000)); + assert_eq!(encode_f64_to_imm8(3.125), Some(0b0_000_1001)); + assert_eq!(encode_f64_to_imm8(3.25), Some(0b0_000_1010)); + assert_eq!(encode_f64_to_imm8(3.375), Some(0b0_000_1011)); + assert_eq!(encode_f64_to_imm8(3.5), Some(0b0_000_1100)); + assert_eq!(encode_f64_to_imm8(3.625), Some(0b0_000_1101)); + assert_eq!(encode_f64_to_imm8(3.75), Some(0b0_000_1110)); + assert_eq!(encode_f64_to_imm8(3.875), Some(0b0_000_1111)); + + assert_eq!(encode_f64_to_imm8(-2.0), Some(0b1_000_0000)); + assert_eq!(encode_f64_to_imm8(-0.25), Some(0b1_101_0000)); + assert_eq!(encode_f64_to_imm8(-2.5), Some(0b1_000_0100)); + assert_eq!(encode_f64_to_imm8(-3.375), Some(0b1_000_1011)); + + assert_eq!(encode_f64_to_imm8(1.9375), Some(0b0_111_1111)); + assert_eq!(encode_f64_to_imm8(-1.9375), Some(0b1_111_1111)); + + assert_eq!(encode_f64_to_imm8(23.0), Some(0b0_011_0111)); + assert_eq!(encode_f64_to_imm8(-23.0), Some(0b1_011_0111)); + + assert_eq!(encode_f64_to_imm8(0.0), None); + assert_eq!(encode_f64_to_imm8(-0.0), None); + assert_eq!(encode_f64_to_imm8(32.0), None); + assert_eq!(encode_f64_to_imm8(-32.0), None); + assert_eq!(encode_f64_to_imm8(0.0625), None); + assert_eq!(encode_f64_to_imm8(-0.0625), None); + assert_eq!(encode_f64_to_imm8(0.3), None); + assert_eq!(encode_f64_to_imm8(-0.3), None); + } + + #[test] + fn test_fmov_freg_imm8() { + disassembler_test!( + |buf: &mut Vec<'_, u8>, ftype: FloatWidth, dst: AArch64FloatReg, imm: f32| { + // We need to encode the float immediate to 8 bits first. + let encoded = match ftype { + FloatWidth::F32 => encode_f32_to_imm8(imm), + FloatWidth::F64 => encode_f64_to_imm8(imm as f64), + }; + fmov_freg_imm8(buf, ftype, dst, encoded.unwrap()) + }, + |ftype: FloatWidth, reg: AArch64FloatReg, imm: f32| format!( + "fmov {}, #{:.8}", + reg.capstone_string(ftype), + imm + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + [ + // These are all of the possible values that can be encoded in an 8-bit float immediate. + // See ARM manual Table C2-1: A64 Floating-point modified immediate constants. + 2.0, 4.0, 8.0, 16.0, 0.125, 0.25, 0.5, 1.0, 2.125, 4.25, 8.5, 17.0, 0.1328125, + 0.265625, 0.53125, 1.0625, 2.25, 4.5, 9.0, 18.0, 0.140625, 0.28125, 0.5625, 1.125, + 2.375, 4.75, 9.5, 19.0, 0.1484375, 0.296875, 0.59375, 1.1875, 2.5, 5.0, 10.0, 20.0, + 0.15625, 0.3125, 0.625, 1.25, 2.625, 5.25, 10.5, 21.0, 0.1640625, 0.328125, + 0.65625, 1.3125, 2.75, 5.5, 11.0, 22.0, 0.171875, 0.34375, 0.6875, 1.375, 2.875, + 5.75, 11.5, 23.0, 0.1796875, 0.359375, 0.71875, 1.4375, 3.0, 6.0, 12.0, 24.0, + 0.1875, 0.375, 0.75, 1.5, 3.125, 6.25, 12.5, 25.0, 0.1953125, 0.390625, 0.78125, + 1.5625, 3.25, 6.5, 13.0, 26.0, 0.203125, 0.40625, 0.8125, 1.625, 3.375, 6.75, 13.5, + 27.0, 0.2109375, 0.421875, 0.84375, 1.6875, 3.5, 7.0, 14.0, 28.0, 0.21875, 0.4375, + 0.875, 1.75, 3.625, 7.25, 14.5, 29.0, 0.2265625, 0.453125, 0.90625, 1.8125, 3.75, + 7.5, 15.0, 30.0, 0.234375, 0.46875, 0.9375, 1.875, 3.875, 7.75, 15.5, 31.0, + 0.2421875, 0.484375, 0.96875, 1.9375, -2.0, -4.0, -8.0, -16.0, -0.125, -0.25, -0.5, + -1.0, -2.125, -4.25, -8.5, -17.0, -0.1328125, -0.265625, -0.53125, -1.0625, -2.25, + -4.5, -9.0, -18.0, -0.140625, -0.28125, -0.5625, -1.125, -2.375, -4.75, -9.5, + -19.0, -0.1484375, -0.296875, -0.59375, -1.1875, -2.5, -5.0, -10.0, -20.0, + -0.15625, -0.3125, -0.625, -1.25, -2.625, -5.25, -10.5, -21.0, -0.1640625, + -0.328125, -0.65625, -1.3125, -2.75, -5.5, -11.0, -22.0, -0.171875, -0.34375, + -0.6875, -1.375, -2.875, -5.75, -11.5, -23.0, -0.1796875, -0.359375, -0.71875, + -1.4375, -3.0, -6.0, -12.0, -24.0, -0.1875, -0.375, -0.75, -1.5, -3.125, -6.25, + -12.5, -25.0, -0.1953125, -0.390625, -0.78125, -1.5625, -3.25, -6.5, -13.0, -26.0, + -0.203125, -0.40625, -0.8125, -1.625, -3.375, -6.75, -13.5, -27.0, -0.2109375, + -0.421875, -0.84375, -1.6875, -3.5, -7.0, -14.0, -28.0, -0.21875, -0.4375, -0.875, + -1.75, -3.625, -7.25, -14.5, -29.0, -0.2265625, -0.453125, -0.90625, -1.8125, + -3.75, -7.5, -15.0, -30.0, -0.234375, -0.46875, -0.9375, -1.875, -3.875, -7.75, + -15.5, -31.0, -0.2421875, -0.484375, -0.96875, -1.9375, + ] + ); + } + + #[test] + fn test_fmul_freg_freg_freg() { + disassembler_test!( + fmul_freg_freg_freg, + |ftype: FloatWidth, + reg1: AArch64FloatReg, + reg2: AArch64FloatReg, + reg3: AArch64FloatReg| format!( + "fmul {}, {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(ftype), + reg3.capstone_string(ftype) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_fsqrt_freg_freg() { + disassembler_test!( + fsqrt_freg_freg, + |ftype: FloatWidth, reg1: AArch64FloatReg, reg2: AArch64FloatReg| format!( + "fsqrt {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(ftype) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_movi_freg_zero() { + disassembler_test!( + movi_freg_zero, + |reg: AArch64FloatReg| format!( + "movi {}, #0000000000000000", + reg.capstone_string(FloatWidth::F64) + ), + ALL_FLOAT_REGS + ); + } + + #[test] + fn test_scvtf_freg_reg64() { + disassembler_test!( + scvtf_freg_reg64, + |ftype: FloatWidth, reg1: AArch64FloatReg, reg2: AArch64GeneralReg| format!( + "scvtf {}, {}", + reg1.capstone_string(ftype), + reg2.capstone_string(UsesZR) + ), + ALL_FLOAT_TYPES, + ALL_FLOAT_REGS, + ALL_GENERAL_REGS + ); + } } diff --git a/crates/compiler/gen_dev/src/generic64/mod.rs b/crates/compiler/gen_dev/src/generic64/mod.rs index da0970b490..fa87c1719f 100644 --- a/crates/compiler/gen_dev/src/generic64/mod.rs +++ b/crates/compiler/gen_dev/src/generic64/mod.rs @@ -62,15 +62,15 @@ pub trait CallConv( - buf: &mut Vec<'a, u8>, + fn setup_stack( + buf: &mut Vec<'_, u8>, general_saved_regs: &[GeneralReg], float_saved_regs: &[FloatReg], requested_stack_size: i32, fn_call_stack_size: i32, ) -> i32; - fn cleanup_stack<'a>( - buf: &mut Vec<'a, u8>, + fn cleanup_stack( + buf: &mut Vec<'_, u8>, general_saved_regs: &[GeneralReg], float_saved_regs: &[FloatReg], aligned_stack_size: i32, @@ -78,9 +78,9 @@ pub trait CallConv( + fn load_args<'a>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, Self>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, Self>, layout_interner: &mut STLayoutInterner<'a>, args: &'a [(InLayout<'a>, Symbol)], // ret_layout is needed because if it is a complex type, we pass a pointer as the first arg. @@ -89,9 +89,9 @@ pub trait CallConv( + fn store_args<'a>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, Self>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, Self>, layout_interner: &mut STLayoutInterner<'a>, dst: &Symbol, args: &[Symbol], @@ -102,9 +102,9 @@ pub trait CallConv( + fn return_complex_symbol<'a>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, Self>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, Self>, layout_interner: &mut STLayoutInterner<'a>, sym: &Symbol, layout: &InLayout<'a>, @@ -112,9 +112,9 @@ pub trait CallConv( + fn load_returned_complex_symbol<'a>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, Self>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, Self>, layout_interner: &mut STLayoutInterner<'a>, sym: &Symbol, layout: &InLayout<'a>, @@ -184,9 +184,9 @@ pub trait Assembler: Sized + Copy { src2: GeneralReg, ); - fn shl_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn shl_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>, dst: GeneralReg, src1: GeneralReg, src2: GeneralReg, @@ -194,9 +194,9 @@ pub trait Assembler: Sized + Copy { ASM: Assembler, CC: CallConv; - fn shr_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn shr_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>, dst: GeneralReg, src1: GeneralReg, src2: GeneralReg, @@ -204,9 +204,9 @@ pub trait Assembler: Sized + Copy { ASM: Assembler, CC: CallConv; - fn sar_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn sar_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>, dst: GeneralReg, src1: GeneralReg, src2: GeneralReg, @@ -359,9 +359,9 @@ pub trait Assembler: Sized + Copy { src1: GeneralReg, src2: GeneralReg, ); - fn umul_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn umul_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>, dst: GeneralReg, src1: GeneralReg, src2: GeneralReg, @@ -369,18 +369,18 @@ pub trait Assembler: Sized + Copy { ASM: Assembler, CC: CallConv; - fn idiv_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn idiv_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>, dst: GeneralReg, src1: GeneralReg, src2: GeneralReg, ) where ASM: Assembler, CC: CallConv; - fn udiv_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn udiv_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, GeneralReg, FloatReg, ASM, CC>, dst: GeneralReg, src1: GeneralReg, src2: GeneralReg, @@ -1776,7 +1776,7 @@ impl< self.storage_manager.with_tmp_general_reg( &mut self.buf, |storage_manager, buf, list_ptr| { - ASM::mov_reg64_base32(buf, list_ptr, base_offset as i32); + ASM::mov_reg64_base32(buf, list_ptr, base_offset); storage_manager.with_tmp_general_reg(buf, |storage_manager, buf, tmp| { // calculate `element_width * index` ASM::mov_reg64_imm64(buf, tmp, ret_stack_size as i64); diff --git a/crates/compiler/gen_dev/src/generic64/x86_64.rs b/crates/compiler/gen_dev/src/generic64/x86_64.rs index 1ff34eb546..95c2e63758 100644 --- a/crates/compiler/gen_dev/src/generic64/x86_64.rs +++ b/crates/compiler/gen_dev/src/generic64/x86_64.rs @@ -216,8 +216,8 @@ impl CallConv for X86_64Syste } #[inline(always)] - fn setup_stack<'a>( - buf: &mut Vec<'a, u8>, + fn setup_stack( + buf: &mut Vec<'_, u8>, saved_general_regs: &[X86_64GeneralReg], saved_float_regs: &[X86_64FloatReg], requested_stack_size: i32, @@ -233,8 +233,8 @@ impl CallConv for X86_64Syste } #[inline(always)] - fn cleanup_stack<'a>( - buf: &mut Vec<'a, u8>, + fn cleanup_stack( + buf: &mut Vec<'_, u8>, saved_general_regs: &[X86_64GeneralReg], saved_float_regs: &[X86_64FloatReg], aligned_stack_size: i32, @@ -250,11 +250,11 @@ impl CallConv for X86_64Syste } #[inline(always)] - fn load_args<'a, 'r>( + fn load_args<'a>( _buf: &mut Vec<'a, u8>, storage_manager: &mut StorageManager< 'a, - 'r, + '_, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, @@ -284,11 +284,11 @@ impl CallConv for X86_64Syste } #[inline(always)] - fn store_args<'a, 'r>( + fn store_args<'a>( buf: &mut Vec<'a, u8>, storage_manager: &mut StorageManager< 'a, - 'r, + '_, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, @@ -330,11 +330,11 @@ impl CallConv for X86_64Syste storage_manager.update_fn_call_stack_size(state.tmp_stack_offset as u32); } - fn return_complex_symbol<'a, 'r>( + fn return_complex_symbol<'a>( buf: &mut Vec<'a, u8>, storage_manager: &mut StorageManager< 'a, - 'r, + '_, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, @@ -388,11 +388,11 @@ impl CallConv for X86_64Syste } } - fn load_returned_complex_symbol<'a, 'r>( + fn load_returned_complex_symbol<'a>( buf: &mut Vec<'a, u8>, storage_manager: &mut StorageManager< 'a, - 'r, + '_, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, @@ -447,10 +447,10 @@ impl X64_64SystemVStoreArgs { const FLOAT_PARAM_REGS: &'static [X86_64FloatReg] = X86_64SystemV::FLOAT_PARAM_REGS; const FLOAT_RETURN_REGS: &'static [X86_64FloatReg] = X86_64SystemV::FLOAT_RETURN_REGS; - fn store_arg<'a, 'r>( + fn store_arg<'a>( &mut self, buf: &mut Vec<'a, u8>, - storage_manager: &mut X86_64StorageManager<'a, 'r, X86_64SystemV>, + storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>, layout_interner: &mut STLayoutInterner<'a>, sym: Symbol, in_layout: InLayout<'a>, @@ -537,10 +537,10 @@ impl X64_64SystemVStoreArgs { } } - fn store_arg_general<'a, 'r>( + fn store_arg_general<'a>( &mut self, buf: &mut Vec<'a, u8>, - storage_manager: &mut X86_64StorageManager<'a, 'r, X86_64SystemV>, + storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>, sym: Symbol, ) { if self.general_i < Self::GENERAL_PARAM_REGS.len() { @@ -562,10 +562,10 @@ impl X64_64SystemVStoreArgs { } } - fn store_arg_float<'a, 'r>( + fn store_arg_float<'a>( &mut self, buf: &mut Vec<'a, u8>, - storage_manager: &mut X86_64StorageManager<'a, 'r, X86_64SystemV>, + storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>, sym: Symbol, ) { if self.float_i < Self::FLOAT_PARAM_REGS.len() { @@ -598,9 +598,9 @@ type X86_64StorageManager<'a, 'r, CallConv> = StorageManager<'a, 'r, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, CallConv>; impl X64_64SystemVLoadArgs { - fn load_arg<'a, 'r>( + fn load_arg<'a>( &mut self, - storage_manager: &mut X86_64StorageManager<'a, 'r, X86_64SystemV>, + storage_manager: &mut X86_64StorageManager<'a, '_, X86_64SystemV>, layout_interner: &mut STLayoutInterner<'a>, sym: Symbol, in_layout: InLayout<'a>, @@ -645,9 +645,9 @@ impl X64_64SystemVLoadArgs { } } - fn load_arg_general<'a, 'r>( + fn load_arg_general( &mut self, - storage_manager: &mut X86_64StorageManager<'a, 'r, X86_64SystemV>, + storage_manager: &mut X86_64StorageManager<'_, '_, X86_64SystemV>, sym: Symbol, ) { if self.general_i < X86_64SystemV::GENERAL_PARAM_REGS.len() { @@ -660,9 +660,9 @@ impl X64_64SystemVLoadArgs { } } - fn load_arg_float<'a, 'r>( + fn load_arg_float( &mut self, - storage_manager: &mut X86_64StorageManager<'a, 'r, X86_64SystemV>, + storage_manager: &mut X86_64StorageManager<'_, '_, X86_64SystemV>, sym: Symbol, ) { if self.general_i < X86_64SystemV::GENERAL_PARAM_REGS.len() { @@ -783,8 +783,8 @@ impl CallConv for X86_64Windo } #[inline(always)] - fn setup_stack<'a>( - buf: &mut Vec<'a, u8>, + fn setup_stack( + buf: &mut Vec<'_, u8>, saved_general_regs: &[X86_64GeneralReg], saved_float_regs: &[X86_64FloatReg], requested_stack_size: i32, @@ -800,8 +800,8 @@ impl CallConv for X86_64Windo } #[inline(always)] - fn cleanup_stack<'a>( - buf: &mut Vec<'a, u8>, + fn cleanup_stack( + buf: &mut Vec<'_, u8>, saved_general_regs: &[X86_64GeneralReg], saved_float_regs: &[X86_64FloatReg], aligned_stack_size: i32, @@ -817,9 +817,9 @@ impl CallConv for X86_64Windo } #[inline(always)] - fn load_args<'a, 'r>( + fn load_args<'a>( _buf: &mut Vec<'a, u8>, - storage_manager: &mut X86_64StorageManager<'a, 'r, X86_64WindowsFastcall>, + storage_manager: &mut X86_64StorageManager<'a, '_, X86_64WindowsFastcall>, layout_interner: &mut STLayoutInterner<'a>, args: &'a [(InLayout<'a>, Symbol)], ret_layout: &InLayout<'a>, @@ -861,11 +861,11 @@ impl CallConv for X86_64Windo } #[inline(always)] - fn store_args<'a, 'r>( + fn store_args<'a>( buf: &mut Vec<'a, u8>, storage_manager: &mut StorageManager< 'a, - 'r, + '_, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, @@ -938,11 +938,11 @@ impl CallConv for X86_64Windo storage_manager.update_fn_call_stack_size(tmp_stack_offset as u32); } - fn return_complex_symbol<'a, 'r>( + fn return_complex_symbol<'a>( _buf: &mut Vec<'a, u8>, _storage_manager: &mut StorageManager< 'a, - 'r, + '_, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, @@ -955,11 +955,11 @@ impl CallConv for X86_64Windo todo!("Returning complex symbols for X86_64"); } - fn load_returned_complex_symbol<'a, 'r>( + fn load_returned_complex_symbol<'a>( _buf: &mut Vec<'a, u8>, _storage_manager: &mut StorageManager< 'a, - 'r, + '_, X86_64GeneralReg, X86_64FloatReg, X86_64Assembler, @@ -985,8 +985,8 @@ impl X86_64WindowsFastcall { } #[inline(always)] -fn x86_64_generic_setup_stack<'a>( - buf: &mut Vec<'a, u8>, +fn x86_64_generic_setup_stack( + buf: &mut Vec<'_, u8>, saved_general_regs: &[X86_64GeneralReg], saved_float_regs: &[X86_64FloatReg], requested_stack_size: i32, @@ -1042,8 +1042,8 @@ fn x86_64_generic_setup_stack<'a>( #[inline(always)] #[allow(clippy::unnecessary_wraps)] -fn x86_64_generic_cleanup_stack<'a>( - buf: &mut Vec<'a, u8>, +fn x86_64_generic_cleanup_stack( + buf: &mut Vec<'_, u8>, saved_general_regs: &[X86_64GeneralReg], saved_float_regs: &[X86_64FloatReg], aligned_stack_size: i32, @@ -1183,9 +1183,9 @@ impl Assembler for X86_64Assembler { imul_reg64_reg64(buf, dst, src2); } - fn umul_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn umul_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, dst: X86_64GeneralReg, src1: X86_64GeneralReg, src2: X86_64GeneralReg, @@ -1267,9 +1267,9 @@ impl Assembler for X86_64Assembler { } } - fn idiv_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn idiv_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, dst: X86_64GeneralReg, src1: X86_64GeneralReg, src2: X86_64GeneralReg, @@ -1287,9 +1287,9 @@ impl Assembler for X86_64Assembler { mov_reg64_reg64(buf, dst, X86_64GeneralReg::RAX); } - fn udiv_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn udiv_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, dst: X86_64GeneralReg, src1: X86_64GeneralReg, src2: X86_64GeneralReg, @@ -1734,9 +1734,9 @@ impl Assembler for X86_64Assembler { binop_move_src_to_dst_reg64(buf, xor_reg64_reg64, dst, src1, src2) } - fn shl_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn shl_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, dst: X86_64GeneralReg, src1: X86_64GeneralReg, src2: X86_64GeneralReg, @@ -1747,9 +1747,9 @@ impl Assembler for X86_64Assembler { shift_reg64_reg64_reg64(buf, storage_manager, shl_reg64_reg64, dst, src1, src2) } - fn shr_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn shr_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, dst: X86_64GeneralReg, src1: X86_64GeneralReg, src2: X86_64GeneralReg, @@ -1760,9 +1760,9 @@ impl Assembler for X86_64Assembler { shift_reg64_reg64_reg64(buf, storage_manager, shr_reg64_reg64, dst, src1, src2) } - fn sar_reg64_reg64_reg64<'a, 'r, ASM, CC>( + fn sar_reg64_reg64_reg64<'a, ASM, CC>( buf: &mut Vec<'a, u8>, - storage_manager: &mut StorageManager<'a, 'r, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, + storage_manager: &mut StorageManager<'a, '_, X86_64GeneralReg, X86_64FloatReg, ASM, CC>, dst: X86_64GeneralReg, src1: X86_64GeneralReg, src2: X86_64GeneralReg, diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index 3c05f0611d..327290bb21 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -885,7 +885,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> { self.code_builder.f32_eq(); } ValueType::F64 => { - self.code_builder.f64_const(f64::from_bits(*value as u64)); + self.code_builder.f64_const(f64::from_bits(*value)); self.code_builder.f64_eq(); } } @@ -1114,7 +1114,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> { match storage { StoredValue::VirtualMachineStack { value_type, .. } => { match (lit, value_type) { - (Literal::Float(x), ValueType::F64) => self.code_builder.f64_const(*x as f64), + (Literal::Float(x), ValueType::F64) => self.code_builder.f64_const(*x), (Literal::Float(x), ValueType::F32) => self.code_builder.f32_const(*x as f32), (Literal::Int(x), ValueType::I64) => { self.code_builder.i64_const(i128::from_ne_bytes(*x) as i64) diff --git a/crates/compiler/gen_wasm/src/code_builder.rs b/crates/compiler/gen_wasm/src/code_builder.rs index ddb6c6cd5b..92912f0d01 100644 --- a/crates/compiler/gen_wasm/src/code_builder.rs +++ b/crates/compiler/gen_wasm/src/code_builder.rs @@ -506,7 +506,7 @@ impl<'a> CodeBuilder<'a> { stack_size ); - let new_len = stack_size - pops as usize; + let new_len = stack_size - pops; current_stack.truncate(new_len); if push { current_stack.push(Symbol::WASM_TMP); diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index b3205e615f..722f8b0f7e 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -2347,8 +2347,8 @@ macro_rules! debug_check_ir { } /// Report modules that are imported, but from which nothing is used -fn report_unused_imported_modules<'a>( - state: &mut State<'a>, +fn report_unused_imported_modules( + state: &mut State<'_>, module_id: ModuleId, constrained_module: &ConstrainedModule, ) { diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index 7ceaf869e9..0ecb3e7f65 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -1253,6 +1253,7 @@ define_builtins! { 152 NUM_COUNT_LEADING_ZERO_BITS: "countLeadingZeroBits" 153 NUM_COUNT_TRAILING_ZERO_BITS: "countTrailingZeroBits" 154 NUM_COUNT_ONE_BITS: "countOneBits" + 155 NUM_ABS_DIFF: "absDiff" } 4 BOOL: "Bool" => { 0 BOOL_BOOL: "Bool" exposed_type=true // the Bool.Bool type alias diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index e2b644ec00..75188b666f 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -25,9 +25,9 @@ use crate::{ /** Insert the reference count operations for procedures. */ -pub fn insert_inc_dec_operations<'a, 'i>( +pub fn insert_inc_dec_operations<'a>( arena: &'a Bump, - layout_interner: &'i STLayoutInterner<'a>, + layout_interner: &STLayoutInterner<'a>, procedures: &mut HashMap<(Symbol, ProcLayout), Proc<'a>, BuildHasherDefault>, ) { // Create a SymbolRcTypesEnv for the procedures as they get referenced but should be marked as non reference counted. @@ -401,9 +401,9 @@ impl<'v> RefcountEnvironment<'v> { /** Insert the reference counting operations into a statement. */ -fn insert_inc_dec_operations_proc<'a, 'i>( +fn insert_inc_dec_operations_proc<'a>( arena: &'a Bump, - mut symbol_rc_types_env: SymbolRcTypesEnv<'a, 'i>, + mut symbol_rc_types_env: SymbolRcTypesEnv<'a, '_>, proc: &mut Proc<'a>, ) { // Clone the symbol_rc_types_env and insert the symbols in the current procedure. diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index af41bb0ca0..dec90edf26 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -279,8 +279,9 @@ impl AbilityAliases { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] pub enum CapturedSymbols<'a> { + #[default] None, Captured(&'a [(Symbol, Variable)]), } @@ -294,12 +295,6 @@ impl<'a> CapturedSymbols<'a> { } } -impl<'a> Default for CapturedSymbols<'a> { - fn default() -> Self { - CapturedSymbols::None - } -} - #[derive(Clone, Debug, PartialEq)] pub struct Proc<'a> { pub name: LambdaName<'a>, @@ -2722,8 +2717,8 @@ fn patterns_to_when<'a>( /// { x } -> body /// /// conversion of one-pattern when expressions will do the most optimal thing -fn pattern_to_when<'a>( - env: &mut Env<'a, '_>, +fn pattern_to_when( + env: &mut Env<'_, '_>, pattern_var: Variable, pattern: Loc, body_var: Variable, @@ -5740,8 +5735,8 @@ fn compile_struct_like<'a, L, UnusedLayout>( } #[inline(always)] -fn late_resolve_ability_specialization<'a>( - env: &mut Env<'a, '_>, +fn late_resolve_ability_specialization( + env: &mut Env<'_, '_>, member: Symbol, specialization_id: Option, specialization_var: Variable, diff --git a/crates/compiler/mono/src/ir/decision_tree.rs b/crates/compiler/mono/src/ir/decision_tree.rs index c5c1a48425..dea1bba167 100644 --- a/crates/compiler/mono/src/ir/decision_tree.rs +++ b/crates/compiler/mono/src/ir/decision_tree.rs @@ -1193,7 +1193,7 @@ fn extract<'a>( /// FIND IRRELEVANT BRANCHES -fn is_irrelevant_to<'a>(selected_path: &[PathInstruction], branch: &Branch<'a>) -> bool { +fn is_irrelevant_to(selected_path: &[PathInstruction], branch: &Branch<'_>) -> bool { match branch .patterns .iter() @@ -1720,7 +1720,7 @@ fn test_to_comparison<'a>( Test::IsFloat(test_int, precision) => { // TODO maybe we can actually use i64 comparison here? - let test_float = f64::from_bits(test_int as u64); + let test_float = f64::from_bits(test_int); let lhs = Expr::Literal(Literal::Float(test_float)); let lhs_symbol = env.unique_symbol(); stores.push((lhs_symbol, Layout::float_width(precision), lhs)); @@ -2240,7 +2240,7 @@ fn decide_to_branching<'a>( let tag = match test { Test::IsInt(v, _) => i128::from_ne_bytes(v) as u64, - Test::IsFloat(v, _) => v as u64, + Test::IsFloat(v, _) => v, Test::IsBit(v) => v as u64, Test::IsByte { tag_id, .. } => tag_id as u64, Test::IsCtor { tag_id, .. } => tag_id as u64, diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index a90a275234..bcd07d254e 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -457,7 +457,7 @@ macro_rules! cached { } pub type TagIdIntType = u16; -pub const MAX_ENUM_SIZE: usize = (std::mem::size_of::() * 8) as usize; +pub const MAX_ENUM_SIZE: usize = std::mem::size_of::() * 8; const GENERATE_NULLABLE: bool = true; #[derive(Debug, Clone, Copy)] @@ -898,7 +898,7 @@ impl<'a> UnionLayout<'a> { } => { debug_assert_ne!(nullable_id, tag_id != 0); - other_fields[index as usize] + other_fields[index] } }; diff --git a/crates/compiler/mono/src/layout/intern.rs b/crates/compiler/mono/src/layout/intern.rs index 8f5b6b20ea..69b30d09e2 100644 --- a/crates/compiler/mono/src/layout/intern.rs +++ b/crates/compiler/mono/src/layout/intern.rs @@ -23,7 +23,7 @@ macro_rules! cache_interned_layouts { )* } - fn fill_reserved_layouts<'a>(interner: &mut STLayoutInterner<'a>) { + fn fill_reserved_layouts(interner: &mut STLayoutInterner<'_>) { assert!(interner.is_empty()); $( interner.insert($layout); diff --git a/crates/compiler/region/src/all.rs b/crates/compiler/region/src/all.rs index f2b188b104..9b556b76b4 100644 --- a/crates/compiler/region/src/all.rs +++ b/crates/compiler/region/src/all.rs @@ -105,14 +105,14 @@ impl Position { #[must_use] pub const fn bump_column(self, count: u32) -> Self { Self { - offset: self.offset + count as u32, + offset: self.offset + count, } } #[must_use] pub fn bump_invisible(self, count: u32) -> Self { Self { - offset: self.offset + count as u32, + offset: self.offset + count, } } @@ -126,7 +126,7 @@ impl Position { #[must_use] pub const fn sub(self, count: u32) -> Self { Self { - offset: self.offset - count as u32, + offset: self.offset - count, } } @@ -376,7 +376,7 @@ impl LineInfo { let column = offset - self.line_offsets[line]; LineColumn { line: line as u32, - column: column as u32, + column, } } diff --git a/crates/compiler/solve/src/solve.rs b/crates/compiler/solve/src/solve.rs index 349e8427dc..00a5b0d9a3 100644 --- a/crates/compiler/solve/src/solve.rs +++ b/crates/compiler/solve/src/solve.rs @@ -2537,14 +2537,14 @@ enum TypeToVar { } #[allow(clippy::too_many_arguments)] -fn type_to_variable<'a>( +fn type_to_variable( subs: &mut Subs, rank: Rank, pools: &mut Pools, problems: &mut Vec, abilities_store: &AbilitiesStore, obligation_cache: &mut ObligationCache, - arena: &'a bumpalo::Bump, + arena: &bumpalo::Bump, aliases: &mut Aliases, types: &mut Types, typ: Index, diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index c86499166a..58cf662de3 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -7,14 +7,10 @@ extern crate bumpalo; #[cfg(test)] mod solve_expr { - use roc_can::abilities::ImplKey; use roc_load::LoadedModule; use test_solve_helpers::{format_problems, run_load_and_infer}; - use roc_types::{ - pretty_print::{name_and_print_var, DebugPrint}, - types::MemberImpl, - }; + use roc_types::pretty_print::{name_and_print_var, DebugPrint}; // HELPERS @@ -92,73 +88,6 @@ mod solve_expr { assert_eq!(actual, expected.to_string()); } - fn check_inferred_abilities<'a, I>(src: &'a str, expected_specializations: I) - where - I: IntoIterator, - { - let LoadedModule { - module_id: home, - mut can_problems, - mut type_problems, - interns, - abilities_store, - .. - } = run_load_and_infer(src, [], false).unwrap().0; - - let can_problems = can_problems.remove(&home).unwrap_or_default(); - let type_problems = type_problems.remove(&home).unwrap_or_default(); - - assert_eq!(can_problems, Vec::new(), "Canonicalization problems: "); - - if !type_problems.is_empty() { - eprintln!("{:?}", type_problems); - panic!(); - } - - let known_specializations = abilities_store.iter_declared_implementations().filter_map( - |(impl_key, member_impl)| match member_impl { - MemberImpl::Impl(impl_symbol) => { - let specialization = abilities_store.specialization_info(*impl_symbol).expect( - "declared implementations should be resolved conclusively after solving", - ); - Some((impl_key, specialization.clone())) - } - MemberImpl::Error => None, - }, - ); - - use std::collections::HashSet; - let pretty_specializations = known_specializations - .into_iter() - .map(|(impl_key, _)| { - let ImplKey { - opaque, - ability_member, - } = impl_key; - let member_data = abilities_store.member_def(ability_member).unwrap(); - let member_str = ability_member.as_str(&interns); - let ability_str = member_data.parent_ability.as_str(&interns); - ( - format!("{}:{}", ability_str, member_str), - opaque.as_str(&interns), - ) - }) - .collect::>(); - - for (parent, specialization) in expected_specializations.into_iter() { - let has_the_one = pretty_specializations - .iter() - // references are annoying so we do this - .any(|(p, s)| p == parent && s == &specialization); - assert!( - has_the_one, - "{:#?} not in {:#?}", - (parent, specialization), - pretty_specializations, - ); - } - } - #[test] fn int_literal() { infer_eq("5", "Num *"); @@ -5209,1119 +5138,4 @@ mod solve_expr { r#"{ bi128 : I128 -> I128, bi16 : I16 -> I16, bi32 : I32 -> I32, bi64 : I64 -> I64, bi8 : I8 -> I8, bnat : Nat -> Nat, bu128 : U128 -> U128, bu16 : U16 -> U16, bu32 : U32 -> U32, bu64 : U64 -> U64, bu8 : U8 -> U8, dec : Dec -> Dec, f32 : F32 -> F32, f64 : F64 -> F64, fdec : Dec -> Dec, ff32 : F32 -> F32, ff64 : F64 -> F64, i128 : I128 -> I128, i16 : I16 -> I16, i32 : I32 -> I32, i64 : I64 -> I64, i8 : I8 -> I8, nat : Nat -> Nat, u128 : U128 -> U128, u16 : U16 -> U16, u32 : U32 -> U32, u64 : U64 -> U64, u8 : U8 -> U8 }"#, ) } - - #[test] - fn issue_2458() { - infer_eq_without_problem( - indoc!( - r#" - Foo a : [Blah (Result (Bar a) { val: a })] - Bar a : Foo a - - v : Bar U8 - v = Blah (Ok (Blah (Err { val: 1 }))) - - v - "# - ), - "Bar U8", - ) - } - - #[test] - fn issue_2458_swapped_order() { - infer_eq_without_problem( - indoc!( - r#" - Bar a : Foo a - Foo a : [Blah (Result (Bar a) { val: a })] - - v : Bar U8 - v = Blah (Ok (Blah (Err { val: 1 }))) - - v - "# - ), - "Bar U8", - ) - } - - // https://github.com/roc-lang/roc/issues/2379 - #[test] - fn copy_vars_referencing_copied_vars() { - infer_eq_without_problem( - indoc!( - r#" - Job : [Job [Command] (List Job)] - - job : Job - - job - "# - ), - "Job", - ) - } - - #[test] - fn generalize_and_specialize_recursion_var() { - infer_eq_without_problem( - indoc!( - r#" - Job a : [Job (List (Job a)) a] - - job : Job Str - - when job is - Job lst s -> P lst s - "# - ), - "[P (List ([Job (List a) Str] as a)) Str]", - ) - } - - #[test] - fn to_int() { - infer_eq_without_problem( - indoc!( - r#" - { - toI8: Num.toI8, - toI16: Num.toI16, - toI32: Num.toI32, - toI64: Num.toI64, - toI128: Num.toI128, - toNat: Num.toNat, - toU8: Num.toU8, - toU16: Num.toU16, - toU32: Num.toU32, - toU64: Num.toU64, - toU128: Num.toU128, - } - "# - ), - r#"{ toI128 : Int * -> I128, toI16 : Int a -> I16, toI32 : Int b -> I32, toI64 : Int c -> I64, toI8 : Int d -> I8, toNat : Int e -> Nat, toU128 : Int f -> U128, toU16 : Int g -> U16, toU32 : Int h -> U32, toU64 : Int i -> U64, toU8 : Int j -> U8 }"#, - ) - } - - #[test] - fn to_float() { - infer_eq_without_problem( - indoc!( - r#" - { - toF32: Num.toF32, - toF64: Num.toF64, - } - "# - ), - r#"{ toF32 : Num * -> F32, toF64 : Num a -> F64 }"#, - ) - } - - #[test] - fn opaque_wrap_infer() { - infer_eq_without_problem( - indoc!( - r#" - Age := U32 - - @Age 21 - "# - ), - r#"Age"#, - ) - } - - #[test] - fn opaque_wrap_check() { - infer_eq_without_problem( - indoc!( - r#" - Age := U32 - - a : Age - a = @Age 21 - - a - "# - ), - r#"Age"#, - ) - } - - #[test] - fn opaque_wrap_polymorphic_infer() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - @Id (Id 21 "sasha") - "# - ), - r#"Id Str"#, - ) - } - - #[test] - fn opaque_wrap_polymorphic_check() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - a : Id Str - a = @Id (Id 21 "sasha") - - a - "# - ), - r#"Id Str"#, - ) - } - - #[test] - fn opaque_wrap_polymorphic_from_multiple_branches_infer() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - condition : Bool - - if condition - then @Id (Id 21 (Y "sasha")) - else @Id (Id 21 (Z "felix")) - "# - ), - r#"Id [Y Str, Z Str]"#, - ) - } - - #[test] - fn opaque_wrap_polymorphic_from_multiple_branches_check() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - condition : Bool - - v : Id [Y Str, Z Str] - v = - if condition - then @Id (Id 21 (Y "sasha")) - else @Id (Id 21 (Z "felix")) - - v - "# - ), - r#"Id [Y Str, Z Str]"#, - ) - } - - #[test] - fn opaque_unwrap_infer() { - infer_eq_without_problem( - indoc!( - r#" - Age := U32 - - \@Age n -> n - "# - ), - r#"Age -> U32"#, - ) - } - - #[test] - fn opaque_unwrap_check() { - infer_eq_without_problem( - indoc!( - r#" - Age := U32 - - v : Age -> U32 - v = \@Age n -> n - v - "# - ), - r#"Age -> U32"#, - ) - } - - #[test] - fn opaque_unwrap_polymorphic_infer() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - \@Id (Id _ n) -> n - "# - ), - r#"Id a -> a"#, - ) - } - - #[test] - fn opaque_unwrap_polymorphic_check() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - v : Id a -> a - v = \@Id (Id _ n) -> n - - v - "# - ), - r#"Id a -> a"#, - ) - } - - #[test] - fn opaque_unwrap_polymorphic_specialized_infer() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - strToBool : Str -> Bool - - \@Id (Id _ n) -> strToBool n - "# - ), - r#"Id Str -> Bool"#, - ) - } - - #[test] - fn opaque_unwrap_polymorphic_specialized_check() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - strToBool : Str -> Bool - - v : Id Str -> Bool - v = \@Id (Id _ n) -> strToBool n - - v - "# - ), - r#"Id Str -> Bool"#, - ) - } - - #[test] - fn opaque_unwrap_polymorphic_from_multiple_branches_infer() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - \id -> - when id is - @Id (Id _ A) -> "" - @Id (Id _ B) -> "" - @Id (Id _ (C { a: "" })) -> "" - @Id (Id _ (C { a: _ })) -> "" # any other string, for exhautiveness - "# - ), - r#"Id [A, B, C { a : Str }*] -> Str"#, - ) - } - - #[test] - fn opaque_unwrap_polymorphic_from_multiple_branches_check() { - infer_eq_without_problem( - indoc!( - r#" - Id n := [Id U32 n] - - f : Id [A, B, C { a : Str }e] -> Str - f = \id -> - when id is - @Id (Id _ A) -> "" - @Id (Id _ B) -> "" - @Id (Id _ (C { a: "" })) -> "" - @Id (Id _ (C { a: _ })) -> "" # any other string, for exhautiveness - - f - "# - ), - r#"Id [A, B, C { a : Str }e] -> Str"#, - ) - } - - #[test] - fn lambda_set_within_alias_is_quantified() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [effectAlways] to "./platform" - - Effect a := {} -> a - - effectAlways : a -> Effect a - effectAlways = \x -> - inner = \{} -> x - - @Effect inner - "# - ), - r#"a -> Effect a"#, - ) - } - - #[test] - fn generalized_accessor_function_applied() { - infer_eq_without_problem( - indoc!( - r#" - returnFoo = .foo - - returnFoo { foo: "foo" } - "# - ), - "Str", - ) - } - - #[test] - fn record_extension_variable_is_alias() { - infer_eq_without_problem( - indoc!( - r#" - Other a b : { y: a, z: b } - - f : { x : Str }(Other Str Str) - f - "# - ), - r#"{ x : Str, y : Str, z : Str }"#, - ) - } - - #[test] - fn tag_extension_variable_is_alias() { - infer_eq_without_problem( - indoc!( - r#" - Other : [B, C] - - f : [A]Other - f - "# - ), - r#"[A, B, C]"#, - ) - } - - #[test] - // https://github.com/roc-lang/roc/issues/2702 - fn tag_inclusion_behind_opaque() { - infer_eq_without_problem( - indoc!( - r#" - Outer k := [Empty, Wrapped k] - - insert : Outer k, k -> Outer k - insert = \m, var -> - when m is - @Outer Empty -> @Outer (Wrapped var) - @Outer (Wrapped _) -> @Outer (Wrapped var) - - insert - "# - ), - r#"Outer k, k -> Outer k"#, - ) - } - - #[test] - fn tag_inclusion_behind_opaque_infer() { - infer_eq_without_problem( - indoc!( - r#" - Outer k := [Empty, Wrapped k] - - when (@Outer Empty) is - @Outer Empty -> @Outer (Wrapped "") - @Outer (Wrapped k) -> @Outer (Wrapped k) - "# - ), - r#"Outer Str"#, - ) - } - - #[test] - fn tag_inclusion_behind_opaque_infer_single_ctor() { - infer_eq_without_problem( - indoc!( - r#" - Outer := [A, B] - - when (@Outer A) is - @Outer A -> @Outer A - @Outer B -> @Outer B - "# - ), - r#"Outer"#, - ) - } - - #[test] - fn issue_2583_specialize_errors_behind_unified_branches() { - infer_eq_without_problem( - indoc!( - r#" - if Bool.true then List.first [] else Str.toI64 "" - "# - ), - "Result I64 [InvalidNumStr, ListWasEmpty]", - ) - } - - #[test] - fn lots_of_type_variables() { - infer_eq_without_problem( - indoc!( - r#" - fun = \a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb -> {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb} - fun - "# - ), - "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb -> { a : a, aa : aa, b : b, bb : bb, c : c, d : d, e : e, f : f, g : g, h : h, i : i, j : j, k : k, l : l, m : m, n : n, o : o, p : p, q : q, r : r, s : s, t : t, u : u, v : v, w : w, x : x, y : y, z : z }", - ) - } - - #[test] - fn exposed_ability_name() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [hash] to "./platform" - - MHash has hash : a -> U64 | a has MHash - "# - ), - "a -> U64 | a has MHash", - ) - } - - #[test] - fn single_ability_single_member_specializations() { - check_inferred_abilities( - indoc!( - r#" - app "test" provides [hash] to "./platform" - - MHash has hash : a -> U64 | a has MHash - - Id := U64 has [MHash {hash}] - - hash = \@Id n -> n - "# - ), - [("MHash:hash", "Id")], - ) - } - - #[test] - fn single_ability_multiple_members_specializations() { - check_inferred_abilities( - indoc!( - r#" - app "test" provides [hash, hash32] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - hash32 : a -> U32 | a has MHash - - Id := U64 has [MHash {hash, hash32}] - - hash = \@Id n -> n - hash32 = \@Id n -> Num.toU32 n - "# - ), - [("MHash:hash", "Id"), ("MHash:hash32", "Id")], - ) - } - - #[test] - fn multiple_abilities_multiple_members_specializations() { - check_inferred_abilities( - indoc!( - r#" - app "test" provides [hash, hash32, eq, le] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - hash32 : a -> U32 | a has MHash - - Ord has - eq : a, a -> Bool | a has Ord - le : a, a -> Bool | a has Ord - - Id := U64 has [MHash {hash, hash32}, Ord {eq, le}] - - hash = \@Id n -> n - hash32 = \@Id n -> Num.toU32 n - - eq = \@Id m, @Id n -> m == n - le = \@Id m, @Id n -> m < n - "# - ), - [ - ("MHash:hash", "Id"), - ("MHash:hash32", "Id"), - ("Ord:eq", "Id"), - ("Ord:le", "Id"), - ], - ) - } - - #[test] - fn ability_checked_specialization_with_typed_body() { - check_inferred_abilities( - indoc!( - r#" - app "test" provides [hash] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - Id := U64 has [MHash {hash}] - - hash : Id -> U64 - hash = \@Id n -> n - "# - ), - [("MHash:hash", "Id")], - ) - } - - #[test] - fn ability_checked_specialization_with_annotation_only() { - check_inferred_abilities( - indoc!( - r#" - app "test" provides [hash] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - Id := U64 has [MHash {hash}] - - hash : Id -> U64 - "# - ), - [("MHash:hash", "Id")], - ) - } - - #[test] - fn ability_specialization_called() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [zero] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - Id := U64 has [MHash {hash}] - - hash = \@Id n -> n - - zero = hash (@Id 0) - "# - ), - "U64", - ) - } - - #[test] - fn alias_ability_member() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [thething] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - thething = - itis = hash - itis - "# - ), - "a -> U64 | a has MHash", - ) - } - - #[test] - fn when_branch_and_body_flipflop() { - infer_eq_without_problem( - indoc!( - r#" - func = \record -> - when record.tag is - A -> { record & tag: B } - B -> { record & tag: A } - - func - "# - ), - "{ tag : [A, B] }a -> { tag : [A, B] }a", - ) - } - - #[test] - fn ability_constrained_in_non_member_check() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [hashEq] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - hashEq : a, a -> Bool | a has MHash - hashEq = \x, y -> hash x == hash y - "# - ), - "a, a -> Bool | a has MHash", - ) - } - - #[test] - fn ability_constrained_in_non_member_infer() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [hashEq] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - hashEq = \x, y -> hash x == hash y - "# - ), - "a, a1 -> Bool | a has MHash, a1 has MHash", - ) - } - - #[test] - fn ability_constrained_in_non_member_infer_usage() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [result] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - hashEq = \x, y -> hash x == hash y - - Id := U64 has [MHash {hash}] - hash = \@Id n -> n - - result = hashEq (@Id 100) (@Id 101) - "# - ), - "Bool", - ) - } - - #[test] - fn ability_constrained_in_non_member_multiple_specializations() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [result] to "./platform" - - MHash has - hash : a -> U64 | a has MHash - - mulMHashes = \x, y -> hash x * hash y - - Id := U64 has [MHash { hash: hashId }] - hashId = \@Id n -> n - - Three := {} has [MHash { hash: hashThree }] - hashThree = \@Three _ -> 3 - - result = mulMHashes (@Id 100) (@Three {}) - "# - ), - "U64", - ) - } - - #[test] - fn nested_open_tag_union() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [go] to "./platform" - - Expr : [ - Wrap Expr, - Val I64, - ] - - go : Expr -> Expr - go = \e -> - when P e is - P (Wrap (Val _)) -> Wrap e - - # This branch should force the first argument to `P` and - # the first argument to `Wrap` to be an open tag union. - # This tests checks that we don't regress on that. - P y1 -> Wrap y1 - "# - ), - indoc!(r#"Expr -> Expr"#), - ) - } - - #[test] - fn opaque_and_alias_unify() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [always] to "./platform" - - Effect a := {} -> a - - Task a err : Effect (Result a err) - - always : a -> Task a * - always = \x -> @Effect (\{} -> Ok x) - "# - ), - "a -> Task a *", - ); - } - - #[test] - fn export_rigid_to_lower_rank() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [foo] to "./platform" - - F a : { foo : a } - - foo = \arg -> - x : F b - x = arg - x.foo - "# - ), - "F b -> b", - ); - } - - #[test] - fn alias_in_opaque() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [foo] to "./platform" - - MyError : [Error] - - MyResult := Result U8 MyError - - foo = @MyResult (Err Error) - "# - ), - "MyResult", - ) - } - - #[test] - fn alias_propagates_able_var() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [zeroEncoder] to "./platform" - - MEncoder fmt := List U8, fmt -> List U8 | fmt has Format - - Format has it : fmt -> {} | fmt has Format - - zeroEncoder = @MEncoder \lst, _ -> lst - "# - ), - "MEncoder a | a has Format", - ) - } - - #[test] - fn task_wildcard_wildcard() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [tforever] to "./platform" - - Effect a := {} -> a - - eforever : Effect a -> Effect b - - Task a err : Effect (Result a err) - - tforever : Task val err -> Task * * - tforever = \task -> eforever task - "# - ), - "Task val err -> Task * *", - ); - } - - #[test] - fn stdlib_encode_json() { - infer_eq_without_problem( - indoc!( - r#" - app "test" - imports [Json] - provides [main] to "./platform" - - HelloWorld := {} has [Encoding {toEncoder}] - - toEncoder = \@HelloWorld {} -> - Encode.custom \bytes, fmt -> - bytes - |> Encode.appendWith (Encode.string "Hello, World!\n") fmt - - main = - when Str.fromUtf8 (Encode.toBytes (@HelloWorld {}) Json.toUtf8) is - Ok s -> s - _ -> "" - "# - ), - "Str", - ) - } - - #[test] - fn self_recursion_with_inference_var() { - infer_eq_without_problem( - indoc!( - r#" - f : _ -> _ - f = \_ -> if Bool.false then "" else f "" - - f - "# - ), - "Str -> Str", - ) - } - - #[test] - fn mutual_recursion_with_inference_var() { - infer_eq_without_problem( - indoc!( - r#" - f : _ -> Str - f = \s -> g s - g = \s -> if Bool.true then s else f s - - g - "# - ), - "Str -> Str", - ) - } - - #[test] - fn function_alias_in_signature() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [main] to "./platform" - - Parser a : List U8 -> List [Pair a (List U8)] - - any: Parser U8 - any = \inp -> - when List.first inp is - Ok u -> [Pair u (List.drop inp 1)] - _ -> [] - - main = any - "# - ), - "Parser U8", - ); - } - - #[test] - fn infer_variables_in_value_def_signature() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [a] to "./platform" - - a : {a: _} - a = {a: ""} - "# - ), - "{ a : Str }", - ); - } - - #[test] - fn infer_variables_in_destructure_def_signature() { - infer_eq_without_problem( - indoc!( - r#" - app "test" provides [a] to "./platform" - - {a} : {a: _} - {a} = {a: ""} - "# - ), - "Str", - ) - } - - #[test] - fn check_phantom_type() { - infer_eq_without_problem( - indoc!( - r#" - F a b := b - - foo : F Str Str -> F U8 Str - - x : F Str Str - - foo x - "# - ), - "F U8 Str", - ) - } - - #[test] - fn infer_phantom_type_flow() { - infer_eq_without_problem( - indoc!( - r#" - F a b := b - - foo : _ -> F U8 Str - foo = \it -> it - - foo - "# - ), - "F U8 Str -> F U8 Str", - ) - } - - #[test] - fn infer_unbound_phantom_type_star() { - infer_eq_without_problem( - indoc!( - r#" - F a b := b - - foo = \@F {} -> @F "" - - foo - "# - ), - "F * {}* -> F * Str", - ) - } - - #[test] - fn wrap_recursive_opaque_negative_position() { - infer_eq_without_problem( - indoc!( - r#" - OList := [Nil, Cons {} OList] - - lst : [Cons {} OList] - - olist : OList - olist = (\l -> @OList l) lst - - olist - "# - ), - "OList", - ); - } - - #[test] - fn wrap_recursive_opaque_positive_position() { - infer_eq_without_problem( - indoc!( - r#" - OList := [Nil, Cons {} OList] - - lst : [Cons {} OList] - - olist : OList - olist = @OList lst - - olist - "# - ), - "OList", - ); - } - - #[test] - fn rosetree_with_result_is_legal_recursive_type() { - infer_eq_without_problem( - indoc!( - r#" - Rose a : [Rose (Result (List (Rose a)) I64)] - - x : Rose I64 - x = Rose (Ok []) - - x - "# - ), - "Rose I64", - ); - } - - #[test] - fn opaque_wrap_function() { - infer_eq_without_problem( - indoc!( - r#" - A := U8 - List.map [1, 2, 3] @A - "# - ), - "List A", - ); - } - - #[test] - fn opaque_wrap_function_with_inferred_arg() { - infer_eq_without_problem( - indoc!( - r#" - A a := a - List.map [1u8, 2u8, 3u8] @A - "# - ), - "List (A U8)", - ); - } } diff --git a/crates/compiler/test_gen/src/gen_num.rs b/crates/compiler/test_gen/src/gen_num.rs index 2e9276c86f..3df19b9ed3 100644 --- a/crates/compiler/test_gen/src/gen_num.rs +++ b/crates/compiler/test_gen/src/gen_num.rs @@ -3998,3 +3998,60 @@ fn num_count_one_bits() { assert_evals_to!(r#"Num.countOneBits 0u32"#, 0, usize); assert_evals_to!(r#"Num.countOneBits 0b0010_1111u64"#, 5, usize); } + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn num_abs_diff_int() { + assert_evals_to!(r#"Num.absDiff 0u8 0u8"#, 0, u8); + assert_evals_to!(r#"Num.absDiff 1u8 2u8"#, 1, u8); + assert_evals_to!(r#"Num.absDiff 2u8 1u8"#, 1, u8); + assert_evals_to!(r#"Num.absDiff -1 1"#, 2, i64); + assert_evals_to!(r#"Num.absDiff 1 -1"#, 2, i64); + assert_evals_to!(r#"Num.absDiff Num.minI64 -1"#, i64::MAX, i64); +} + +#[test] +#[cfg(any(feature = "gen-llvm"))] +fn num_abs_diff_large_bits() { + assert_evals_to!(r#"Num.absDiff 0u128 0u128"#, 0, u128); + assert_evals_to!(r#"Num.absDiff 1u128 2u128"#, 1, u128); + assert_evals_to!(r#"Num.absDiff -1i128 1i128"#, 2, i128); + assert_evals_to!(r#"Num.absDiff Num.minI128 -1i128"#, i128::MAX, i128); +} + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn num_abs_diff_float() { + assert_evals_to!(r#"Num.absDiff 0.0 0.0"#, 0.0, f64); + assert_evals_to!(r#"Num.absDiff 1.0 2.0"#, 1.0, f64); + assert_evals_to!(r#"Num.absDiff 2.0 1.0"#, 1.0, f64); + assert_evals_to!(r#"Num.absDiff -1.0 1.0"#, 2.0, f64); + assert_evals_to!(r#"Num.absDiff 1.0 -1.0"#, 2.0, f64); +} + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)] +fn num_abs_max_overflow() { + assert_evals_to!(r#"Num.absDiff Num.maxI64 -1"#, 0, i64); +} + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)] +fn num_abs_int_min_overflow() { + assert_evals_to!(r#"Num.absDiff Num.minI64 0"#, 0, i64); +} + +#[test] +#[cfg(any(feature = "gen-llvm"))] +#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)] +fn num_abs_large_bits_min_overflow() { + assert_evals_to!(r#"Num.absDiff Num.minI128 0"#, 0, i128); +} + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn num_abs_float_overflow() { + assert_evals_to!("Num.absDiff Num.maxF64 Num.minF64", f64::INFINITY, f64); +} diff --git a/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt b/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt index 8aff16ab40..5f1ab9d7d4 100644 --- a/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt +++ b/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt @@ -86,16 +86,16 @@ procedure List.92 (List.430, List.431, List.432): ret List.515; procedure Num.19 (#Attr.2, #Attr.3): - let Num.277 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.280; procedure Num.22 (#Attr.2, #Attr.3): - let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.278; + let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.281; procedure Num.77 (#Attr.2, #Attr.3): - let Num.276 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; + ret Num.279; procedure Test.1 (Test.2): let Test.13 : U64 = 0i64; diff --git a/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt b/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt index 13945b6e74..f54cb12482 100644 --- a/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt +++ b/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt @@ -48,8 +48,8 @@ procedure List.9 (List.287): ret List.496; procedure Num.22 (#Attr.2, #Attr.3): - let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.278; procedure Result.5 (Result.12, Result.13): let Result.39 : U8 = 1i64; diff --git a/crates/compiler/test_mono/generated/choose_i128_layout.txt b/crates/compiler/test_mono/generated/choose_i128_layout.txt index b14d4d43fb..bd5ff1be91 100644 --- a/crates/compiler/test_mono/generated/choose_i128_layout.txt +++ b/crates/compiler/test_mono/generated/choose_i128_layout.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.276 : I128 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : I128 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.279; procedure Test.0 (): let Test.6 : I128 = 18446744073709551616i64; diff --git a/crates/compiler/test_mono/generated/choose_u128_layout.txt b/crates/compiler/test_mono/generated/choose_u128_layout.txt index 4754f21bcd..064c77603b 100644 --- a/crates/compiler/test_mono/generated/choose_u128_layout.txt +++ b/crates/compiler/test_mono/generated/choose_u128_layout.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U128 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U128 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.2 : U128 = 170141183460469231731687303715884105728u128; diff --git a/crates/compiler/test_mono/generated/choose_u64_layout.txt b/crates/compiler/test_mono/generated/choose_u64_layout.txt index 21383cc40e..67c6ed5a60 100644 --- a/crates/compiler/test_mono/generated/choose_u64_layout.txt +++ b/crates/compiler/test_mono/generated/choose_u64_layout.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.2 : U64 = 9999999999999999999i64; diff --git a/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt b/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt index 24a19436c5..62e38d36c7 100644 --- a/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt +++ b/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt @@ -40,12 +40,12 @@ procedure List.92 (List.430, List.431, List.432): ret List.497; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Num.22 (#Attr.2, #Attr.3): - let Num.276 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.279; procedure Str.3 (#Attr.2, #Attr.3): let Str.300 : Str = lowlevel StrConcat #Attr.2 #Attr.3; diff --git a/crates/compiler/test_mono/generated/dict.txt b/crates/compiler/test_mono/generated/dict.txt index 171b053006..af409ba16c 100644 --- a/crates/compiler/test_mono/generated/dict.txt +++ b/crates/compiler/test_mono/generated/dict.txt @@ -74,12 +74,12 @@ procedure List.82 (List.526, List.527, List.528): jump List.508 List.526 List.527 List.528; procedure Num.20 (#Attr.2, #Attr.3): - let Num.276 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.279; procedure Num.24 (#Attr.2, #Attr.3): - let Num.278 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.278; + let Num.281 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.281; procedure Test.0 (): let Test.3 : {} = Struct {}; diff --git a/crates/compiler/test_mono/generated/empty_list_of_function_type.txt b/crates/compiler/test_mono/generated/empty_list_of_function_type.txt index 937cff9d90..e7393a5b3a 100644 --- a/crates/compiler/test_mono/generated/empty_list_of_function_type.txt +++ b/crates/compiler/test_mono/generated/empty_list_of_function_type.txt @@ -25,8 +25,8 @@ procedure List.66 (#Attr.2, #Attr.3): ret List.499; procedure Num.22 (#Attr.2, #Attr.3): - let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.278; procedure Test.2 (Test.5): dec Test.5; 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 6e4d7570bc..879a2febce 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 @@ -299,24 +299,24 @@ procedure List.92 (List.430, List.431, List.432): ret List.592; procedure Num.127 (#Attr.2): - let Num.301 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.301; - -procedure Num.19 (#Attr.2, #Attr.3): - let Num.304 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + let Num.304 : U8 = lowlevel NumIntCast #Attr.2; ret Num.304; -procedure Num.20 (#Attr.2, #Attr.3): - let Num.302 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.302; +procedure Num.19 (#Attr.2, #Attr.3): + let Num.307 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.307; -procedure Num.22 (#Attr.2, #Attr.3): - let Num.305 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; +procedure Num.20 (#Attr.2, #Attr.3): + let Num.305 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.305; +procedure Num.22 (#Attr.2, #Attr.3): + let Num.308 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.308; + procedure Num.24 (#Attr.2, #Attr.3): - let Num.303 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.303; + let Num.306 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.306; procedure Str.12 (#Attr.2): let Str.315 : List U8 = lowlevel StrToUtf8 #Attr.2; 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 a2aad89371..48cff67ae8 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 @@ -176,24 +176,24 @@ procedure List.92 (List.430, List.431, List.432): ret List.525; procedure Num.127 (#Attr.2): - let Num.282 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.282; - -procedure Num.19 (#Attr.2, #Attr.3): - let Num.285 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + let Num.285 : U8 = lowlevel NumIntCast #Attr.2; ret Num.285; -procedure Num.20 (#Attr.2, #Attr.3): - let Num.283 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.283; +procedure Num.19 (#Attr.2, #Attr.3): + let Num.288 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.288; -procedure Num.22 (#Attr.2, #Attr.3): - let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; +procedure Num.20 (#Attr.2, #Attr.3): + let Num.286 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.286; +procedure Num.22 (#Attr.2, #Attr.3): + let Num.289 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.289; + procedure Num.24 (#Attr.2, #Attr.3): - let Num.284 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.284; + let Num.287 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.287; procedure Str.12 (#Attr.2): let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2; 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 cadd18398a..3267cc9cf1 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 @@ -184,24 +184,24 @@ procedure List.92 (List.430, List.431, List.432): ret List.525; procedure Num.127 (#Attr.2): - let Num.282 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.282; - -procedure Num.19 (#Attr.2, #Attr.3): - let Num.285 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + let Num.285 : U8 = lowlevel NumIntCast #Attr.2; ret Num.285; -procedure Num.20 (#Attr.2, #Attr.3): - let Num.283 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.283; +procedure Num.19 (#Attr.2, #Attr.3): + let Num.288 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.288; -procedure Num.22 (#Attr.2, #Attr.3): - let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; +procedure Num.20 (#Attr.2, #Attr.3): + let Num.286 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.286; +procedure Num.22 (#Attr.2, #Attr.3): + let Num.289 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.289; + procedure Num.24 (#Attr.2, #Attr.3): - let Num.284 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.284; + let Num.287 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.287; procedure Str.12 (#Attr.2): let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2; diff --git a/crates/compiler/test_mono/generated/encode_derived_string.txt b/crates/compiler/test_mono/generated/encode_derived_string.txt index 2ffd7b9767..23337de9c2 100644 --- a/crates/compiler/test_mono/generated/encode_derived_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_string.txt @@ -53,8 +53,8 @@ procedure List.8 (#Attr.2, #Attr.3): ret List.504; procedure Num.127 (#Attr.2): - let Num.276 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.276; + let Num.279 : U8 = lowlevel NumIntCast #Attr.2; + ret Num.279; procedure Str.12 (#Attr.2): let Str.312 : List U8 = lowlevel StrToUtf8 #Attr.2; 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 c2978e75c8..695a97b6a0 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 @@ -185,24 +185,24 @@ procedure List.92 (List.430, List.431, List.432): ret List.531; procedure Num.127 (#Attr.2): - let Num.284 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.284; - -procedure Num.19 (#Attr.2, #Attr.3): - let Num.287 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + let Num.287 : U8 = lowlevel NumIntCast #Attr.2; ret Num.287; -procedure Num.20 (#Attr.2, #Attr.3): - let Num.285 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.285; +procedure Num.19 (#Attr.2, #Attr.3): + let Num.290 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.290; -procedure Num.22 (#Attr.2, #Attr.3): - let Num.288 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; +procedure Num.20 (#Attr.2, #Attr.3): + let Num.288 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.288; +procedure Num.22 (#Attr.2, #Attr.3): + let Num.291 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.291; + procedure Num.24 (#Attr.2, #Attr.3): - let Num.286 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.286; + let Num.289 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.289; procedure Str.12 (#Attr.2): let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2; 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 fafb45fe43..79fddcc818 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 @@ -191,24 +191,24 @@ procedure List.92 (List.430, List.431, List.432): ret List.531; procedure Num.127 (#Attr.2): - let Num.284 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.284; - -procedure Num.19 (#Attr.2, #Attr.3): - let Num.287 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + let Num.287 : U8 = lowlevel NumIntCast #Attr.2; ret Num.287; -procedure Num.20 (#Attr.2, #Attr.3): - let Num.285 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.285; +procedure Num.19 (#Attr.2, #Attr.3): + let Num.290 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.290; -procedure Num.22 (#Attr.2, #Attr.3): - let Num.288 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; +procedure Num.20 (#Attr.2, #Attr.3): + let Num.288 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.288; +procedure Num.22 (#Attr.2, #Attr.3): + let Num.291 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.291; + procedure Num.24 (#Attr.2, #Attr.3): - let Num.286 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.286; + let Num.289 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.289; procedure Str.12 (#Attr.2): let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2; diff --git a/crates/compiler/test_mono/generated/factorial.txt b/crates/compiler/test_mono/generated/factorial.txt index e0c96b0c43..5fd018b39f 100644 --- a/crates/compiler/test_mono/generated/factorial.txt +++ b/crates/compiler/test_mono/generated/factorial.txt @@ -1,10 +1,10 @@ procedure Num.20 (#Attr.2, #Attr.3): - let Num.276 : I64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : I64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.279; procedure Num.21 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumMul #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumMul #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.15, Test.16): joinpoint Test.7 Test.2 Test.3: diff --git a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt index c344eb7f53..955566e1d2 100644 --- a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt +++ b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.8): let Test.3 : I64 = 10i64; diff --git a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt index 0c7b8891e0..7c8c378f4a 100644 --- a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt +++ b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.276 : U8 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U8 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.279; procedure Test.1 (Test.9): let Test.4 : U8 = 10i64; diff --git a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt index fe6e0ec65d..84a7f95ca0 100644 --- a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt +++ b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt @@ -3,8 +3,8 @@ procedure Bool.1 (): ret Bool.23; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.3 (Test.4): ret Test.4; diff --git a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt index 93430cffc9..6c6a4b267b 100644 --- a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt +++ b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.277 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.280; procedure Test.2 (Test.3): switch Test.3: diff --git a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt index 361c97da60..9e29bcf6e0 100644 --- a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt +++ b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.276 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.279; procedure Test.2 (Test.3, Test.1): let Test.17 : Int1 = false; diff --git a/crates/compiler/test_mono/generated/ir_int_add.txt b/crates/compiler/test_mono/generated/ir_int_add.txt index dd14a05419..9a95c752e8 100644 --- a/crates/compiler/test_mono/generated/ir_int_add.txt +++ b/crates/compiler/test_mono/generated/ir_int_add.txt @@ -3,8 +3,8 @@ procedure List.6 (#Attr.2): ret List.494; procedure Num.19 (#Attr.2, #Attr.3): - let Num.277 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.280; procedure Test.0 (): let Test.1 : List I64 = Array [1i64, 2i64]; diff --git a/crates/compiler/test_mono/generated/ir_plus.txt b/crates/compiler/test_mono/generated/ir_plus.txt index 19f312321c..78b88a11a8 100644 --- a/crates/compiler/test_mono/generated/ir_plus.txt +++ b/crates/compiler/test_mono/generated/ir_plus.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.2 : I64 = 1i64; diff --git a/crates/compiler/test_mono/generated/ir_round.txt b/crates/compiler/test_mono/generated/ir_round.txt index b385b68115..1e9d8e6ba8 100644 --- a/crates/compiler/test_mono/generated/ir_round.txt +++ b/crates/compiler/test_mono/generated/ir_round.txt @@ -1,6 +1,6 @@ procedure Num.45 (#Attr.2): - let Num.275 : I64 = lowlevel NumRound #Attr.2; - ret Num.275; + let Num.278 : I64 = lowlevel NumRound #Attr.2; + ret Num.278; procedure Test.0 (): let Test.2 : Float64 = 3.6f64; diff --git a/crates/compiler/test_mono/generated/ir_two_defs.txt b/crates/compiler/test_mono/generated/ir_two_defs.txt index 5088e4342b..ff9e3d27a9 100644 --- a/crates/compiler/test_mono/generated/ir_two_defs.txt +++ b/crates/compiler/test_mono/generated/ir_two_defs.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.1 : I64 = 3i64; diff --git a/crates/compiler/test_mono/generated/ir_when_idiv.txt b/crates/compiler/test_mono/generated/ir_when_idiv.txt index 1a24b0dd7f..e81871fa7b 100644 --- a/crates/compiler/test_mono/generated/ir_when_idiv.txt +++ b/crates/compiler/test_mono/generated/ir_when_idiv.txt @@ -1,22 +1,22 @@ procedure Num.30 (#Attr.2): - let Num.282 : I64 = 0i64; - let Num.281 : Int1 = lowlevel Eq #Attr.2 Num.282; - ret Num.281; + let Num.285 : I64 = 0i64; + let Num.284 : Int1 = lowlevel Eq #Attr.2 Num.285; + ret Num.284; procedure Num.39 (#Attr.2, #Attr.3): - let Num.277 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3; + ret Num.280; -procedure Num.40 (Num.247, Num.248): - let Num.278 : Int1 = CallByName Num.30 Num.248; - if Num.278 then - let Num.280 : {} = Struct {}; - let Num.279 : [C {}, C I64] = TagId(0) Num.280; - ret Num.279; +procedure Num.40 (Num.250, Num.251): + let Num.281 : Int1 = CallByName Num.30 Num.251; + if Num.281 then + let Num.283 : {} = Struct {}; + let Num.282 : [C {}, C I64] = TagId(0) Num.283; + ret Num.282; else - let Num.276 : I64 = CallByName Num.39 Num.247 Num.248; - let Num.275 : [C {}, C I64] = TagId(1) Num.276; - ret Num.275; + let Num.279 : I64 = CallByName Num.39 Num.250 Num.251; + let Num.278 : [C {}, C I64] = TagId(1) Num.279; + ret Num.278; procedure Test.0 (): let Test.8 : I64 = 1000i64; diff --git a/crates/compiler/test_mono/generated/ir_when_just.txt b/crates/compiler/test_mono/generated/ir_when_just.txt index a830281301..8089c0e3bb 100644 --- a/crates/compiler/test_mono/generated/ir_when_just.txt +++ b/crates/compiler/test_mono/generated/ir_when_just.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.10 : I64 = 41i64; diff --git a/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt b/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt index df895fb065..1154228a6e 100644 --- a/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt +++ b/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt @@ -44,8 +44,8 @@ procedure List.9 (List.287): ret List.496; procedure Num.22 (#Attr.2, #Attr.3): - let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.278; procedure Str.27 (Str.99): let Str.298 : [C Int1, C I64] = CallByName Str.72 Str.99; diff --git a/crates/compiler/test_mono/generated/issue_4749.txt b/crates/compiler/test_mono/generated/issue_4749.txt index d4226b54c1..e419a3f762 100644 --- a/crates/compiler/test_mono/generated/issue_4749.txt +++ b/crates/compiler/test_mono/generated/issue_4749.txt @@ -336,16 +336,16 @@ procedure List.72 (#Attr.2, #Attr.3, #Attr.4): ret List.505; procedure Num.20 (#Attr.2, #Attr.3): - let Num.276 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.279; procedure Num.24 (#Attr.2, #Attr.3): - let Num.278 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.278; + let Num.281 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.281; procedure Num.77 (#Attr.2, #Attr.3): - let Num.280 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; - ret Num.280; + let Num.283 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; + ret Num.283; procedure Str.48 (#Attr.2, #Attr.3, #Attr.4): let Str.307 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4; 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 5f98319551..90f9a45cd4 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 @@ -302,16 +302,16 @@ procedure List.72 (#Attr.2, #Attr.3, #Attr.4): ret List.499; procedure Num.20 (#Attr.2, #Attr.3): - let Num.276 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.279; procedure Num.24 (#Attr.2, #Attr.3): - let Num.278 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.278; + let Num.281 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.281; procedure Num.77 (#Attr.2, #Attr.3): - let Num.280 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; - ret Num.280; + let Num.283 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; + ret Num.283; procedure Str.12 (#Attr.2): let Str.307 : List U8 = lowlevel StrToUtf8 #Attr.2; diff --git a/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt b/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt index 33ffa57579..4a376c3cb7 100644 --- a/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt +++ b/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt @@ -1,10 +1,10 @@ procedure Num.96 (#Attr.2): - let Num.275 : Str = lowlevel NumToStr #Attr.2; - ret Num.275; + let Num.278 : Str = lowlevel NumToStr #Attr.2; + ret Num.278; procedure Num.96 (#Attr.2): - let Num.276 : Str = lowlevel NumToStr #Attr.2; - ret Num.276; + let Num.279 : Str = lowlevel NumToStr #Attr.2; + ret Num.279; procedure Test.1 (Test.4): let Test.13 : [C U8, C U64] = TagId(1) Test.4; diff --git a/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt b/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt index ef6c2e8aa4..1174867211 100644 --- a/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt +++ b/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt @@ -7,12 +7,12 @@ procedure Bool.2 (): ret Bool.24; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Num.21 (#Attr.2, #Attr.3): - let Num.276 : U64 = lowlevel NumMul #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U64 = lowlevel NumMul #Attr.2 #Attr.3; + ret Num.279; procedure Test.0 (Test.8): let Test.20 : Int1 = CallByName Bool.2; diff --git a/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt b/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt index e933502499..980053928e 100644 --- a/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt +++ b/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt @@ -36,12 +36,12 @@ procedure List.92 (List.430, List.431, List.432): ret List.497; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Num.22 (#Attr.2, #Attr.3): - let Num.276 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.279; procedure Test.7 (Test.11, Test.12): let Test.17 : {[C *self, ], [, C {[C *self, ], *self}]} = Struct {Test.12, Test.11}; diff --git a/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt b/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt index f585b00608..f26c5c2f4f 100644 --- a/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt +++ b/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt @@ -24,12 +24,12 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4): ret List.501; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Num.22 (#Attr.2, #Attr.3): - let Num.276 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.279; procedure Test.1 (): let Test.8 : List I64 = Array [1i64, 2i64, 3i64]; diff --git a/crates/compiler/test_mono/generated/list_get.txt b/crates/compiler/test_mono/generated/list_get.txt index 1662e696ee..4812fe8f34 100644 --- a/crates/compiler/test_mono/generated/list_get.txt +++ b/crates/compiler/test_mono/generated/list_get.txt @@ -21,8 +21,8 @@ procedure List.66 (#Attr.2, #Attr.3): ret List.499; procedure Num.22 (#Attr.2, #Attr.3): - let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.2): let Test.6 : List I64 = Array [1i64, 2i64, 3i64]; diff --git a/crates/compiler/test_mono/generated/list_len.txt b/crates/compiler/test_mono/generated/list_len.txt index 2c9b2a0743..e4ed91bee9 100644 --- a/crates/compiler/test_mono/generated/list_len.txt +++ b/crates/compiler/test_mono/generated/list_len.txt @@ -7,8 +7,8 @@ procedure List.6 (#Attr.2): ret List.495; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.1 : List I64 = Array [1i64, 2i64, 3i64]; diff --git a/crates/compiler/test_mono/generated/list_map_closure_borrows.txt b/crates/compiler/test_mono/generated/list_map_closure_borrows.txt index d99df9690d..748f8482dc 100644 --- a/crates/compiler/test_mono/generated/list_map_closure_borrows.txt +++ b/crates/compiler/test_mono/generated/list_map_closure_borrows.txt @@ -26,8 +26,8 @@ procedure List.66 (#Attr.2, #Attr.3): ret List.499; procedure Num.22 (#Attr.2, #Attr.3): - let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.278; procedure Str.16 (#Attr.2, #Attr.3): let Str.298 : Str = lowlevel StrRepeat #Attr.2 #Attr.3; diff --git a/crates/compiler/test_mono/generated/list_map_closure_owns.txt b/crates/compiler/test_mono/generated/list_map_closure_owns.txt index 59c677ad64..3724bcf222 100644 --- a/crates/compiler/test_mono/generated/list_map_closure_owns.txt +++ b/crates/compiler/test_mono/generated/list_map_closure_owns.txt @@ -26,8 +26,8 @@ procedure List.66 (#Attr.2, #Attr.3): ret List.499; procedure Num.22 (#Attr.2, #Attr.3): - let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.278; procedure Str.3 (#Attr.2, #Attr.3): let Str.299 : Str = lowlevel StrConcat #Attr.2 #Attr.3; diff --git a/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt b/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt index bc2a3687f7..ec2eb0db53 100644 --- a/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt +++ b/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt @@ -21,8 +21,8 @@ procedure List.5 (#Attr.2, #Attr.3): procedure Num.19 (#Attr.2, #Attr.3): - let Num.277 : U8 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : U8 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.280; procedure Test.4 (Test.5, #Attr.12): let Test.1 : U8 = UnionAtIndex (Id 0) (Index 0) #Attr.12; diff --git a/crates/compiler/test_mono/generated/list_pass_to_function.txt b/crates/compiler/test_mono/generated/list_pass_to_function.txt index 4b9b7112ec..1ac971394b 100644 --- a/crates/compiler/test_mono/generated/list_pass_to_function.txt +++ b/crates/compiler/test_mono/generated/list_pass_to_function.txt @@ -24,8 +24,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4): ret List.499; procedure Num.22 (#Attr.2, #Attr.3): - let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.278; procedure Test.2 (Test.3): let Test.6 : U64 = 0i64; diff --git a/crates/compiler/test_mono/generated/list_sort_asc.txt b/crates/compiler/test_mono/generated/list_sort_asc.txt index 8ac7ce082d..27cfaeff8b 100644 --- a/crates/compiler/test_mono/generated/list_sort_asc.txt +++ b/crates/compiler/test_mono/generated/list_sort_asc.txt @@ -8,8 +8,8 @@ procedure List.59 (List.282): ret List.494; procedure Num.46 (#Attr.2, #Attr.3): - let Num.275 : U8 = lowlevel NumCompare #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U8 = lowlevel NumCompare #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.2 : List I64 = Array [4i64, 3i64, 2i64, 1i64]; diff --git a/crates/compiler/test_mono/generated/nested_pattern_match.txt b/crates/compiler/test_mono/generated/nested_pattern_match.txt index 3da4e73dcc..f7f39f716c 100644 --- a/crates/compiler/test_mono/generated/nested_pattern_match.txt +++ b/crates/compiler/test_mono/generated/nested_pattern_match.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.19 : I64 = 41i64; diff --git a/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt b/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt index ef70723086..9273d22e51 100644 --- a/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt +++ b/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt @@ -1,6 +1,6 @@ procedure Num.37 (#Attr.2, #Attr.3): - let Num.275 : Float64 = lowlevel NumDivFrac #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : Float64 = lowlevel NumDivFrac #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.2 : Float64 = 1f64; diff --git a/crates/compiler/test_mono/generated/optional_when.txt b/crates/compiler/test_mono/generated/optional_when.txt index 191cc305b4..1272c5ca62 100644 --- a/crates/compiler/test_mono/generated/optional_when.txt +++ b/crates/compiler/test_mono/generated/optional_when.txt @@ -1,6 +1,6 @@ procedure Num.21 (#Attr.2, #Attr.3): - let Num.277 : I64 = lowlevel NumMul #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : I64 = lowlevel NumMul #Attr.2 #Attr.3; + ret Num.280; procedure Test.1 (Test.6): let Test.21 : Int1 = false; diff --git a/crates/compiler/test_mono/generated/quicksort_help.txt b/crates/compiler/test_mono/generated/quicksort_help.txt index f00adf21db..8d01887c8a 100644 --- a/crates/compiler/test_mono/generated/quicksort_help.txt +++ b/crates/compiler/test_mono/generated/quicksort_help.txt @@ -1,14 +1,14 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Num.20 (#Attr.2, #Attr.3): - let Num.276 : I64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : I64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.279; procedure Num.22 (#Attr.2, #Attr.3): - let Num.277 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.280; procedure Test.1 (Test.24, Test.25, Test.26): joinpoint Test.12 Test.2 Test.3 Test.4: diff --git a/crates/compiler/test_mono/generated/quicksort_swap.txt b/crates/compiler/test_mono/generated/quicksort_swap.txt index beea50170d..0b08fc6886 100644 --- a/crates/compiler/test_mono/generated/quicksort_swap.txt +++ b/crates/compiler/test_mono/generated/quicksort_swap.txt @@ -42,8 +42,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4): ret List.499; procedure Num.22 (#Attr.2, #Attr.3): - let Num.277 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.280; procedure Test.1 (Test.2): let Test.28 : U64 = 0i64; diff --git a/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt index eea16dcef9..01c72606d7 100644 --- a/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt +++ b/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.4): let Test.2 : I64 = StructAtIndex 0 Test.4; diff --git a/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt index 74a2941f14..8ba3a4a789 100644 --- a/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt +++ b/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.4): let Test.2 : I64 = 10i64; diff --git a/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt index f9d2495d40..3b36b15e32 100644 --- a/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt +++ b/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.2): let Test.3 : I64 = StructAtIndex 0 Test.2; diff --git a/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt index feb8083f78..aa27dff32f 100644 --- a/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt +++ b/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.2): let Test.3 : I64 = 10i64; diff --git a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt index eca9933033..c0d34f84a9 100644 --- a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt +++ b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt @@ -3,8 +3,8 @@ procedure Bool.2 (): ret Bool.23; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U32 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U32 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.2): let Test.8 : U32 = 0i64; diff --git a/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt b/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt index 984500a25b..6b8746f034 100644 --- a/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt +++ b/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt @@ -3,12 +3,12 @@ procedure Bool.11 (#Attr.2, #Attr.3): ret Bool.23; procedure Num.20 (#Attr.2, #Attr.3): - let Num.276 : U8 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U8 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.279; procedure Num.21 (#Attr.2, #Attr.3): - let Num.275 : U8 = lowlevel NumMul #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U8 = lowlevel NumMul #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.26, Test.27): joinpoint Test.11 Test.2 Test.3: diff --git a/crates/compiler/test_mono/generated/recursively_build_effect.txt b/crates/compiler/test_mono/generated/recursively_build_effect.txt index fe79da8de2..289870388b 100644 --- a/crates/compiler/test_mono/generated/recursively_build_effect.txt +++ b/crates/compiler/test_mono/generated/recursively_build_effect.txt @@ -1,6 +1,6 @@ procedure Num.20 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.278; procedure Str.3 (#Attr.2, #Attr.3): let Str.300 : Str = lowlevel StrConcat #Attr.2 #Attr.3; diff --git a/crates/compiler/test_mono/generated/rigids.txt b/crates/compiler/test_mono/generated/rigids.txt index fb566e78a2..166c47eb2e 100644 --- a/crates/compiler/test_mono/generated/rigids.txt +++ b/crates/compiler/test_mono/generated/rigids.txt @@ -42,8 +42,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4): ret List.499; procedure Num.22 (#Attr.2, #Attr.3): - let Num.277 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.280; procedure Test.1 (Test.2, Test.3, Test.4): inc Test.4; diff --git a/crates/compiler/test_mono/generated/specialize_closures.txt b/crates/compiler/test_mono/generated/specialize_closures.txt index 4d1ee3ac7e..87304ac2d6 100644 --- a/crates/compiler/test_mono/generated/specialize_closures.txt +++ b/crates/compiler/test_mono/generated/specialize_closures.txt @@ -3,12 +3,12 @@ procedure Bool.2 (): ret Bool.24; procedure Num.19 (#Attr.2, #Attr.3): - let Num.276 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.279; procedure Num.21 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumMul #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumMul #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.2, Test.3): let Test.15 : U8 = GetTagId Test.2; diff --git a/crates/compiler/test_mono/generated/specialize_lowlevel.txt b/crates/compiler/test_mono/generated/specialize_lowlevel.txt index 38ce048821..e4a35c87ff 100644 --- a/crates/compiler/test_mono/generated/specialize_lowlevel.txt +++ b/crates/compiler/test_mono/generated/specialize_lowlevel.txt @@ -3,12 +3,12 @@ procedure Bool.2 (): ret Bool.23; procedure Num.19 (#Attr.2, #Attr.3): - let Num.276 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.279; procedure Num.21 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumMul #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumMul #Attr.2 #Attr.3; + ret Num.278; procedure Test.6 (Test.8, #Attr.12): let Test.4 : I64 = UnionAtIndex (Id 0) (Index 0) #Attr.12; diff --git a/crates/compiler/test_mono/generated/tail_call_elimination.txt b/crates/compiler/test_mono/generated/tail_call_elimination.txt index 9d990096aa..2f05838272 100644 --- a/crates/compiler/test_mono/generated/tail_call_elimination.txt +++ b/crates/compiler/test_mono/generated/tail_call_elimination.txt @@ -1,10 +1,10 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Num.20 (#Attr.2, #Attr.3): - let Num.276 : I64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : I64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.279; procedure Test.1 (Test.15, Test.16): joinpoint Test.7 Test.2 Test.3: 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 d2d99d4b71..7cce0f6fb1 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 @@ -170,24 +170,24 @@ procedure List.92 (List.430, List.431, List.432): ret List.529; procedure Num.127 (#Attr.2): - let Num.284 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.284; - -procedure Num.19 (#Attr.2, #Attr.3): - let Num.287 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + let Num.287 : U8 = lowlevel NumIntCast #Attr.2; ret Num.287; -procedure Num.20 (#Attr.2, #Attr.3): - let Num.285 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.285; +procedure Num.19 (#Attr.2, #Attr.3): + let Num.290 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.290; -procedure Num.22 (#Attr.2, #Attr.3): - let Num.288 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; +procedure Num.20 (#Attr.2, #Attr.3): + let Num.288 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.288; +procedure Num.22 (#Attr.2, #Attr.3): + let Num.291 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.291; + procedure Num.24 (#Attr.2, #Attr.3): - let Num.286 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.286; + let Num.289 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.289; procedure Str.12 (#Attr.2): let Str.299 : List U8 = lowlevel StrToUtf8 #Attr.2; diff --git a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt index 8f4a776f38..7744205320 100644 --- a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt +++ b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt @@ -310,24 +310,24 @@ procedure List.92 (List.430, List.431, List.432): ret List.596; procedure Num.127 (#Attr.2): - let Num.303 : U8 = lowlevel NumIntCast #Attr.2; - ret Num.303; - -procedure Num.19 (#Attr.2, #Attr.3): - let Num.306 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + let Num.306 : U8 = lowlevel NumIntCast #Attr.2; ret Num.306; -procedure Num.20 (#Attr.2, #Attr.3): - let Num.304 : U64 = lowlevel NumSub #Attr.2 #Attr.3; - ret Num.304; +procedure Num.19 (#Attr.2, #Attr.3): + let Num.309 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.309; -procedure Num.22 (#Attr.2, #Attr.3): - let Num.307 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; +procedure Num.20 (#Attr.2, #Attr.3): + let Num.307 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.307; +procedure Num.22 (#Attr.2, #Attr.3): + let Num.310 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.310; + procedure Num.24 (#Attr.2, #Attr.3): - let Num.305 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; - ret Num.305; + let Num.308 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.308; procedure Str.12 (#Attr.2): let Str.300 : List U8 = lowlevel StrToUtf8 #Attr.2; diff --git a/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt b/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt index 267bd66fac..77515f115c 100644 --- a/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt +++ b/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt @@ -86,16 +86,16 @@ procedure List.92 (List.430, List.431, List.432): ret List.515; procedure Num.19 (#Attr.2, #Attr.3): - let Num.277 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.277; + let Num.280 : U64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.280; procedure Num.22 (#Attr.2, #Attr.3): - let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; - ret Num.278; + let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.281; procedure Num.77 (#Attr.2, #Attr.3): - let Num.276 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; - ret Num.276; + let Num.279 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3; + ret Num.279; procedure Test.3 (Test.4, Test.12): let Test.13 : [C U64, C U64] = TagId(0) Test.4; diff --git a/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt b/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt index 08f2861fbc..9c1fe5dc8a 100644 --- a/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt +++ b/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt @@ -3,8 +3,8 @@ procedure Bool.2 (): ret Bool.25; procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : U8 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : U8 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.1 (Test.2): joinpoint Test.12: diff --git a/crates/compiler/test_mono/generated/when_nested_maybe.txt b/crates/compiler/test_mono/generated/when_nested_maybe.txt index 3da4e73dcc..f7f39f716c 100644 --- a/crates/compiler/test_mono/generated/when_nested_maybe.txt +++ b/crates/compiler/test_mono/generated/when_nested_maybe.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.19 : I64 = 41i64; diff --git a/crates/compiler/test_mono/generated/when_on_record.txt b/crates/compiler/test_mono/generated/when_on_record.txt index 6735c9b9bb..b700d45479 100644 --- a/crates/compiler/test_mono/generated/when_on_record.txt +++ b/crates/compiler/test_mono/generated/when_on_record.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.5 : I64 = 2i64; diff --git a/crates/compiler/test_mono/generated/when_on_two_values.txt b/crates/compiler/test_mono/generated/when_on_two_values.txt index 263451ff02..7f7fd17562 100644 --- a/crates/compiler/test_mono/generated/when_on_two_values.txt +++ b/crates/compiler/test_mono/generated/when_on_two_values.txt @@ -1,6 +1,6 @@ procedure Num.19 (#Attr.2, #Attr.3): - let Num.275 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; - ret Num.275; + let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3; + ret Num.278; procedure Test.0 (): let Test.15 : I64 = 3i64; diff --git a/crates/compiler/test_solve_helpers/src/lib.rs b/crates/compiler/test_solve_helpers/src/lib.rs index 410ab622a3..5e2102d7f2 100644 --- a/crates/compiler/test_solve_helpers/src/lib.rs +++ b/crates/compiler/test_solve_helpers/src/lib.rs @@ -183,7 +183,7 @@ fn parse_queries(src: &str, line_info: &LineInfo) -> Vec { } }; - let mut queries_on_line = RE_TYPE_QUERY.captures_iter(line).into_iter().peekable(); + let mut queries_on_line = RE_TYPE_QUERY.captures_iter(line).peekable(); if queries_on_line.peek().is_none() || line.contains(MUTLILINE_MARKER) { consecutive_query_lines = 0; diff --git a/crates/compiler/types/src/pretty_print.rs b/crates/compiler/types/src/pretty_print.rs index 25527f0f72..590d410f02 100644 --- a/crates/compiler/types/src/pretty_print.rs +++ b/crates/compiler/types/src/pretty_print.rs @@ -1285,8 +1285,8 @@ fn write_flat_type<'a>( } } -pub fn push_union<'a, L: Label>( - subs: &'a Subs, +pub fn push_union( + subs: &Subs, tags: &UnionLabels, fields: &mut Vec<(L, Vec)>, ) { diff --git a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt new file mode 100644 index 0000000000..35e7b3d362 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt @@ -0,0 +1,9 @@ +app "test" provides [hash] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +Id := U64 has [MHash {hash}] + +hash : Id -> U64 +#^^^^{-1} Id#hash(3): Id -[[hash(3)]]-> U64 diff --git a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt new file mode 100644 index 0000000000..ecbe8c2922 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt @@ -0,0 +1,10 @@ +app "test" provides [hash] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +Id := U64 has [MHash {hash}] + +hash : Id -> U64 +hash = \@Id n -> n +#^^^^{-1} Id#hash(3): Id -[[hash(3)]]-> U64 diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt new file mode 100644 index 0000000000..cdb461a6f2 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt @@ -0,0 +1,8 @@ +app "test" provides [hashEq] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +hashEq : a, a -> Bool | a has MHash +hashEq = \x, y -> hash x == hash y +#^^^^^^{-1} a, a -[[hashEq(0)]]-> Bool | a has MHash diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt new file mode 100644 index 0000000000..caf1681ba5 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt @@ -0,0 +1,7 @@ +app "test" provides [hashEq] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +hashEq = \x, y -> hash x == hash y +#^^^^^^{-1} a, a1 -[[hashEq(0)]]-> Bool | a has MHash, a1 has MHash diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt new file mode 100644 index 0000000000..18d9d56846 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt @@ -0,0 +1,12 @@ +app "test" provides [result] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +hashEq = \x, y -> hash x == hash y + +Id := U64 has [MHash {hash}] +hash = \@Id n -> n + +result = hashEq (@Id 100) (@Id 101) +#^^^^^^{-1} Bool diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt new file mode 100644 index 0000000000..cd2e96ba48 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt @@ -0,0 +1,15 @@ +app "test" provides [result] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +mulMHashes = \x, y -> hash x * hash y + +Id := U64 has [MHash { hash: hashId }] +hashId = \@Id n -> n + +Three := {} has [MHash { hash: hashThree }] +hashThree = \@Three _ -> 3 + +result = mulMHashes (@Id 100) (@Three {}) +#^^^^^^{-1} U64 diff --git a/crates/compiler/uitest/tests/solve/ability_specialization_called.txt b/crates/compiler/uitest/tests/solve/ability_specialization_called.txt new file mode 100644 index 0000000000..e88496dfda --- /dev/null +++ b/crates/compiler/uitest/tests/solve/ability_specialization_called.txt @@ -0,0 +1,11 @@ +app "test" provides [zero] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +Id := U64 has [MHash {hash}] + +hash = \@Id n -> n + +zero = hash (@Id 0) +#^^^^{-1} U64 diff --git a/crates/compiler/uitest/tests/solve/alias_ability_member.txt b/crates/compiler/uitest/tests/solve/alias_ability_member.txt new file mode 100644 index 0000000000..e552bf692e --- /dev/null +++ b/crates/compiler/uitest/tests/solve/alias_ability_member.txt @@ -0,0 +1,9 @@ +app "test" provides [thething] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + +thething = +#^^^^^^^^{-1} a -[[] + a:hash(2):1]-> U64 | a has MHash + itis = hash + itis diff --git a/crates/compiler/uitest/tests/solve/alias_in_opaque.txt b/crates/compiler/uitest/tests/solve/alias_in_opaque.txt new file mode 100644 index 0000000000..b4c3dbf064 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/alias_in_opaque.txt @@ -0,0 +1,8 @@ +app "test" provides [foo] to "./platform" + +MyError : [Error] + +MyResult := Result U8 MyError + +foo = @MyResult (Err Error) +#^^^{-1} MyResult diff --git a/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt b/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt new file mode 100644 index 0000000000..6696025603 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt @@ -0,0 +1,8 @@ +app "test" provides [zeroEncoder] to "./platform" + +MEncoder fmt := List U8, fmt -> List U8 | fmt has Format + +Format has it : fmt -> {} | fmt has Format + +zeroEncoder = @MEncoder \lst, _ -> lst +#^^^^^^^^^^^{-1} MEncoder a | a has Format diff --git a/crates/compiler/uitest/tests/solve/check_phantom_type.txt b/crates/compiler/uitest/tests/solve/check_phantom_type.txt new file mode 100644 index 0000000000..138b7f1e79 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/check_phantom_type.txt @@ -0,0 +1,13 @@ +app "test" provides [main] to "./platform" + +entry = + F a b := b + + foo : F Str Str -> F U8 Str + + x : F Str Str + + foo x + +main = entry +# ^^^^^ F U8 Str diff --git a/crates/compiler/uitest/tests/constrain_dbg_flex_var.txt b/crates/compiler/uitest/tests/solve/constrain_dbg_flex_var.txt similarity index 100% rename from crates/compiler/uitest/tests/constrain_dbg_flex_var.txt rename to crates/compiler/uitest/tests/solve/constrain_dbg_flex_var.txt diff --git a/crates/compiler/uitest/tests/solve/copy_vars_referencing_copied_vars.txt b/crates/compiler/uitest/tests/solve/copy_vars_referencing_copied_vars.txt new file mode 100644 index 0000000000..9d47e11a30 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/copy_vars_referencing_copied_vars.txt @@ -0,0 +1,11 @@ +app "test" provides [main] to "./platform" + +entry = + Job : [Job [Command] (List Job)] + + job : Job + + job + +main = entry +# ^^^^^ Job diff --git a/crates/compiler/uitest/tests/solve/export_rigid_to_lower_rank.txt b/crates/compiler/uitest/tests/solve/export_rigid_to_lower_rank.txt new file mode 100644 index 0000000000..d444bce244 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/export_rigid_to_lower_rank.txt @@ -0,0 +1,9 @@ +app "test" provides [foo] to "./platform" + +F a : { foo : a } + +foo = \arg -> +#^^^{-1} F b -[[foo(0)]]-> b + x : F b + x = arg + x.foo diff --git a/crates/compiler/uitest/tests/solve/exposed_ability_name.txt b/crates/compiler/uitest/tests/solve/exposed_ability_name.txt new file mode 100644 index 0000000000..3563c02521 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/exposed_ability_name.txt @@ -0,0 +1,6 @@ +app "test" provides [main] to "./platform" + +MHash has hash : a -> U64 | a has MHash + +main = hash +# ^^^^ MHash#hash(2): a -[[] + a:hash(2):1]-> U64 | a has MHash diff --git a/crates/compiler/uitest/tests/solve/function_alias_in_signature.txt b/crates/compiler/uitest/tests/solve/function_alias_in_signature.txt new file mode 100644 index 0000000000..6cedeb04fc --- /dev/null +++ b/crates/compiler/uitest/tests/solve/function_alias_in_signature.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +Parser a : List U8 -> List [Pair a (List U8)] + +any: Parser U8 +any = \inp -> + when List.first inp is + Ok u -> [Pair u (List.drop inp 1)] + _ -> [] + +main = any +# ^^^ Parser U8 diff --git a/crates/compiler/uitest/tests/solve/generalize_and_specialize_recursion_var.txt b/crates/compiler/uitest/tests/solve/generalize_and_specialize_recursion_var.txt new file mode 100644 index 0000000000..800350c466 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/generalize_and_specialize_recursion_var.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + Job a : [Job (List (Job a)) a] + + job : Job Str + + when job is + Job lst s -> P lst s + +main = entry +# ^^^^^ [P (List ([Job (List a) Str] as a)) Str]w_b diff --git a/crates/compiler/uitest/tests/solve/generalized_accessor_function_applied.txt b/crates/compiler/uitest/tests/solve/generalized_accessor_function_applied.txt new file mode 100644 index 0000000000..30914efc28 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/generalized_accessor_function_applied.txt @@ -0,0 +1,9 @@ +app "test" provides [main] to "./platform" + +entry = + returnFoo = .foo + + returnFoo { foo: "foo" } + +main = entry +# ^^^^^ Str diff --git a/crates/compiler/uitest/tests/infer_concrete_type_with_inference_var.txt b/crates/compiler/uitest/tests/solve/infer_concrete_type_with_inference_var.txt similarity index 100% rename from crates/compiler/uitest/tests/infer_concrete_type_with_inference_var.txt rename to crates/compiler/uitest/tests/solve/infer_concrete_type_with_inference_var.txt diff --git a/crates/compiler/uitest/tests/infer_contextual_crash.txt b/crates/compiler/uitest/tests/solve/infer_contextual_crash.txt similarity index 100% rename from crates/compiler/uitest/tests/infer_contextual_crash.txt rename to crates/compiler/uitest/tests/solve/infer_contextual_crash.txt diff --git a/crates/compiler/uitest/tests/solve/infer_phantom_type_flow.txt b/crates/compiler/uitest/tests/solve/infer_phantom_type_flow.txt new file mode 100644 index 0000000000..e63b4810bd --- /dev/null +++ b/crates/compiler/uitest/tests/solve/infer_phantom_type_flow.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + F a b := b + + foo : _ -> F U8 Str + foo = \it -> it + + foo + +main = entry +# ^^^^^ F U8 Str -[[foo(3)]]-> F U8 Str diff --git a/crates/compiler/uitest/tests/solve/infer_unbound_phantom_type_star.txt b/crates/compiler/uitest/tests/solve/infer_unbound_phantom_type_star.txt new file mode 100644 index 0000000000..c579709de7 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/infer_unbound_phantom_type_star.txt @@ -0,0 +1,11 @@ +app "test" provides [main] to "./platform" + +entry = + F a b := b + + foo = \@F {} -> @F "" + + foo + +main = entry +# ^^^^^ F w_a {}w_b -[[foo(3)]]-> F w_c Str diff --git a/crates/compiler/uitest/tests/solve/infer_variables_in_destructure_def_signature.txt b/crates/compiler/uitest/tests/solve/infer_variables_in_destructure_def_signature.txt new file mode 100644 index 0000000000..30904ff3b3 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/infer_variables_in_destructure_def_signature.txt @@ -0,0 +1,7 @@ +app "test" provides [f] to "./platform" + +{a} : {a: _} +{a} = {a: ""} + +f = a +# ^ Str diff --git a/crates/compiler/uitest/tests/solve/infer_variables_in_value_def_signature.txt b/crates/compiler/uitest/tests/solve/infer_variables_in_value_def_signature.txt new file mode 100644 index 0000000000..640cbcaea1 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/infer_variables_in_value_def_signature.txt @@ -0,0 +1,5 @@ +app "test" provides [a] to "./platform" + +a : {a: _} +a = {a: ""} +#^{-1} { a : Str } diff --git a/crates/compiler/uitest/tests/solve/issue_2458.txt b/crates/compiler/uitest/tests/solve/issue_2458.txt new file mode 100644 index 0000000000..3ec2b3c206 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/issue_2458.txt @@ -0,0 +1,13 @@ +app "test" provides [main] to "./platform" + +entry = + Foo a : [Blah (Result (Bar a) { val: a })] + Bar a : Foo a + + v : Bar U8 + v = Blah (Ok (Blah (Err { val: 1 }))) + + v + +main = entry +# ^^^^^ Bar U8 diff --git a/crates/compiler/uitest/tests/solve/issue_2458_swapped_order.txt b/crates/compiler/uitest/tests/solve/issue_2458_swapped_order.txt new file mode 100644 index 0000000000..d94ee27c62 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/issue_2458_swapped_order.txt @@ -0,0 +1,13 @@ +app "test" provides [main] to "./platform" + +entry = + Bar a : Foo a + Foo a : [Blah (Result (Bar a) { val: a })] + + v : Bar U8 + v = Blah (Ok (Blah (Err { val: 1 }))) + + v + +main = entry +# ^^^^^ Bar U8 diff --git a/crates/compiler/uitest/tests/solve/issue_2583_specialize_errors_behind_unified_branches.txt b/crates/compiler/uitest/tests/solve/issue_2583_specialize_errors_behind_unified_branches.txt new file mode 100644 index 0000000000..f54fdb4a1c --- /dev/null +++ b/crates/compiler/uitest/tests/solve/issue_2583_specialize_errors_behind_unified_branches.txt @@ -0,0 +1,7 @@ +app "test" provides [main] to "./platform" + +entry = + if Bool.true then List.first [] else Str.toI64 "" + +main = entry +# ^^^^^ Result I64 [InvalidNumStr, ListWasEmpty]w_a diff --git a/crates/compiler/uitest/tests/solve/lambda_set_within_alias_is_quantified.txt b/crates/compiler/uitest/tests/solve/lambda_set_within_alias_is_quantified.txt new file mode 100644 index 0000000000..0f873b7252 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/lambda_set_within_alias_is_quantified.txt @@ -0,0 +1,10 @@ +app "test" provides [effectAlways] to "./platform" + +Effect a := {} -> a + +effectAlways : a -> Effect a +effectAlways = \x -> +#^^^^^^^^^^^^{-1} a -[[effectAlways(0)]]-> Effect a + inner = \{} -> x + + @Effect inner diff --git a/crates/compiler/uitest/tests/solve/lots_of_type_variables.txt b/crates/compiler/uitest/tests/solve/lots_of_type_variables.txt new file mode 100644 index 0000000000..65f7223e6b --- /dev/null +++ b/crates/compiler/uitest/tests/solve/lots_of_type_variables.txt @@ -0,0 +1,8 @@ +app "test" provides [main] to "./platform" + +entry = + fun = \a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb -> {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb} + fun + +main = entry +# ^^^^^ w_a, w_b, w_c, w_d, w_e, w_f, w_g, w_h, w_i, w_j, w_k, w_l, w_m, w_n, w_o, w_p, w_q, w_r, w_s, w_t, w_u, w_v, w_w, w_x, w_y, w_z, w_aa, w_bb -[[fun(2)]]-> { a : w_a, aa : w_aa, b : w_b, bb : w_bb, c : w_c, d : w_d, e : w_e, f : w_f, g : w_g, h : w_h, i : w_i, j : w_j, k : w_k, l : w_l, m : w_m, n : w_n, o : w_o, p : w_p, q : w_q, r : w_r, s : w_s, t : w_t, u : w_u, v : w_v, w : w_w, x : w_x, y : w_y, z : w_z } diff --git a/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt b/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt new file mode 100644 index 0000000000..d124bd1687 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt @@ -0,0 +1,23 @@ +app "test" provides [hash, hash32, eq, le] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + hash32 : a -> U32 | a has MHash + +Ord has + eq : a, a -> Bool | a has Ord + le : a, a -> Bool | a has Ord + +Id := U64 has [MHash {hash, hash32}, Ord {eq, le}] + +hash = \@Id n -> n +#^^^^{-1} Id#hash(7): Id -[[hash(7)]]-> U64 + +hash32 = \@Id n -> Num.toU32 n +#^^^^^^{-1} Id#hash32(8): Id -[[hash32(8)]]-> U32 + +eq = \@Id m, @Id n -> m == n +#^^{-1} Id#eq(9): Id, Id -[[eq(9)]]-> Bool + +le = \@Id m, @Id n -> m < n +#^^{-1} Id#le(10): Id, Id -[[le(10)]]-> Bool diff --git a/crates/compiler/uitest/tests/solve/mutual_recursion_with_inference_var.txt b/crates/compiler/uitest/tests/solve/mutual_recursion_with_inference_var.txt new file mode 100644 index 0000000000..e54c2b3aa3 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/mutual_recursion_with_inference_var.txt @@ -0,0 +1,11 @@ +app "test" provides [main] to "./platform" + +entry = + f : _ -> Str + f = \s -> g s + g = \s -> if Bool.true then s else f s + + g + +main = entry +# ^^^^^ Str -[[g(3)]]-> Str diff --git a/crates/compiler/uitest/tests/solve/nested_open_tag_union.txt b/crates/compiler/uitest/tests/solve/nested_open_tag_union.txt new file mode 100644 index 0000000000..3f12b8f227 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/nested_open_tag_union.txt @@ -0,0 +1,17 @@ +app "test" provides [go] to "./platform" + +Expr : [ + Wrap Expr, + Val I64, +] + +go : Expr -> Expr +go = \e -> +#^^{-1} Expr -[[go(0)]]-> Expr + when P e is + P (Wrap (Val _)) -> Wrap e + + # This branch should force the first argument to `P` and + # the first argument to `Wrap` to be an open tag union. + # This tests checks that we don't regress on that. + P y1 -> Wrap y1 diff --git a/crates/compiler/uitest/tests/solve/opaque_and_alias_unify.txt b/crates/compiler/uitest/tests/solve/opaque_and_alias_unify.txt new file mode 100644 index 0000000000..ec2c19b054 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_and_alias_unify.txt @@ -0,0 +1,9 @@ +app "test" provides [always] to "./platform" + +Effect a := {} -> a + +Task a err : Effect (Result a err) + +always : a -> Task a * +always = \x -> @Effect (\{} -> Ok x) +#^^^^^^{-1} a -[[always(0)]]-> Task a * diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_check.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_check.txt new file mode 100644 index 0000000000..cec2bfc1b8 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_check.txt @@ -0,0 +1,11 @@ +app "test" provides [main] to "./platform" + +entry = + Age := U32 + + v : Age -> U32 + v = \@Age n -> n + v + +main = entry +# ^^^^^ Age -[[v(3)]]-> U32 diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_infer.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_infer.txt new file mode 100644 index 0000000000..f884eea1b9 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_infer.txt @@ -0,0 +1,9 @@ +app "test" provides [main] to "./platform" + +entry = + Age := U32 + + \@Age n -> n + +main = entry +# ^^^^^ Age -[[entry(1)]]-> U32 diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_check.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_check.txt new file mode 100644 index 0000000000..f97d345253 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_check.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + v : Id a -> a + v = \@Id (Id _ n) -> n + + v + +main = entry +# ^^^^^ Id a -[[v(3)]]-> a diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_from_multiple_branches_check.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_from_multiple_branches_check.txt new file mode 100644 index 0000000000..1e4fa11b70 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_from_multiple_branches_check.txt @@ -0,0 +1,17 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + f : Id [A, B, C { a : Str }e] -> Str + f = \id -> + when id is + @Id (Id _ A) -> "" + @Id (Id _ B) -> "" + @Id (Id _ (C { a: "" })) -> "" + @Id (Id _ (C { a: _ })) -> "" # any other string, for exhautiveness + + f + +main = entry +# ^^^^^ Id [A, B, C { a : Str }e] -[[f(3)]]-> Str diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_from_multiple_branches_infer.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_from_multiple_branches_infer.txt new file mode 100644 index 0000000000..29cee40fef --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_from_multiple_branches_infer.txt @@ -0,0 +1,14 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + \id -> + when id is + @Id (Id _ A) -> "" + @Id (Id _ B) -> "" + @Id (Id _ (C { a: "" })) -> "" + @Id (Id _ (C { a: _ })) -> "" # any other string, for exhautiveness + +main = entry +# ^^^^^ Id [A, B, C { a : Str }w_a] -[[entry(1)]]-> Str diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_infer.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_infer.txt new file mode 100644 index 0000000000..d132ba2b51 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_infer.txt @@ -0,0 +1,9 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + \@Id (Id _ n) -> n + +main = entry +# ^^^^^ Id w_a -[[entry(1)]]-> w_a diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_specialized_check.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_specialized_check.txt new file mode 100644 index 0000000000..4ccfb15d8c --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_specialized_check.txt @@ -0,0 +1,14 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + strToBool : Str -> Bool + + v : Id Str -> Bool + v = \@Id (Id _ n) -> strToBool n + + v + +main = entry +# ^^^^^ Id Str -[[v(4)]]-> Bool diff --git a/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_specialized_infer.txt b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_specialized_infer.txt new file mode 100644 index 0000000000..eb7e7f8c7c --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_unwrap_polymorphic_specialized_infer.txt @@ -0,0 +1,11 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + strToBool : Str -> Bool + + \@Id (Id _ n) -> strToBool n + +main = entry +# ^^^^^ Id Str -[[5]]-> Bool diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_check.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_check.txt new file mode 100644 index 0000000000..9ca92ed6af --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_check.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + Age := U32 + + a : Age + a = @Age 21 + + a + +main = entry +# ^^^^^ Age diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_function.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_function.txt new file mode 100644 index 0000000000..ab0f612d95 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_function.txt @@ -0,0 +1,8 @@ +app "test" provides [main] to "./platform" + +entry = + A := U8 + List.map [1, 2, 3] @A + +main = entry +# ^^^^^ List A diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_function_with_inferred_arg.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_function_with_inferred_arg.txt new file mode 100644 index 0000000000..935df316d6 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_function_with_inferred_arg.txt @@ -0,0 +1,8 @@ +app "test" provides [main] to "./platform" + +entry = + A a := a + List.map [1u8, 2u8, 3u8] @A + +main = entry +# ^^^^^ List (A U8) diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_infer.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_infer.txt new file mode 100644 index 0000000000..88a4d61332 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_infer.txt @@ -0,0 +1,9 @@ +app "test" provides [main] to "./platform" + +entry = + Age := U32 + + @Age 21 + +main = entry +# ^^^^^ Age diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_check.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_check.txt new file mode 100644 index 0000000000..f479a460da --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_check.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + a : Id Str + a = @Id (Id 21 "sasha") + + a + +main = entry +# ^^^^^ Id Str diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_from_multiple_branches_check.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_from_multiple_branches_check.txt new file mode 100644 index 0000000000..9ed2033afa --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_from_multiple_branches_check.txt @@ -0,0 +1,16 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + condition : Bool + + v : Id [Y Str, Z Str] + v = + if condition + then @Id (Id 21 (Y "sasha")) + else @Id (Id 21 (Z "felix")) + + v + +main = entry +# ^^^^^ Id [Y Str, Z Str]w_a diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_from_multiple_branches_infer.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_from_multiple_branches_infer.txt new file mode 100644 index 0000000000..2f27b838d1 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_from_multiple_branches_infer.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + condition : Bool + + if condition + then @Id (Id 21 (Y "sasha")) + else @Id (Id 21 (Z "felix")) + +main = entry +# ^^^^^ Id [Y Str, Z Str]w_a diff --git a/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_infer.txt b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_infer.txt new file mode 100644 index 0000000000..2ec51089b8 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/opaque_wrap_polymorphic_infer.txt @@ -0,0 +1,9 @@ +app "test" provides [main] to "./platform" + +entry = + Id n := [Id U32 n] + + @Id (Id 21 "sasha") + +main = entry +# ^^^^^ Id Str diff --git a/crates/compiler/uitest/tests/solve/record_extension_variable_is_alias.txt b/crates/compiler/uitest/tests/solve/record_extension_variable_is_alias.txt new file mode 100644 index 0000000000..82593db7fc --- /dev/null +++ b/crates/compiler/uitest/tests/solve/record_extension_variable_is_alias.txt @@ -0,0 +1,10 @@ +app "test" provides [main] to "./platform" + +entry = + Other a b : { y: a, z: b } + + f : { x : Str }(Other Str Str) + f + +main = entry +# ^^^^^ { x : Str, y : Str, z : Str } diff --git a/crates/compiler/uitest/tests/solve/rosetree_with_result_is_legal_recursive_type.txt b/crates/compiler/uitest/tests/solve/rosetree_with_result_is_legal_recursive_type.txt new file mode 100644 index 0000000000..6419b27fef --- /dev/null +++ b/crates/compiler/uitest/tests/solve/rosetree_with_result_is_legal_recursive_type.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + Rose a : [Rose (Result (List (Rose a)) I64)] + + x : Rose I64 + x = Rose (Ok []) + + x + +main = entry +# ^^^^^ Rose I64 diff --git a/crates/compiler/uitest/tests/solve/self_recursion_with_inference_var.txt b/crates/compiler/uitest/tests/solve/self_recursion_with_inference_var.txt new file mode 100644 index 0000000000..5781ec77a7 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/self_recursion_with_inference_var.txt @@ -0,0 +1,10 @@ +app "test" provides [main] to "./platform" + +entry = + f : _ -> _ + f = \_ -> if Bool.false then "" else f "" + + f + +main = entry +# ^^^^^ Str -[[f(2)]]-> Str diff --git a/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt b/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt new file mode 100644 index 0000000000..7b73ffa9ff --- /dev/null +++ b/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt @@ -0,0 +1,13 @@ +app "test" provides [hash, hash32] to "./platform" + +MHash has + hash : a -> U64 | a has MHash + hash32 : a -> U32 | a has MHash + +Id := U64 has [MHash {hash, hash32}] + +hash = \@Id n -> n +#^^^^{-1} Id#hash(4): Id -[[hash(4)]]-> U64 + +hash32 = \@Id n -> Num.toU32 n +#^^^^^^{-1} Id#hash32(5): Id -[[hash32(5)]]-> U32 diff --git a/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt b/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt new file mode 100644 index 0000000000..33e30ed971 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt @@ -0,0 +1,8 @@ +app "test" provides [hash] to "./platform" + +MHash has hash : a -> U64 | a has MHash + +Id := U64 has [MHash {hash}] + +hash = \@Id n -> n +#^^^^{-1} Id#hash(3): Id -[[hash(3)]]-> U64 diff --git a/crates/compiler/uitest/tests/solve/stdlib_encode_json.txt b/crates/compiler/uitest/tests/solve/stdlib_encode_json.txt new file mode 100644 index 0000000000..4ba5a6df2b --- /dev/null +++ b/crates/compiler/uitest/tests/solve/stdlib_encode_json.txt @@ -0,0 +1,18 @@ +app "test" + imports [Json] + provides [main] to "./platform" + +HelloWorld := {} has [Encoding {toEncoder}] + +toEncoder = \@HelloWorld {} -> + Encode.custom \bytes, fmt -> + bytes + |> Encode.appendWith (Encode.string "Hello, World!\n") fmt + +f = + when Str.fromUtf8 (Encode.toBytes (@HelloWorld {}) Json.toUtf8) is + Ok s -> s + _ -> "" + +main = f +# ^ Str diff --git a/crates/compiler/uitest/tests/solve/tag_extension_variable_is_alias.txt b/crates/compiler/uitest/tests/solve/tag_extension_variable_is_alias.txt new file mode 100644 index 0000000000..713c13776d --- /dev/null +++ b/crates/compiler/uitest/tests/solve/tag_extension_variable_is_alias.txt @@ -0,0 +1,10 @@ +app "test" provides [main] to "./platform" + +entry = + Other : [B, C] + + f : [A]Other + f + +main = entry +# ^^^^^ [A, B, C]* diff --git a/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque.txt b/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque.txt new file mode 100644 index 0000000000..c94370dec2 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque.txt @@ -0,0 +1,15 @@ +app "test" provides [main] to "./platform" + +entry = + Outer k := [Empty, Wrapped k] + + insert : Outer k, k -> Outer k + insert = \m, var -> + when m is + @Outer Empty -> @Outer (Wrapped var) + @Outer (Wrapped _) -> @Outer (Wrapped var) + + insert + +main = entry +# ^^^^^ Outer k, k -[[insert(3)]]-> Outer k diff --git a/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque_infer.txt b/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque_infer.txt new file mode 100644 index 0000000000..cd79fea6c5 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque_infer.txt @@ -0,0 +1,11 @@ +app "test" provides [main] to "./platform" + +entry = + Outer k := [Empty, Wrapped k] + + when (@Outer Empty) is + @Outer Empty -> @Outer (Wrapped "") + @Outer (Wrapped k) -> @Outer (Wrapped k) + +main = entry +# ^^^^^ Outer Str diff --git a/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque_infer_single_ctor.txt b/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque_infer_single_ctor.txt new file mode 100644 index 0000000000..b182e08c72 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/tag_inclusion_behind_opaque_infer_single_ctor.txt @@ -0,0 +1,11 @@ +app "test" provides [main] to "./platform" + +entry = + Outer := [A, B] + + when (@Outer A) is + @Outer A -> @Outer A + @Outer B -> @Outer B + +main = entry +# ^^^^^ Outer diff --git a/crates/compiler/uitest/tests/solve/task_wildcard_wildcard.txt b/crates/compiler/uitest/tests/solve/task_wildcard_wildcard.txt new file mode 100644 index 0000000000..38a57c0d70 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/task_wildcard_wildcard.txt @@ -0,0 +1,11 @@ +app "test" provides [tforever] to "./platform" + +Effect a := {} -> a + +eforever : Effect a -> Effect b + +Task a err : Effect (Result a err) + +tforever : Task val err -> Task * * +tforever = \task -> eforever task +#^^^^^^^^{-1} Task val err -[[tforever(0)]]-> Task * * diff --git a/crates/compiler/uitest/tests/solve/to_float.txt b/crates/compiler/uitest/tests/solve/to_float.txt new file mode 100644 index 0000000000..a8ad977725 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/to_float.txt @@ -0,0 +1,10 @@ +app "test" provides [main] to "./platform" + +entry = + { + toF32: Num.toF32, + toF64: Num.toF64, + } + +main = entry +# ^^^^^ { toF32 : Num * -[[Num.toF32(139)]]-> F32, toF64 : Num w_a -[[Num.toF64(141)]]-> F64 } diff --git a/crates/compiler/uitest/tests/solve/to_int.txt b/crates/compiler/uitest/tests/solve/to_int.txt new file mode 100644 index 0000000000..bcf87a847f --- /dev/null +++ b/crates/compiler/uitest/tests/solve/to_int.txt @@ -0,0 +1,19 @@ +app "test" provides [main] to "./platform" + +entry = + { + toI8: Num.toI8, + toI16: Num.toI16, + toI32: Num.toI32, + toI64: Num.toI64, + toI128: Num.toI128, + toNat: Num.toNat, + toU8: Num.toU8, + toU16: Num.toU16, + toU32: Num.toU32, + toU64: Num.toU64, + toU128: Num.toU128, + } + +main = entry +# ^^^^^ { toI128 : Int * -[[Num.toI128(125)]]-> I128, toI16 : Int w_a -[[Num.toI16(119)]]-> I16, toI32 : Int w_b -[[Num.toI32(121)]]-> I32, toI64 : Int w_c -[[Num.toI64(123)]]-> I64, toI8 : Int w_d -[[Num.toI8(117)]]-> I8, toNat : Int w_e -[[Num.toNat(137)]]-> Nat, toU128 : Int w_f -[[Num.toU128(135)]]-> U128, toU16 : Int w_g -[[Num.toU16(129)]]-> U16, toU32 : Int w_h -[[Num.toU32(131)]]-> U32, toU64 : Int w_i -[[Num.toU64(133)]]-> U64, toU8 : Int w_j -[[Num.toU8(127)]]-> U8 } diff --git a/crates/compiler/uitest/tests/solve/when_branch_and_body_flipflop.txt b/crates/compiler/uitest/tests/solve/when_branch_and_body_flipflop.txt new file mode 100644 index 0000000000..384550a1f0 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/when_branch_and_body_flipflop.txt @@ -0,0 +1,12 @@ +app "test" provides [main] to "./platform" + +entry = + func = \record -> + when record.tag is + A -> { record & tag: B } + B -> { record & tag: A } + + func + +main = entry +# ^^^^^ { tag : [A, B] }w_a -[[func(2)]]-> { tag : [A, B] }w_a diff --git a/crates/compiler/uitest/tests/solve/wrap_recursive_opaque_negative_position.txt b/crates/compiler/uitest/tests/solve/wrap_recursive_opaque_negative_position.txt new file mode 100644 index 0000000000..55996ae134 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/wrap_recursive_opaque_negative_position.txt @@ -0,0 +1,14 @@ +app "test" provides [main] to "./platform" + +entry = + OList := [Nil, Cons {} OList] + + lst : [Cons {} OList] + + olist : OList + olist = (\l -> @OList l) lst + + olist + +main = entry +# ^^^^^ OList diff --git a/crates/compiler/uitest/tests/solve/wrap_recursive_opaque_positive_position.txt b/crates/compiler/uitest/tests/solve/wrap_recursive_opaque_positive_position.txt new file mode 100644 index 0000000000..c0c4ec9667 --- /dev/null +++ b/crates/compiler/uitest/tests/solve/wrap_recursive_opaque_positive_position.txt @@ -0,0 +1,14 @@ +app "test" provides [main] to "./platform" + +entry = + OList := [Nil, Cons {} OList] + + lst : [Cons {} OList] + + olist : OList + olist = @OList lst + + olist + +main = entry +# ^^^^^ OList diff --git a/crates/compiler/unify/src/unify.rs b/crates/compiler/unify/src/unify.rs index 4b6d737dfb..4c3648ed80 100644 --- a/crates/compiler/unify/src/unify.rs +++ b/crates/compiler/unify/src/unify.rs @@ -1359,10 +1359,8 @@ fn separate_union_lambdas( // F2 -> { left: [ [a] ], right: [ [Str] ] } let mut buckets: VecMap = VecMap::with_capacity(fields1.len() + fields2.len()); - let (mut fields_left, mut fields_right) = ( - fields1.iter_all().into_iter().peekable(), - fields2.iter_all().into_iter().peekable(), - ); + let (mut fields_left, mut fields_right) = + (fields1.iter_all().peekable(), fields2.iter_all().peekable()); loop { use std::cmp::Ordering; diff --git a/crates/editor/src/editor/mvc/ed_view.rs b/crates/editor/src/editor/mvc/ed_view.rs index 8e7feacccd..7998439d03 100644 --- a/crates/editor/src/editor/mvc/ed_view.rs +++ b/crates/editor/src/editor/mvc/ed_view.rs @@ -67,8 +67,8 @@ impl RenderedWgpu { } // create text and rectangles based on EdModel's markup_root -pub fn model_to_wgpu<'a>( - ed_model: &'a mut EdModel, +pub fn model_to_wgpu( + ed_model: &mut EdModel, size: &PhysicalSize, txt_coords: Vector2, config: &Config, diff --git a/crates/editor/src/editor/render_ast.rs b/crates/editor/src/editor/render_ast.rs index ac0bcbc764..ae687de017 100644 --- a/crates/editor/src/editor/render_ast.rs +++ b/crates/editor/src/editor/render_ast.rs @@ -16,13 +16,13 @@ use winit::dpi::PhysicalSize; use crate::{editor::config::Config, graphics::colors}; -pub fn build_code_graphics<'a>( +pub fn build_code_graphics( markup_ids: &[MarkNodeId], size: &PhysicalSize, txt_coords: Vector2, config: &Config, glyph_dim_rect: Rect, - mark_node_pool: &'a SlowPool, + mark_node_pool: &SlowPool, ) -> EdResult { let area_bounds = (size.width as f32, size.height as f32); let layout = wgpu_glyph::Layout::default().h_align(wgpu_glyph::HorizontalAlign::Left); diff --git a/crates/editor/src/ui/text/caret_w_select.rs b/crates/editor/src/ui/text/caret_w_select.rs index 951305bb95..c5a72900d8 100644 --- a/crates/editor/src/ui/text/caret_w_select.rs +++ b/crates/editor/src/ui/text/caret_w_select.rs @@ -196,12 +196,7 @@ pub mod test_caret_w_select { } } Rule::text => { - let split_str = elt - .as_span() - .as_str() - .split('\n') - .into_iter() - .collect::>(); + let split_str = elt.as_span().as_str().split('\n').collect::>(); if split_str.len() > 1 { line_nr += split_str.len() - 1; diff --git a/crates/linker/src/elf.rs b/crates/linker/src/elf.rs index a512be51e2..147d3008af 100644 --- a/crates/linker/src/elf.rs +++ b/crates/linker/src/elf.rs @@ -68,7 +68,7 @@ fn collect_roc_definitions<'a>(object: &object::File<'a, &'a [u8]>) -> MutMap { target_offset - virt_base as i64 + rel.1.addend() @@ -1449,14 +1449,14 @@ fn surgery_elf_help( offset += new_section_count * sh_ent_size as usize; let section_headers = load_structs_inplace_mut::>( exec_mmap, - new_sh_offset as usize, + new_sh_offset, sh_num as usize + new_section_count, ); let new_rodata_section_size = new_text_section_offset as u64 - new_rodata_section_offset as u64; let new_rodata_section_virtual_size = new_text_section_vaddr as u64 - new_rodata_section_vaddr as u64; - let new_text_section_vaddr = new_rodata_section_vaddr as u64 + new_rodata_section_size as u64; + let new_text_section_vaddr = new_rodata_section_vaddr as u64 + new_rodata_section_size; let new_text_section_size = new_sh_offset as u64 - new_text_section_offset as u64; // set the new rodata section header @@ -1610,7 +1610,7 @@ fn surgery_elf_help( dynsym_offset as usize + *i as usize * mem::size_of::>(), ); sym.st_shndx = endian::U16::new(LE, new_text_section_index as u16); - sym.st_value = endian::U64::new(LE, func_virt_offset as u64); + sym.st_value = endian::U64::new(LE, func_virt_offset); sym.st_size = endian::U64::new( LE, match app_func_size_map.get(func_name) { @@ -1627,7 +1627,7 @@ fn surgery_elf_help( symtab_offset as usize + *i as usize * mem::size_of::>(), ); sym.st_shndx = endian::U16::new(LE, new_text_section_index as u16); - sym.st_value = endian::U64::new(LE, func_virt_offset as u64); + sym.st_value = endian::U64::new(LE, func_virt_offset); sym.st_size = endian::U64::new( LE, match app_func_size_map.get(func_name) { @@ -1812,7 +1812,7 @@ mod tests { false, ); - std::fs::copy(&preprocessed_host_filename, &dir.join("final")).unwrap(); + std::fs::copy(&preprocessed_host_filename, dir.join("final")).unwrap(); surgery_elf( &roc_app, @@ -1833,7 +1833,7 @@ mod tests { zig_host_app_help(dir, &Triple::from_str("x86_64-unknown-linux-musl").unwrap()); - let output = std::process::Command::new(&dir.join("final")) + let output = std::process::Command::new(dir.join("final")) .current_dir(dir) .output() .unwrap(); diff --git a/crates/linker/src/lib.rs b/crates/linker/src/lib.rs index acc5b617ce..50e08aa313 100644 --- a/crates/linker/src/lib.rs +++ b/crates/linker/src/lib.rs @@ -255,7 +255,7 @@ fn generate_dynamic_lib(target: &Triple, stub_dll_symbols: &[String], stub_lib_p let bytes = crate::generate_dylib::generate(target, stub_dll_symbols) .unwrap_or_else(|e| internal_error!("{e}")); - if let Err(e) = std::fs::write(stub_lib_path, &bytes) { + if let Err(e) = std::fs::write(stub_lib_path, bytes) { internal_error!("failed to write stub lib to {:?}: {e}", stub_lib_path) } @@ -290,7 +290,7 @@ fn generate_import_library(stub_lib_path: &Path, custom_names: &[String]) { // For when we want to do this in-memory in the future. We can also consider using // // > https://github.com/messense/implib-rs - let output = std::process::Command::new(&zig) + let output = std::process::Command::new(zig) .current_dir(stub_lib_path.parent().unwrap()) .args([ "dlltool", diff --git a/crates/linker/src/macho.rs b/crates/linker/src/macho.rs index 33e304120f..f1159caaf9 100644 --- a/crates/linker/src/macho.rs +++ b/crates/linker/src/macho.rs @@ -67,7 +67,7 @@ fn collect_roc_definitions<'a>(object: &object::File<'a, &'a [u8]>) -> MutMap 0 { cmd.fileoff - .set(LittleEndian, old_file_offest + md.added_byte_count as u64); + .set(LittleEndian, old_file_offest + md.added_byte_count); cmd.vmaddr.set( LittleEndian, - cmd.vmaddr.get(NativeEndian) + md.added_byte_count as u64, + cmd.vmaddr.get(NativeEndian) + md.added_byte_count, ); } else { cmd.filesize.set( LittleEndian, - cmd.filesize.get(NativeEndian) + md.added_byte_count as u64, + cmd.filesize.get(NativeEndian) + md.added_byte_count, ); cmd.vmsize.set( LittleEndian, - cmd.vmsize.get(NativeEndian) + md.added_byte_count as u64, + cmd.vmsize.get(NativeEndian) + md.added_byte_count, ); } @@ -831,7 +831,7 @@ fn gen_macho_le( if entry_type == macho::N_ABS || entry_type == macho::N_SECT { entry.n_value.set( LittleEndian, - entry.n_value.get(NativeEndian) + md.added_byte_count as u64, + entry.n_value.get(NativeEndian) + md.added_byte_count, ); } } @@ -1046,7 +1046,7 @@ fn gen_macho_le( cmd.entryoff.set( LittleEndian, - cmd.entryoff.get(NativeEndian) + md.added_byte_count as u64, + cmd.entryoff.get(NativeEndian) + md.added_byte_count, ); } macho::LC_NOTE => { @@ -1058,7 +1058,7 @@ fn gen_macho_le( if cmd.size.get(NativeEndian) > 0 { cmd.offset.set( LittleEndian, - cmd.offset.get(NativeEndian) + md.added_byte_count as u64, + cmd.offset.get(NativeEndian) + md.added_byte_count, ); } } @@ -1397,8 +1397,8 @@ fn surgery_macho_help( }; if let Some(target_offset) = target_offset { - let virt_base = section_virtual_offset as usize + rel.0 as usize; - let base = section_offset as usize + rel.0 as usize; + let virt_base = section_virtual_offset + rel.0 as usize; + let base = section_offset + rel.0 as usize; let target: i64 = match rel.1.kind() { RelocationKind::Relative | RelocationKind::PltRelative => { target_offset - virt_base as i64 + rel.1.addend() diff --git a/crates/linker/src/pe.rs b/crates/linker/src/pe.rs index 784c199edc..68ce5ecd8e 100644 --- a/crates/linker/src/pe.rs +++ b/crates/linker/src/pe.rs @@ -305,10 +305,7 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b let executable = &mut open_mmap_mut(executable_path, md.dynhost_file_size + app_sections_size); let app_code_section_va = md.last_host_section_address - + next_multiple_of( - md.last_host_section_size as usize, - section_alignment as usize, - ) as u64; + + next_multiple_of(md.last_host_section_size as usize, section_alignment) as u64; let mut section_file_offset = md.dynhost_file_size; let mut section_virtual_address = (app_code_section_va - image_base) as u32; @@ -470,9 +467,9 @@ pub(crate) fn surgery_pe(executable_path: &Path, metadata_path: &Path, roc_app_b update_optional_header( executable, md.optional_header_offset, - code_bytes_added as u32, - file_bytes_added as u32, - data_bytes_added as u32, + code_bytes_added, + file_bytes_added, + data_bytes_added, ); let symbols: Vec<_> = symbols @@ -707,7 +704,7 @@ impl Preprocessor { Self { extra_sections_start: section_table_offset as usize - + sections.len() as usize * Self::SECTION_HEADER_WIDTH, + + sections.len() * Self::SECTION_HEADER_WIDTH, extra_sections_width, additional_header_space, additional_reloc_space, @@ -1724,7 +1721,7 @@ mod test { ) .unwrap(); - std::fs::copy(&preprocessed_host_filename, &dir.join("app.exe")).unwrap(); + std::fs::copy(&preprocessed_host_filename, dir.join("app.exe")).unwrap(); surgery_pe(&dir.join("app.exe"), &dir.join("metadata"), &roc_app); } @@ -1739,7 +1736,7 @@ mod test { runner(dir); - let output = std::process::Command::new(&dir.join("app.exe")) + let output = std::process::Command::new(dir.join("app.exe")) .current_dir(dir) .output() .unwrap(); @@ -1908,7 +1905,7 @@ mod test { std::fs::write(dir.join("host.zig"), host_zig.as_bytes()).unwrap(); - let mut command = std::process::Command::new(&zig); + let mut command = std::process::Command::new(zig); command.current_dir(dir).args([ "build-exe", "host.zig", diff --git a/crates/repl_cli/src/repl_state.rs b/crates/repl_cli/src/repl_state.rs index a55e717f6a..d9c70731b3 100644 --- a/crates/repl_cli/src/repl_state.rs +++ b/crates/repl_cli/src/repl_state.rs @@ -596,7 +596,7 @@ fn format_output( let term_width = match dimensions { Some((width, _)) => width.min(VAR_NAME_COLUMN_MAX), - None => VAR_NAME_COLUMN_MAX as usize, + None => VAR_NAME_COLUMN_MAX, }; let expr_with_type = format!("{expr}{EXPR_TYPE_SEPARATOR}{expr_type}"); diff --git a/crates/repl_eval/src/eval.rs b/crates/repl_eval/src/eval.rs index 5e235f674d..1fc06c9291 100644 --- a/crates/repl_eval/src/eval.rs +++ b/crates/repl_eval/src/eval.rs @@ -265,8 +265,8 @@ fn get_tags_vars_and_variant<'a>( (vars_of_tag, union_variant) } -fn expr_of_tag<'a, 'env, M: ReplAppMemory>( - env: &mut Env<'a, 'env>, +fn expr_of_tag<'a, M: ReplAppMemory>( + env: &mut Env<'a, '_>, mem: &'a M, data_addr: usize, tag_name: &TagName, @@ -289,8 +289,8 @@ fn expr_of_tag<'a, 'env, M: ReplAppMemory>( /// Gets the tag ID of a union variant, assuming that the tag ID is stored alongside (after) the /// tag data. The caller is expected to check that the tag ID is indeed stored this way. -fn tag_id_from_data<'a, 'env, M: ReplAppMemory>( - env: &Env<'a, 'env>, +fn tag_id_from_data<'a, M: ReplAppMemory>( + env: &Env<'a, '_>, mem: &M, union_layout: UnionLayout<'a>, data_addr: usize, @@ -947,8 +947,8 @@ fn list_to_ast<'a, M: ReplAppMemory>( Expr::List(Collection::with_items(output)) } -fn single_tag_union_to_ast<'a, 'env, M: ReplAppMemory>( - env: &mut Env<'a, 'env>, +fn single_tag_union_to_ast<'a, M: ReplAppMemory>( + env: &mut Env<'a, '_>, mem: &'a M, addr: usize, field_layouts: &'a [InLayout<'a>], @@ -1004,8 +1004,8 @@ where output } -fn struct_to_ast<'a, 'env, M: ReplAppMemory>( - env: &mut Env<'a, 'env>, +fn struct_to_ast<'a, M: ReplAppMemory>( + env: &mut Env<'a, '_>, mem: &'a M, addr: usize, record_fields: RecordFields, @@ -1130,8 +1130,8 @@ fn struct_to_ast<'a, 'env, M: ReplAppMemory>( } } -fn struct_to_ast_tuple<'a, 'env, M: ReplAppMemory>( - env: &mut Env<'a, 'env>, +fn struct_to_ast_tuple<'a, M: ReplAppMemory>( + env: &mut Env<'a, '_>, mem: &'a M, addr: usize, tuple_elems: TupleElems, diff --git a/crates/repl_wasm/build.rs b/crates/repl_wasm/build.rs index 0ed3b1b4dd..7cb3d02149 100644 --- a/crates/repl_wasm/build.rs +++ b/crates/repl_wasm/build.rs @@ -31,7 +31,7 @@ fn main() { let builtins_host_tempfile = roc_bitcode::host_wasm_tempfile() .expect("failed to write host builtins object to tempfile"); - let output = Command::new(&zig_executable()) + let output = Command::new(zig_executable()) .args([ "wasm-ld", builtins_host_tempfile.path().to_str().unwrap(), @@ -67,7 +67,7 @@ fn build_wasm_platform(out_dir: &str, source_path: &str) -> PathBuf { let mut platform_obj = PathBuf::from(out_dir).join(PLATFORM_FILENAME); platform_obj.set_extension(OBJECT_EXTENSION); - Command::new(&zig_executable()) + Command::new(zig_executable()) .args([ "build-lib", "-target", diff --git a/crates/vendor/morphic_lib/src/util/bytes_id.rs b/crates/vendor/morphic_lib/src/util/bytes_id.rs index b75d618271..cbcd00fbc5 100644 --- a/crates/vendor/morphic_lib/src/util/bytes_id.rs +++ b/crates/vendor/morphic_lib/src/util/bytes_id.rs @@ -15,7 +15,7 @@ macro_rules! bytes_id { $owned_vis struct $owned($owned_vis ::smallvec::SmallVec<[u8; 23]>); impl $owned { - fn borrowed<'a>(&'a self) -> $borrowed<'a> { + fn borrowed(&self) -> $borrowed<'_> { $borrowed(&self.0) } } diff --git a/crates/vendor/pathfinding/src/lib.rs b/crates/vendor/pathfinding/src/lib.rs index 8044a7fed9..6846cc276c 100644 --- a/crates/vendor/pathfinding/src/lib.rs +++ b/crates/vendor/pathfinding/src/lib.rs @@ -219,7 +219,7 @@ where }) .collect(); if prev_group.is_empty() { - let remaining: Vec = preds_map.into_iter().map(|(node, _)| node).collect(); + let remaining: Vec = preds_map.into_keys().collect(); return Err((Vec::new(), remaining)); } for node in &prev_group { @@ -241,7 +241,7 @@ where } groups.push(mem::replace(&mut prev_group, next_group)); if prev_group.is_empty() { - let remaining: Vec = preds_map.into_iter().map(|(node, _)| node).collect(); + let remaining: Vec = preds_map.into_keys().collect(); return Err((groups, remaining)); } } diff --git a/crates/wasi-libc-sys/build.rs b/crates/wasi-libc-sys/build.rs index 1ef3bda1ea..74a2cd6a37 100644 --- a/crates/wasi-libc-sys/build.rs +++ b/crates/wasi-libc-sys/build.rs @@ -38,7 +38,7 @@ fn main() { .unwrap(); // Copy libc to where Cargo expects the output of this crate - fs::copy(&libc_path, &out_file).unwrap(); + fs::copy(libc_path, &out_file).unwrap(); println!( "cargo:rustc-env=WASI_LIBC_PATH={}", diff --git a/crates/wasm_interp/src/instance.rs b/crates/wasm_interp/src/instance.rs index 036d092597..8454a384d1 100644 --- a/crates/wasm_interp/src/instance.rs +++ b/crates/wasm_interp/src/instance.rs @@ -948,7 +948,7 @@ impl<'a, I: ImportDispatcher> Instance<'a, I> { let memory_index = self.fetch_immediate_u32(module); assert_eq!(memory_index, 0); let old_bytes = self.memory.len() as u32; - let old_pages = old_bytes / MemorySection::PAGE_SIZE as u32; + let old_pages = old_bytes / MemorySection::PAGE_SIZE; let grow_pages = self.value_store.pop_u32()?; let grow_bytes = grow_pages * MemorySection::PAGE_SIZE; let new_bytes = old_bytes + grow_bytes; @@ -1700,7 +1700,7 @@ impl<'a, I: ImportDispatcher> Instance<'a, I> { } else { // For calls, we print special debug stuff in do_call let base = self.current_frame.locals_start + self.current_frame.locals_count; - let slice = self.value_store.get_slice(base as usize); + let slice = self.value_store.get_slice(base); eprintln!("{:06x} {:17} {:x?}", file_offset, debug_string, slice); } let is_return = op_code == RETURN || (op_code == END && implicit_return); diff --git a/crates/wasm_interp/src/tests/test_basics.rs b/crates/wasm_interp/src/tests/test_basics.rs index 94791ee696..c0b56cec85 100644 --- a/crates/wasm_interp/src/tests/test_basics.rs +++ b/crates/wasm_interp/src/tests/test_basics.rs @@ -37,7 +37,7 @@ fn test_loop_help(end: i32, expected: i32) { // loop buf.push(OpCode::LOOP as u8); - buf.push(ValueType::VOID as u8); + buf.push(ValueType::VOID); // local.get $i buf.push(OpCode::GETLOCAL as u8); @@ -135,7 +135,7 @@ fn test_if_else_help(condition: i32, expected: i32) { // if buf.push(OpCode::IF as u8); - buf.push(ValueType::VOID as u8); + buf.push(ValueType::VOID); // i32.const 111 buf.push(OpCode::I32CONST as u8); @@ -599,7 +599,7 @@ fn test_call_return_no_args() { ValueType::I32 as u8, OpCode::BLOCK as u8, /* */ // call from inside a block. callee's implicit return should still work correctly. - ValueType::VOID as u8, + ValueType::VOID, OpCode::CALL as u8, 1, // function 1 OpCode::SETLOCAL as u8, diff --git a/www/generate_tutorial/src/input/tutorial.md b/www/generate_tutorial/src/input/tutorial.md index 1688ec26c9..8bf03a296e 100644 --- a/www/generate_tutorial/src/input/tutorial.md +++ b/www/generate_tutorial/src/input/tutorial.md @@ -1978,3 +1978,8 @@ Here are various Roc expressions involving operators, and what they desugar to. | a \|> b | `b a` | | a b c \|> f x y | `f (a b c) x y` | + ### [Language Keywords](#language-keywords) {#language-keywords} + +These are all of the language keywords supported by Roc; + +`if`,`then`,`else`,`when`,`as`,`is`,`dbg`,`expect`,`expect-fx`,`crash`,`interface`,`app`,`package`,`platform`,`hosted`,`exposes`,`imports`,`with`,`generates`,`package`,`packages`,`requires`,`provides`,`to`