diff --git a/Cargo.lock b/Cargo.lock index aaffda7e4f3..293f0fbe35f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2393,6 +2393,7 @@ dependencies = [ "bumpalo", "indoc", "pretty_assertions", + "roc_can_solo", "roc_collections", "roc_error_macros", "roc_exhaustive", @@ -2408,6 +2409,25 @@ dependencies = [ "ven_pretty", ] +[[package]] +name = "roc_can_solo" +version = "0.0.1" +dependencies = [ + "bitvec", + "bumpalo", + "roc_collections", + "roc_error_macros", + "roc_module", + "roc_parse", + "roc_problem", + "roc_region", + "roc_serialize", + "roc_types", + "soa", + "static_assertions", + "ven_pretty", +] + [[package]] name = "roc_checkmate" version = "0.0.1" @@ -2805,6 +2825,7 @@ dependencies = [ "pretty_assertions", "roc_builtins", "roc_can", + "roc_can_solo", "roc_collections", "roc_constrain", "roc_derive", @@ -2828,6 +2849,8 @@ dependencies = [ name = "roc_load_internal" version = "0.0.1" dependencies = [ + "base64-url", + "blake3", "bumpalo", "crossbeam", "indoc", @@ -2836,6 +2859,7 @@ dependencies = [ "pretty_assertions", "roc_builtins", "roc_can", + "roc_can_solo", "roc_checkmate", "roc_collections", "roc_constrain", @@ -3872,6 +3896,7 @@ dependencies = [ "pretty_assertions", "roc_builtins", "roc_can", + "roc_can_solo", "roc_collections", "roc_constrain", "roc_derive", @@ -4016,6 +4041,7 @@ dependencies = [ "indoc", "pretty_assertions", "roc_can", + "roc_can_solo", "roc_collections", "roc_error_macros", "roc_fmt", diff --git a/Cargo.toml b/Cargo.toml index f398cc43bd9..b842dd746ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ - "crates/build/specialize_types", + "crates/build/*", + "crates/check/*", "crates/compiler/*", "crates/vendor/*", "crates/fs", @@ -174,6 +175,7 @@ roc_bitcode_bc = { path = "crates/compiler/builtins/bitcode/bc" } roc_build = { path = "crates/compiler/build" } roc_builtins = { path = "crates/compiler/builtins" } roc_can = { path = "crates/compiler/can" } +roc_can_solo = { path = "crates/check/can_solo" } roc_checkmate = { path = "crates/compiler/checkmate" } roc_checkmate_schema = { path = "crates/compiler/checkmate_schema" } roc_cli = { path = "crates/cli" } diff --git a/crates/check/can_solo/Cargo.toml b/crates/check/can_solo/Cargo.toml new file mode 100644 index 00000000000..914d8f8f760 --- /dev/null +++ b/crates/check/can_solo/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "roc_can_solo" +description = "Canonicalize a Roc module in preparation for typechecking without any knowledge of other modules." + +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[dependencies] +roc_collections.workspace = true +roc_error_macros.workspace = true +roc_module.workspace = true +roc_parse.workspace = true +roc_problem.workspace = true +roc_region.workspace = true +roc_serialize.workspace = true +roc_types.workspace = true +ven_pretty.workspace = true +bitvec.workspace = true +bumpalo.workspace = true +static_assertions.workspace = true +soa.workspace = true diff --git a/crates/check/can_solo/src/desugar.rs b/crates/check/can_solo/src/desugar.rs new file mode 100644 index 00000000000..34262ee7bb3 --- /dev/null +++ b/crates/check/can_solo/src/desugar.rs @@ -0,0 +1,1858 @@ +#![allow(clippy::manual_map)] + +use crate::env::SoloEnv; +use crate::scope::SoloScope; + +use bumpalo::collections::Vec; +use roc_error_macros::internal_error; +use roc_module::called_via::{BinOp, CalledVia}; +use roc_module::ident::ModuleName; +use roc_parse::ast::Expr::{self, *}; +use roc_parse::ast::{ + AssignedField, Collection, Defs, ModuleImportParams, Pattern, ResultTryKind, StrLiteral, + StrSegment, ValueDef, WhenBranch, +}; +use roc_problem::can::Problem; +use roc_region::all::{Loc, Region}; + +// BinOp precedence logic adapted from Gluon by Markus Westerlind +// https://github.com/gluon-lang/gluon - license information can be found in +// the LEGAL_DETAILS file in the root directory of this distribution. +// +// Thank you, Markus! + +/// Desugar a single binary operation. +/// +/// When using this function, don't desugar `left` and `right` before calling so that +/// we can properly desugar `|> try` expressions! +fn new_op_call_expr<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + left: &'a Loc>, + loc_op: Loc, + right: &'a Loc>, +) -> Loc> { + let region = Region::span_across(&left.region, &right.region); + + let value = match loc_op.value { + // Rewrite the Pizza operator into an Apply + BinOp::Pizza => { + // Allow `left |> try (optional)` to desugar to `try left (optional)` + let right_without_spaces = without_spaces(&right.value); + match right_without_spaces { + Try => { + let desugared_left = desugar_expr(env, scope, left); + return Loc::at( + region, + Expr::LowLevelTry(desugared_left, ResultTryKind::KeywordPrefix), + ); + } + PncApply(&Loc { value: Try, .. }, arguments) => { + let try_fn = desugar_expr(env, scope, arguments.items.first().unwrap()); + + let mut args = Vec::with_capacity_in(arguments.len(), env.arena); + args.push(desugar_expr(env, scope, left)); + args.extend( + arguments + .iter() + .skip(1) + .map(|a| desugar_expr(env, scope, a)), + ); + + return Loc::at( + region, + Expr::LowLevelTry( + env.arena.alloc(Loc::at( + region, + Expr::Apply(try_fn, args.into_bump_slice(), CalledVia::Try), + )), + ResultTryKind::KeywordPrefix, + ), + ); + } + Apply(&Loc { value: Try, .. }, arguments, _called_via) => { + let try_fn = desugar_expr(env, scope, arguments.first().unwrap()); + + let mut args = Vec::with_capacity_in(arguments.len(), env.arena); + args.push(desugar_expr(env, scope, left)); + args.extend( + arguments + .iter() + .skip(1) + .map(|a| desugar_expr(env, scope, a)), + ); + + return Loc::at( + region, + Expr::LowLevelTry( + env.arena.alloc(Loc::at( + region, + Expr::Apply(try_fn, args.into_bump_slice(), CalledVia::Try), + )), + ResultTryKind::KeywordPrefix, + ), + ); + } + TrySuffix(fn_expr) => { + let loc_fn = env.arena.alloc(Loc::at(right.region, **fn_expr)); + let function = desugar_expr(env, scope, loc_fn); + + return Loc::at( + region, + LowLevelTry( + env.arena.alloc(Loc::at( + region, + Expr::Apply( + function, + env.arena.alloc([desugar_expr(env, scope, left)]), + CalledVia::Try, + ), + )), + ResultTryKind::OperatorSuffix, + ), + ); + } + PncApply( + &Loc { + value: TrySuffix(fn_expr), + region: fn_region, + }, + loc_args, + ) => { + let loc_fn = env.arena.alloc(Loc::at(fn_region, *fn_expr)); + let function = desugar_expr(env, scope, loc_fn); + + let mut desugared_args = Vec::with_capacity_in(loc_args.len() + 1, env.arena); + desugared_args.push(desugar_expr(env, scope, left)); + for loc_arg in loc_args.items { + desugared_args.push(desugar_expr(env, scope, loc_arg)); + } + + return Loc::at( + region, + LowLevelTry( + env.arena.alloc(Loc::at( + region, + Expr::Apply( + function, + desugared_args.into_bump_slice(), + CalledVia::Try, + ), + )), + ResultTryKind::OperatorSuffix, + ), + ); + } + Apply( + &Loc { + value: TrySuffix(fn_expr), + region: fn_region, + }, + loc_args, + _called_via, + ) => { + let loc_fn = env.arena.alloc(Loc::at(fn_region, *fn_expr)); + let function = desugar_expr(env, scope, loc_fn); + + let mut desugared_args = Vec::with_capacity_in(loc_args.len() + 1, env.arena); + desugared_args.push(desugar_expr(env, scope, left)); + for loc_arg in &loc_args[..] { + desugared_args.push(desugar_expr(env, scope, loc_arg)); + } + + return Loc::at( + region, + LowLevelTry( + env.arena.alloc(Loc::at( + region, + Expr::Apply( + function, + desugared_args.into_bump_slice(), + CalledVia::Try, + ), + )), + ResultTryKind::OperatorSuffix, + ), + ); + } + _ => {} + } + + let left = desugar_expr(env, scope, left); + let right = desugar_expr(env, scope, right); + + match right.value { + Apply(function, arguments, _called_via) => { + let mut args = Vec::with_capacity_in(1 + arguments.len(), env.arena); + + args.push(left); + args.extend(arguments.iter()); + + let args = args.into_bump_slice(); + + Apply(function, args, CalledVia::BinOp(BinOp::Pizza)) + } + PncApply(function, arguments) => { + let mut args = Vec::with_capacity_in(1 + arguments.len(), env.arena); + + args.push(left); + args.extend(arguments.iter()); + + let args = args.into_bump_slice(); + + Apply(function, args, CalledVia::BinOp(BinOp::Pizza)) + } + Dbg => *desugar_dbg_expr(env, scope, left, region), + _ => { + // e.g. `1 |> (if b then (\a -> a) else (\c -> c))` + Apply( + right, + env.arena.alloc([left]), + CalledVia::BinOp(BinOp::Pizza), + ) + } + } + } + BinOp::DoubleQuestion => { + let left = desugar_expr(env, scope, left); + let right = desugar_expr(env, scope, right); + + let ok_var = env.arena.alloc_str(&format!( + "#double_question_ok_{}_{}", + left.region.start().offset, + left.region.end().offset + )); + + let ok_branch_pattern_args = env + .arena + .alloc([Loc::at(left.region, Pattern::Identifier { ident: ok_var })]); + let ok_branch_patterns = env.arena.alloc([Loc::at( + left.region, + Pattern::PncApply( + env.arena.alloc(Loc::at(left.region, Pattern::Tag("Ok"))), + Collection::with_items(ok_branch_pattern_args), + ), + )]); + let ok_branch = &*env.arena.alloc(WhenBranch { + patterns: ok_branch_patterns, + value: Loc::at( + left.region, + Expr::Var { + module_name: "", + ident: ok_var, + }, + ), + guard: None, + }); + + let err_branch_pattern_args = env + .arena + .alloc([(Loc::at(right.region, Pattern::Underscore("")))]); + let err_branch_patterns = env.arena.alloc([Loc::at( + right.region, + Pattern::PncApply( + env.arena.alloc(Loc::at(left.region, Pattern::Tag("Err"))), + Collection::with_items(err_branch_pattern_args), + ), + )]); + let err_branch = &*env.arena.alloc(WhenBranch { + patterns: err_branch_patterns, + value: *right, + guard: None, + }); + + When(left, &*env.arena.alloc([ok_branch, err_branch])) + } + BinOp::SingleQuestion => { + let left = desugar_expr(env, scope, left); + let right = desugar_expr(env, scope, right); + + let ok_var = env.arena.alloc_str(&format!( + "#single_question_ok_{}_{}", + left.region.start().offset, + left.region.end().offset + )); + + let ok_branch_pattern_args = env + .arena + .alloc([Loc::at(left.region, Pattern::Identifier { ident: ok_var })]); + let ok_branch_patterns = env.arena.alloc([Loc::at( + left.region, + Pattern::PncApply( + env.arena.alloc(Loc::at(left.region, Pattern::Tag("Ok"))), + Collection::with_items(ok_branch_pattern_args), + ), + )]); + let ok_branch = &*env.arena.alloc(WhenBranch { + patterns: ok_branch_patterns, + value: Loc::at( + left.region, + Expr::Var { + module_name: "", + ident: ok_var, + }, + ), + guard: None, + }); + + let err_var = env.arena.alloc_str(&format!( + "#single_question_err_{}_{}", + left.region.start().offset, + left.region.end().offset + )); + + let err_branch_pattern_args = env + .arena + .alloc([(Loc::at(right.region, Pattern::Identifier { ident: err_var }))]); + let err_branch_patterns = env.arena.alloc([Loc::at( + right.region, + Pattern::PncApply( + env.arena.alloc(Loc::at(left.region, Pattern::Tag("Err"))), + Collection::with_items(err_branch_pattern_args), + ), + )]); + let map_err_expr = &*env.arena.alloc(Loc::at( + right.region, + Expr::PncApply( + right, + Collection::with_items(&*env.arena.alloc([&*env.arena.alloc(Loc::at( + left.region, + Expr::Var { + module_name: "", + ident: err_var, + }, + ))])), + ), + )); + let err_branch = &*env.arena.alloc(WhenBranch { + patterns: err_branch_patterns, + value: Loc::at( + region, + Expr::Return( + env.arena.alloc(Loc::at( + region, + Expr::PncApply( + env.arena.alloc(Loc::at(region, Expr::Tag("Err"))), + Collection::with_items(&*env.arena.alloc([map_err_expr])), + ), + )), + None, + ), + ), + guard: None, + }); + + When(left, &*env.arena.alloc([ok_branch, err_branch])) + } + BinOp::And => { + let left = desugar_expr(env, scope, left); + let right = desugar_expr(env, scope, right); + + Expr::If { + if_thens: env.arena.alloc([(*left, *right)]), + final_else: env.arena.alloc(Loc::at( + right.region, + Expr::Var { + module_name: ModuleName::BOOL, + ident: "false", + }, + )), + indented_else: false, + } + } + BinOp::Or => { + let left = desugar_expr(env, scope, left); + let right = desugar_expr(env, scope, right); + + Expr::If { + if_thens: env.arena.alloc([( + *left, + Loc::at( + right.region, + Expr::Var { + module_name: ModuleName::BOOL, + ident: "true", + }, + ), + )]), + final_else: right, + indented_else: false, + } + } + binop => { + let left = desugar_expr(env, scope, left); + let right = desugar_expr(env, scope, right); + + // This is a normal binary operator like (+), so desugar it + // into the appropriate function call. + let (module_name, ident) = binop_to_function(binop); + + let args = env.arena.alloc([left, right]); + + let loc_expr = env.arena.alloc(Loc { + value: Expr::Var { module_name, ident }, + region: loc_op.region, + }); + + Apply(loc_expr, args, CalledVia::BinOp(binop)) + } + }; + + Loc { region, value } +} + +fn without_spaces<'a>(expr: &'a Expr<'a>) -> &'a Expr<'a> { + match expr { + Expr::SpaceBefore(inner, _) | Expr::SpaceAfter(inner, _) => without_spaces(inner), + _ => expr, + } +} + +fn desugar_value_def<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + def: &'a ValueDef<'a>, +) -> ValueDef<'a> { + use ValueDef::*; + + match def { + Body(loc_pattern, loc_expr) => Body( + desugar_loc_pattern(env, scope, loc_pattern), + desugar_expr(env, scope, loc_expr), + ), + Annotation(ann_pattern, ann_type) => { + Annotation(*desugar_loc_pattern(env, scope, ann_pattern), *ann_type) + } + AnnotatedBody { + ann_pattern, + ann_type, + lines_between, + body_pattern, + body_expr, + } => AnnotatedBody { + ann_pattern: desugar_loc_pattern(env, scope, ann_pattern), + ann_type, + lines_between, + body_pattern: desugar_loc_pattern(env, scope, body_pattern), + body_expr: desugar_expr(env, scope, body_expr), + }, + + Dbg { + condition, + preceding_comment, + } => { + let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition)); + Dbg { + condition: desugared_condition, + preceding_comment: *preceding_comment, + } + } + Expect { + condition, + preceding_comment, + } => { + let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition)); + Expect { + condition: desugared_condition, + preceding_comment: *preceding_comment, + } + } + ModuleImport(roc_parse::ast::ModuleImport { + before_name, + name, + params, + alias, + exposed, + }) => { + let desugared_params = + params.map(|ModuleImportParams { before, params }| ModuleImportParams { + before, + params: params.map(|params| desugar_field_collection(env, scope, *params)), + }); + + ModuleImport(roc_parse::ast::ModuleImport { + before_name, + name: *name, + params: desugared_params, + alias: *alias, + exposed: *exposed, + }) + } + IngestedFileImport(_) => *def, + + StmtAfterExpr => internal_error!( + "StmtAfterExpression is only created during desugaring, so it shouldn't exist here." + ), + + Stmt(stmt_expr) => Stmt(desugar_expr(env, scope, stmt_expr)), + } +} + +pub fn desugar_defs_node_values<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + defs: &mut roc_parse::ast::Defs<'a>, +) { + for value_def in defs.value_defs.iter_mut() { + *value_def = desugar_value_def(env, scope, env.arena.alloc(*value_def)); + } +} + +/// Reorder the expression tree based on operator precedence and associativity rules, +/// then replace the BinOp nodes with Apply nodes. Also drop SpaceBefore and SpaceAfter nodes. +pub fn desugar_expr<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + loc_expr: &'a Loc>, +) -> &'a Loc> { + match &loc_expr.value { + Float(..) + | Num(..) + | NonBase10Int { .. } + | SingleQuote(_) + | Var { .. } + | AccessorFunction(_) + | Underscore { .. } + | MalformedIdent(_, _) + | PrecedenceConflict { .. } + | EmptyRecordBuilder(_) + | SingleFieldRecordBuilder(_) + | OptionalFieldInRecordBuilder { .. } + | Tag(_) + | OpaqueRef(_) + | Crash + | Try => loc_expr, + + Str(str_literal) => match str_literal { + StrLiteral::PlainLine(_) => loc_expr, + StrLiteral::Line(segments) => { + let region = loc_expr.region; + let value = Str(StrLiteral::Line(desugar_str_segments(env, scope, segments))); + + env.arena.alloc(Loc { region, value }) + } + StrLiteral::Block(lines) => { + let region = loc_expr.region; + let mut new_lines = Vec::with_capacity_in(lines.len(), env.arena); + for segments in lines.iter() { + new_lines.push(desugar_str_segments(env, scope, segments)); + } + let value = Str(StrLiteral::Block(new_lines.into_bump_slice())); + + env.arena.alloc(Loc { region, value }) + } + }, + + TupleAccess(sub_expr, paths) => { + let region = loc_expr.region; + let loc_sub_expr = Loc { + region, + value: **sub_expr, + }; + let value = TupleAccess( + &desugar_expr(env, scope, env.arena.alloc(loc_sub_expr)).value, + paths, + ); + + env.arena.alloc(Loc { region, value }) + } + TrySuffix(sub_expr) => { + let intermediate = env.arena.alloc(Loc::at(loc_expr.region, **sub_expr)); + let new_sub_loc_expr = desugar_expr(env, scope, intermediate); + + env.arena.alloc(Loc::at( + loc_expr.region, + LowLevelTry(new_sub_loc_expr, ResultTryKind::OperatorSuffix), + )) + } + RecordAccess(sub_expr, paths) => { + let region = loc_expr.region; + let loc_sub_expr = Loc { + region, + value: **sub_expr, + }; + let value = RecordAccess( + &desugar_expr(env, scope, env.arena.alloc(loc_sub_expr)).value, + paths, + ); + + env.arena.alloc(Loc { region, value }) + } + List(items) => { + let mut new_items = Vec::with_capacity_in(items.len(), env.arena); + + for item in items.iter() { + new_items.push(desugar_expr(env, scope, item)); + } + let new_items = new_items.into_bump_slice(); + let value: Expr<'a> = List(items.replace_items(new_items)); + + env.arena.alloc(Loc { + region: loc_expr.region, + value, + }) + } + Record(fields) => { + let fields = desugar_field_collection(env, scope, *fields); + env.arena.alloc(Loc { + region: loc_expr.region, + value: Record(fields), + }) + } + Tuple(fields) => { + let mut allocated = Vec::with_capacity_in(fields.len(), env.arena); + for field in fields.iter() { + let expr = desugar_expr(env, scope, field); + allocated.push(expr); + } + let fields = fields.replace_items(allocated.into_bump_slice()); + env.arena.alloc(Loc { + region: loc_expr.region, + value: Tuple(fields), + }) + } + RecordUpdate { fields, update } => { + // NOTE the `update` field is always a `Var { .. }`, we only desugar it to get rid of + // any spaces before/after + let new_update = desugar_expr(env, scope, update); + + let mut allocated = Vec::with_capacity_in(fields.len(), env.arena); + for field in fields.iter() { + let value = desugar_field(env, scope, &field.value); + allocated.push(Loc { + value, + region: field.region, + }); + } + let new_fields = fields.replace_items(allocated.into_bump_slice()); + + env.arena.alloc(Loc { + region: loc_expr.region, + value: RecordUpdate { + update: new_update, + fields: new_fields, + }, + }) + } + RecordUpdater(field_name) => { + let region = loc_expr.region; + + let closure_body = RecordUpdate { + update: env.arena.alloc(Loc { + region, + value: Expr::Var { + module_name: "", + ident: "#record_updater_record", + }, + }), + fields: Collection::with_items( + Vec::from_iter_in( + [Loc::at( + region, + AssignedField::RequiredValue( + Loc::at(region, field_name), + &[], + &*env.arena.alloc(Loc { + region, + value: Expr::Var { + module_name: "", + ident: "#record_updater_field", + }, + }), + ), + )], + env.arena, + ) + .into_bump_slice(), + ), + }; + + env.arena.alloc(Loc { + region, + value: Closure( + env.arena.alloc_slice_copy(&[ + Loc::at( + region, + Pattern::Identifier { + ident: "#record_updater_record", + }, + ), + Loc::at( + region, + Pattern::Identifier { + ident: "#record_updater_field", + }, + ), + ]), + env.arena.alloc(Loc::at(region, closure_body)), + ), + }) + } + Closure(loc_patterns, loc_ret) => env.arena.alloc(Loc { + region: loc_expr.region, + value: Closure( + desugar_loc_patterns(env, scope, loc_patterns), + desugar_expr(env, scope, loc_ret), + ), + }), + RecordBuilder { mapper, fields } => { + // NOTE the `mapper` is always a `Var { .. }`, we only desugar it to get rid of + // any spaces before/after + let new_mapper = desugar_expr(env, scope, mapper); + + if fields.is_empty() { + return env.arena.alloc(Loc { + value: EmptyRecordBuilder(loc_expr), + region: loc_expr.region, + }); + } else if fields.len() == 1 { + return env.arena.alloc(Loc { + value: SingleFieldRecordBuilder(loc_expr), + region: loc_expr.region, + }); + } + + struct FieldData<'d> { + name: Loc<&'d str>, + value: &'d Loc>, + ignored: bool, + } + + let mut field_data = Vec::with_capacity_in(fields.len(), env.arena); + + for field in fields.items { + let desugared_field = desugar_field(env, scope, &field.value); + let (name, value, ignored) = match desugared_field { + AssignedField::RequiredValue(loc_name, _, loc_val) => { + (loc_name, loc_val, false) + } + AssignedField::IgnoredValue(loc_name, _, loc_val) => (loc_name, loc_val, true), + AssignedField::LabelOnly(loc_name) => ( + loc_name, + &*env.arena.alloc(Loc { + region: loc_name.region, + value: Expr::Var { + module_name: "", + ident: loc_name.value, + }, + }), + false, + ), + AssignedField::OptionalValue(loc_name, _, loc_val) => { + return env.arena.alloc(Loc { + region: loc_expr.region, + value: OptionalFieldInRecordBuilder(env.arena.alloc(loc_name), loc_val), + }); + } + AssignedField::SpaceBefore(_, _) | AssignedField::SpaceAfter(_, _) => { + unreachable!("Should have been desugared in `desugar_field`") + } + }; + + field_data.push(FieldData { + name, + value, + ignored, + }); + } + + let closure_arg_from_field = + |FieldData { + name, + value: _, + ignored, + }: &FieldData<'a>| Loc { + region: name.region, + value: if *ignored { + Pattern::Underscore(name.value) + } else { + Pattern::Identifier { + ident: env.arena.alloc_str(&format!("#{}", name.value)), + } + }, + }; + + let combiner_closure_in_region = |region| { + let closure_body = Tuple(Collection::with_items( + Vec::from_iter_in( + [ + &*env.arena.alloc(Loc::at( + region, + Expr::Var { + module_name: "", + ident: "#record_builder_closure_arg_a", + }, + )), + &*env.arena.alloc(Loc::at( + region, + Expr::Var { + module_name: "", + ident: "#record_builder_closure_arg_b", + }, + )), + ], + env.arena, + ) + .into_bump_slice(), + )); + + env.arena.alloc(Loc::at( + region, + Closure( + env.arena.alloc_slice_copy(&[ + Loc::at( + region, + Pattern::Identifier { + ident: "#record_builder_closure_arg_a", + }, + ), + Loc::at( + region, + Pattern::Identifier { + ident: "#record_builder_closure_arg_b", + }, + ), + ]), + env.arena.alloc(Loc::at(region, closure_body)), + ), + )) + }; + + let closure_args = { + if field_data.len() == 2 { + env.arena.alloc_slice_copy(&[ + closure_arg_from_field(&field_data[0]), + closure_arg_from_field(&field_data[1]), + ]) + } else { + let second_to_last_arg = + closure_arg_from_field(&field_data[field_data.len() - 2]); + let last_arg = closure_arg_from_field(&field_data[field_data.len() - 1]); + + let mut second_arg = Pattern::Tuple(Collection::with_items( + env.arena.alloc_slice_copy(&[second_to_last_arg, last_arg]), + )); + let mut second_arg_region = + Region::span_across(&second_to_last_arg.region, &last_arg.region); + + for index in (1..(field_data.len() - 2)).rev() { + second_arg = + Pattern::Tuple(Collection::with_items(env.arena.alloc_slice_copy(&[ + closure_arg_from_field(&field_data[index]), + Loc::at(second_arg_region, second_arg), + ]))); + second_arg_region = + Region::span_across(&field_data[index].name.region, &second_arg_region); + } + + env.arena.alloc_slice_copy(&[ + closure_arg_from_field(&field_data[0]), + Loc::at(second_arg_region, second_arg), + ]) + } + }; + + let record_val = Record(Collection::with_items( + Vec::from_iter_in( + field_data + .iter() + .filter(|field| !field.ignored) + .map(|field| { + Loc::at( + field.name.region, + AssignedField::RequiredValue( + field.name, + &[], + env.arena.alloc(Loc::at( + field.name.region, + Expr::Var { + module_name: "", + ident: env + .arena + .alloc_str(&format!("#{}", field.name.value)), + }, + )), + ), + ) + }), + env.arena, + ) + .into_bump_slice(), + )); + + let record_combiner_closure = env.arena.alloc(Loc { + region: loc_expr.region, + value: Closure( + closure_args, + env.arena.alloc(Loc::at(loc_expr.region, record_val)), + ), + }); + + if field_data.len() == 2 { + return env.arena.alloc(Loc { + region: loc_expr.region, + value: Apply( + new_mapper, + env.arena.alloc_slice_copy(&[ + field_data[0].value, + field_data[1].value, + record_combiner_closure, + ]), + CalledVia::RecordBuilder, + ), + }); + } + + let mut inner_combined = env.arena.alloc(Loc { + region: Region::span_across( + &field_data[field_data.len() - 2].value.region, + &field_data[field_data.len() - 1].value.region, + ), + value: Apply( + new_mapper, + env.arena.alloc_slice_copy(&[ + field_data[field_data.len() - 2].value, + field_data[field_data.len() - 1].value, + combiner_closure_in_region(loc_expr.region), + ]), + CalledVia::RecordBuilder, + ), + }); + + for index in (1..(field_data.len() - 2)).rev() { + inner_combined = env.arena.alloc(Loc { + region: Region::span_across( + &field_data[index].value.region, + &inner_combined.region, + ), + value: Apply( + new_mapper, + env.arena.alloc_slice_copy(&[ + field_data[index].value, + inner_combined, + combiner_closure_in_region(loc_expr.region), + ]), + CalledVia::RecordBuilder, + ), + }); + } + + env.arena.alloc(Loc { + region: loc_expr.region, + value: Apply( + new_mapper, + env.arena.alloc_slice_copy(&[ + field_data[0].value, + inner_combined, + record_combiner_closure, + ]), + CalledVia::RecordBuilder, + ), + }) + } + BinOps(lefts, right) => desugar_bin_ops(env, scope, loc_expr.region, lefts, right), + Defs(defs, loc_ret) => { + let mut defs = (*defs).clone(); + desugar_defs_node_values(env, scope, &mut defs); + let loc_ret = desugar_expr(env, scope, loc_ret); + + env.arena.alloc(Loc::at( + loc_expr.region, + Defs(env.arena.alloc(defs), loc_ret), + )) + } + Apply(Loc { value: Dbg, .. }, loc_args, _called_via) => { + debug_assert!(!loc_args.is_empty()); + + if loc_args.len() > 1 { + let args_region = Region::span_across( + &loc_args.first().unwrap().region, + &loc_args.last().unwrap().region, + ); + env.problems.push(Problem::OverAppliedDbg { + region: args_region, + }); + + env.arena.alloc(Loc { + value: *desugar_invalid_dbg_expr(env, scope, loc_expr.region), + region: loc_expr.region, + }) + } else { + let desugared_arg = desugar_expr(env, scope, loc_args.first().unwrap()); + + env.arena.alloc(Loc { + value: *desugar_dbg_expr(env, scope, desugared_arg, loc_expr.region), + region: loc_expr.region, + }) + } + } + Apply( + Loc { + value: Try, + region: _, + }, + loc_args, + _called_via, + ) => { + let result_expr = if loc_args.len() == 1 { + desugar_expr(env, scope, loc_args[0]) + } else { + let function = desugar_expr(env, scope, loc_args.first().unwrap()); + let mut desugared_args = Vec::with_capacity_in(loc_args.len() - 1, env.arena); + for loc_arg in &loc_args[1..] { + desugared_args.push(desugar_expr(env, scope, loc_arg)); + } + + let args_region = + Region::span_across(&loc_args[0].region, &loc_args[loc_args.len() - 1].region); + + env.arena.alloc(Loc::at( + args_region, + Expr::Apply(function, desugared_args.into_bump_slice(), CalledVia::Try), + )) + }; + + env.arena.alloc(Loc::at( + loc_expr.region, + Expr::LowLevelTry(result_expr, ResultTryKind::KeywordPrefix), + )) + } + Apply( + Loc { + value: TrySuffix(fn_expr), + region: fn_region, + }, + loc_args, + _called_via, + ) => { + let loc_fn = env.arena.alloc(Loc::at(*fn_region, **fn_expr)); + let function = desugar_expr(env, scope, loc_fn); + + let mut desugared_args = Vec::with_capacity_in(loc_args.len(), env.arena); + for loc_arg in &loc_args[..] { + desugared_args.push(desugar_expr(env, scope, loc_arg)); + } + + let args_region = + Region::span_across(&loc_args[0].region, &loc_args[loc_args.len() - 1].region); + + let result_expr = env.arena.alloc(Loc::at( + args_region, + Expr::Apply(function, desugared_args.into_bump_slice(), CalledVia::Try), + )); + + env.arena.alloc(Loc::at( + loc_expr.region, + Expr::LowLevelTry(result_expr, ResultTryKind::OperatorSuffix), + )) + } + Apply(loc_fn, loc_args, called_via) => { + let mut desugared_args = Vec::with_capacity_in(loc_args.len(), env.arena); + + for loc_arg in loc_args.iter() { + let mut current = loc_arg.value; + let arg = loop { + match current { + SpaceBefore(expr, _) | SpaceAfter(expr, _) => { + current = *expr; + } + _ => break loc_arg, + } + }; + + desugared_args.push(desugar_expr(env, scope, arg)); + } + + let desugared_args = desugared_args.into_bump_slice(); + + env.arena.alloc(Loc { + value: Apply( + desugar_expr(env, scope, loc_fn), + desugared_args, + *called_via, + ), + region: loc_expr.region, + }) + } + PncApply(Loc { value: Dbg, .. }, loc_args) => { + if loc_args.is_empty() { + env.problems.push(Problem::UnappliedDbg { + region: loc_expr.region, + }); + env.arena.alloc(Loc { + value: *desugar_invalid_dbg_expr(env, scope, loc_expr.region), + region: loc_expr.region, + }) + } else if loc_args.len() > 1 { + let args_region = Region::span_across( + &loc_args.items.first().unwrap().region, + &loc_args.items.last().unwrap().region, + ); + env.problems.push(Problem::OverAppliedDbg { + region: args_region, + }); + + env.arena.alloc(Loc { + value: *desugar_invalid_dbg_expr(env, scope, loc_expr.region), + region: loc_expr.region, + }) + } else { + let desugared_arg = desugar_expr(env, scope, loc_args.items.first().unwrap()); + + env.arena.alloc(Loc { + value: *desugar_dbg_expr(env, scope, desugared_arg, loc_expr.region), + region: loc_expr.region, + }) + } + } + PncApply( + Loc { + value: Try, + region: _, + }, + loc_args, + ) => { + let result_expr = if loc_args.is_empty() { + env.problems.push(Problem::UnderAppliedTry { + region: loc_expr.region, + }); + // Replace with a dummy expression to avoid cascading errors + env.arena.alloc(Loc { + value: Record(Collection::empty()), + region: loc_expr.region, + }) + } else if loc_args.len() == 1 { + desugar_expr(env, scope, loc_args.items[0]) + } else { + let function = desugar_expr(env, scope, loc_args.items.first().unwrap()); + let mut desugared_args = Vec::with_capacity_in(loc_args.len() - 1, env.arena); + for loc_arg in &loc_args.items[1..] { + desugared_args.push(desugar_expr(env, scope, loc_arg)); + } + + let args_region = Region::span_across( + &loc_args.items[0].region, + &loc_args.items[loc_args.items.len() - 1].region, + ); + + env.arena.alloc(Loc::at( + args_region, + Expr::Apply(function, desugared_args.into_bump_slice(), CalledVia::Try), + )) + }; + + env.arena.alloc(Loc::at( + loc_expr.region, + Expr::LowLevelTry(result_expr, ResultTryKind::KeywordPrefix), + )) + } + PncApply(loc_fn, loc_args) => { + let mut desugared_args = Vec::with_capacity_in(loc_args.len(), env.arena); + + for loc_arg in loc_args.iter() { + let mut current = loc_arg.value; + let arg = loop { + match current { + SpaceBefore(expr, _) | SpaceAfter(expr, _) => { + current = *expr; + } + _ => break loc_arg, + } + }; + + desugared_args.push(desugar_expr(env, scope, arg)); + } + + let desugared_args = Collection::with_items(desugared_args.into_bump_slice()); + + env.arena.alloc(Loc { + value: PncApply(desugar_expr(env, scope, loc_fn), desugared_args), + region: loc_expr.region, + }) + } + + When(loc_cond_expr, branches) => { + let loc_desugared_cond = &*env.arena.alloc(desugar_expr(env, scope, loc_cond_expr)); + let mut desugared_branches = Vec::with_capacity_in(branches.len(), env.arena); + + for branch in branches.iter() { + let desugared_expr = desugar_expr(env, scope, &branch.value); + let desugared_patterns = desugar_loc_patterns(env, scope, branch.patterns); + + let desugared_guard = if let Some(guard) = &branch.guard { + Some(*desugar_expr(env, scope, guard)) + } else { + None + }; + + desugared_branches.push(&*env.arena.alloc(WhenBranch { + patterns: desugared_patterns, + value: *desugared_expr, + guard: desugared_guard, + })); + } + + let desugared_branches = desugared_branches.into_bump_slice(); + + env.arena.alloc(Loc { + value: When(loc_desugared_cond, desugared_branches), + region: loc_expr.region, + }) + } + UnaryOp(loc_arg, loc_op) => { + use roc_module::called_via::UnaryOp::*; + + let region = loc_op.region; + let op = loc_op.value; + // TODO desugar this in canonicalization instead, so we can work + // in terms of integers exclusively and not need to create strings + // which canonicalization then needs to look up, check if they're exposed, etc + let value = match op { + Negate => Var { + module_name: ModuleName::NUM, + ident: "neg", + }, + Not => Var { + module_name: ModuleName::BOOL, + ident: "not", + }, + }; + let loc_fn_var = env.arena.alloc(Loc { region, value }); + let desugared_args = env.arena.alloc([desugar_expr(env, scope, loc_arg)]); + + env.arena.alloc(Loc { + value: Apply(loc_fn_var, desugared_args, CalledVia::UnaryOp(op)), + region: loc_expr.region, + }) + } + SpaceBefore(expr, _) | SpaceAfter(expr, _) => { + // Since we've already begun canonicalization, spaces and parens + // are no longer needed and should be dropped. + desugar_expr( + env, + scope, + env.arena.alloc(Loc { + value: **expr, + region: loc_expr.region, + }), + ) + } + ParensAround(expr) => { + let desugared = desugar_expr( + env, + scope, + env.arena.alloc(Loc { + value: **expr, + region: loc_expr.region, + }), + ); + + env.arena.alloc(Loc { + value: ParensAround(&desugared.value), + region: loc_expr.region, + }) + } + If { + if_thens, + final_else, + indented_else, + } => { + // If does not get desugared into `when` so we can give more targeted error messages during type checking. + let desugared_final_else = &*env.arena.alloc(desugar_expr(env, scope, final_else)); + + let mut desugared_if_thens = Vec::with_capacity_in(if_thens.len(), env.arena); + + for (condition, then_branch) in if_thens.iter() { + let desugared_condition = *desugar_expr(env, scope, condition); + let desugared_then_branch = *desugar_expr(env, scope, then_branch); + + desugared_if_thens.push((desugared_condition, desugared_then_branch)); + } + + env.arena.alloc(Loc { + value: If { + if_thens: desugared_if_thens.into_bump_slice(), + final_else: desugared_final_else, + indented_else: *indented_else, + }, + region: loc_expr.region, + }) + } + Dbg => { + // Allow naked dbg, necessary for piping values into dbg with the `Pizza` binop + loc_expr + } + DbgStmt { + first: condition, + extra_args, + continuation, + pnc_style: _, + } => { + let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition)); + let desugared_continuation = &*env.arena.alloc(desugar_expr(env, scope, continuation)); + + if let Some(last) = extra_args.last() { + let args_region = Region::span_across(&condition.region, &last.region); + env.problems.push(Problem::OverAppliedDbg { + region: args_region, + }); + } + + env.arena.alloc(Loc { + value: *desugar_dbg_stmt(env, desugared_condition, desugared_continuation), + region: loc_expr.region, + }) + } + Return(return_value, after_return) => { + let desugared_return_value = &*env.arena.alloc(desugar_expr(env, scope, return_value)); + + env.arena.alloc(Loc { + // Do not desugar after_return since it isn't run anyway + value: Return(desugared_return_value, *after_return), + region: loc_expr.region, + }) + } + + // note these only exist after desugaring + LowLevelDbg(_, _, _) | LowLevelTry(_, _) => loc_expr, + } +} + +fn desugar_str_segments<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + segments: &'a [StrSegment<'a>], +) -> &'a [StrSegment<'a>] { + let mut allocated = Vec::with_capacity_in(segments.len(), env.arena); + + for segment in segments.iter() { + allocated.push(match segment { + StrSegment::Plaintext(_) | StrSegment::Unicode(_) | StrSegment::EscapedChar(_) => { + *segment + } + StrSegment::Interpolated(loc_expr) => { + let loc_desugared = desugar_expr( + env, + scope, + env.arena.alloc(Loc { + region: loc_expr.region, + value: *loc_expr.value, + }), + ); + StrSegment::Interpolated(Loc { + region: loc_desugared.region, + value: env.arena.alloc(loc_desugared.value), + }) + } + }); + } + + allocated.into_bump_slice() +} + +fn desugar_field_collection<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + fields: Collection<'a, Loc>>>, +) -> Collection<'a, Loc>>> { + let mut allocated = Vec::with_capacity_in(fields.len(), env.arena); + + for field in fields.iter() { + let value = desugar_field(env, scope, &field.value); + + allocated.push(Loc::at(field.region, value)); + } + + fields.replace_items(allocated.into_bump_slice()) +} + +fn desugar_field<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + field: &'a AssignedField<'a, Expr<'a>>, +) -> AssignedField<'a, Expr<'a>> { + use roc_parse::ast::AssignedField::*; + + match field { + RequiredValue(loc_str, spaces, loc_expr) => RequiredValue( + Loc { + value: loc_str.value, + region: loc_str.region, + }, + spaces, + desugar_expr(env, scope, loc_expr), + ), + OptionalValue(loc_str, spaces, loc_expr) => OptionalValue( + Loc { + value: loc_str.value, + region: loc_str.region, + }, + spaces, + desugar_expr(env, scope, loc_expr), + ), + IgnoredValue(loc_str, spaces, loc_expr) => IgnoredValue( + Loc { + value: loc_str.value, + region: loc_str.region, + }, + spaces, + desugar_expr(env, scope, loc_expr), + ), + LabelOnly(loc_str) => { + // Desugar { x } into { x: x } + let loc_expr = Loc { + value: Var { + module_name: "", + ident: loc_str.value, + }, + region: loc_str.region, + }; + + RequiredValue( + Loc { + value: loc_str.value, + region: loc_str.region, + }, + &[], + desugar_expr(env, scope, env.arena.alloc(loc_expr)), + ) + } + SpaceBefore(field, _spaces) => desugar_field(env, scope, field), + SpaceAfter(field, _spaces) => desugar_field(env, scope, field), + } +} + +fn desugar_loc_patterns<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + loc_patterns: &'a [Loc>], +) -> &'a [Loc>] { + let mut allocated = Vec::with_capacity_in(loc_patterns.len(), env.arena); + + for loc_pattern in loc_patterns.iter() { + allocated.push(Loc { + region: loc_pattern.region, + value: desugar_pattern(env, scope, loc_pattern.value), + }); + } + + allocated.into_bump_slice() +} + +fn desugar_loc_pattern<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + loc_pattern: &'a Loc>, +) -> &'a Loc> { + env.arena.alloc(Loc { + region: loc_pattern.region, + value: desugar_pattern(env, scope, loc_pattern.value), + }) +} + +fn desugar_pattern<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + pattern: Pattern<'a>, +) -> Pattern<'a> { + use roc_parse::ast::Pattern::*; + + match pattern { + Identifier { .. } + | Tag(_) + | OpaqueRef(_) + | NumLiteral(_) + | NonBase10Literal { .. } + | FloatLiteral(_) + | StrLiteral(_) + | Underscore(_) + | SingleQuote(_) + | ListRest(_) + | Malformed(_) + | MalformedIdent(_, _) + | MalformedExpr(_) + | QualifiedIdentifier { .. } => pattern, + + Apply(tag, arg_patterns) => { + // Skip desugaring the tag, it should either be a Tag or OpaqueRef + let mut desugared_arg_patterns = Vec::with_capacity_in(arg_patterns.len(), env.arena); + for arg_pattern in arg_patterns.iter() { + desugared_arg_patterns.push(Loc { + region: arg_pattern.region, + value: desugar_pattern(env, scope, arg_pattern.value), + }); + } + + Apply(tag, desugared_arg_patterns.into_bump_slice()) + } + PncApply(tag, arg_patterns) => { + // Skip desugaring the tag, it should either be a Tag or OpaqueRef + let mut desugared_arg_patterns = Vec::with_capacity_in(arg_patterns.len(), env.arena); + for arg_pattern in arg_patterns.iter() { + desugared_arg_patterns.push(Loc { + region: arg_pattern.region, + value: desugar_pattern(env, scope, arg_pattern.value), + }); + } + + PncApply( + tag, + Collection::with_items(desugared_arg_patterns.into_bump_slice()), + ) + } + RecordDestructure(field_patterns) => { + RecordDestructure(desugar_record_destructures(env, scope, field_patterns)) + } + RequiredField(name, field_pattern) => { + RequiredField(name, desugar_loc_pattern(env, scope, field_pattern)) + } + OptionalField(name, expr) => OptionalField(name, desugar_expr(env, scope, expr)), + Tuple(patterns) => { + let mut allocated = Vec::with_capacity_in(patterns.len(), env.arena); + for pattern in patterns.iter() { + let value = desugar_pattern(env, scope, pattern.value); + allocated.push(Loc { + value, + region: pattern.region, + }); + } + let patterns = patterns.replace_items(allocated.into_bump_slice()); + + Tuple(patterns) + } + List(patterns) => { + let mut allocated = Vec::with_capacity_in(patterns.len(), env.arena); + for pattern in patterns.iter() { + let value = desugar_pattern(env, scope, pattern.value); + allocated.push(Loc { + value, + region: pattern.region, + }); + } + let patterns = patterns.replace_items(allocated.into_bump_slice()); + + List(patterns) + } + As(sub_pattern, symbol) => As(desugar_loc_pattern(env, scope, sub_pattern), symbol), + SpaceBefore(sub_pattern, _spaces) => desugar_pattern(env, scope, *sub_pattern), + SpaceAfter(sub_pattern, _spaces) => desugar_pattern(env, scope, *sub_pattern), + } +} + +pub fn desugar_record_destructures<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + field_patterns: Collection<'a, Loc>>, +) -> Collection<'a, Loc>> { + let mut allocated = Vec::with_capacity_in(field_patterns.len(), env.arena); + for field_pattern in field_patterns.iter() { + let value = desugar_pattern(env, scope, field_pattern.value); + allocated.push(Loc { + value, + region: field_pattern.region, + }); + } + + field_patterns.replace_items(allocated.into_bump_slice()) +} + +/// Desugars a `dbg expr` expression into a statement block that prints and returns the +/// value produced by `expr`. Essentially: +/// ( +/// tmpVar = expr +/// LowLevelDbg (Inspect.to_str tmpVar) +/// tmpVar +/// ) +fn desugar_dbg_expr<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + expr: &'a Loc>, + outer_region: Region, +) -> &'a Expr<'a> { + let region = expr.region; + + // tmpVar = expr + let ident = env.arena.alloc(scope.gen_unique_symbol_name().to_string()); + + let value_def = ValueDef::Body( + env.arena.alloc(Loc { + value: Pattern::Identifier { ident }, + region, + }), + expr, + ); + + let defs = env.arena.alloc(Defs::default()); + defs.push_value_def(value_def, region, &[], &[]); + + // tmpVar + let tmp_var = env.arena.alloc(Loc { + value: Var { + module_name: "", + ident, + }, + region, + }); + + // LowLevelDbg + let dbg_stmt = env.arena.alloc(Loc { + value: *desugar_dbg_stmt(env, tmp_var, tmp_var), + region: outer_region, + }); + + env.arena.alloc(Defs(defs, dbg_stmt)) +} + +/// Build a desugared `dbg {}` expression to act as a placeholder when the AST +/// is invalid. +pub fn desugar_invalid_dbg_expr<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + outer_region: Region, +) -> &'a Expr<'a> { + let placeholder_expr = env.arena.alloc(Loc { + value: Record(Collection::empty()), + region: outer_region, + }); + + desugar_dbg_expr(env, scope, placeholder_expr, outer_region) +} + +/// Desugars a `dbg x` statement into essentially `Inspect.to_str x |> LowLevelDbg` +fn desugar_dbg_stmt<'a>( + env: &mut SoloEnv<'a>, + condition: &'a Loc>, + continuation: &'a Loc>, +) -> &'a Expr<'a> { + let region = condition.region; + + let inspect_fn = Var { + module_name: ModuleName::INSPECT, + ident: "to_str", + }; + let loc_inspect_fn_var = env.arena.alloc(Loc { + value: inspect_fn, + region, + }); + let inspect_args = &*env.arena.alloc([condition]); + + let dbg_str = env.arena.alloc(Loc { + value: Apply(loc_inspect_fn_var, inspect_args, CalledVia::Space), + region, + }); + + let line_col = env.line_info().convert_pos(region.start()); + + let dbg_src = env + .src + .split_at(region.start().offset as usize) + .1 + .split_at((region.end().offset - region.start().offset) as usize) + .0; + + let module_path_str = env.module_path.to_string_lossy(); + + // |> LowLevelDbg + env.arena.alloc(LowLevelDbg( + env.arena.alloc(( + &*env + .arena + .alloc_str(&format!("{}:{}", module_path_str, line_col.line + 1)), + &*env.arena.alloc_str(dbg_src), + )), + dbg_str, + continuation, + )) +} + +// TODO move this desugaring to canonicalization, so we can use Symbols instead of strings +#[inline(always)] +fn binop_to_function(binop: BinOp) -> (&'static str, &'static str) { + use self::BinOp::*; + + match binop { + Caret => (ModuleName::NUM, "pow"), + Star => (ModuleName::NUM, "mul"), + Slash => (ModuleName::NUM, "div"), + DoubleSlash => (ModuleName::NUM, "div_trunc"), + Percent => (ModuleName::NUM, "rem"), + Plus => (ModuleName::NUM, "add"), + Minus => (ModuleName::NUM, "sub"), + Equals => (ModuleName::BOOL, "is_eq"), + NotEquals => (ModuleName::BOOL, "is_not_eq"), + LessThan => (ModuleName::NUM, "is_lt"), + GreaterThan => (ModuleName::NUM, "is_gt"), + LessThanOrEq => (ModuleName::NUM, "is_lte"), + GreaterThanOrEq => (ModuleName::NUM, "is_gte"), + And => unreachable!("Cannot desugar the `and` operator"), + Or => unreachable!("Cannot desugar the `or` operator"), + Pizza => unreachable!("Cannot desugar the |> operator"), + DoubleQuestion => unreachable!("Cannot desugar the ?? operator"), + SingleQuestion => unreachable!("Cannot desugar the ? operator"), + } +} + +fn desugar_bin_ops<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + whole_region: Region, + lefts: &'a [(Loc>, Loc)], + right: &'a Loc>, +) -> &'a Loc> { + let mut arg_stack: Vec<&'a Loc> = Vec::with_capacity_in(lefts.len() + 1, env.arena); + let mut op_stack: Vec> = Vec::with_capacity_in(lefts.len(), env.arena); + + for (loc_expr, loc_op) in lefts { + arg_stack.push(loc_expr); + match run_binop_step( + env, + scope, + whole_region, + &mut arg_stack, + &mut op_stack, + *loc_op, + ) { + Err(problem) => return problem, + Ok(()) => continue, + } + } + + let mut expr = right; + + for (left, loc_op) in arg_stack.into_iter().zip(op_stack.into_iter()).rev() { + expr = env + .arena + .alloc(new_op_call_expr(env, scope, left, loc_op, expr)); + } + + expr +} + +enum Step<'a> { + Error(&'a Loc>), + Push(Loc), + Skip, +} + +fn run_binop_step<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + whole_region: Region, + arg_stack: &mut Vec<&'a Loc>>, + op_stack: &mut Vec>, + next_op: Loc, +) -> Result<(), &'a Loc>> { + use Step::*; + + match binop_step(env, scope, whole_region, arg_stack, op_stack, next_op) { + Error(problem) => Err(problem), + Push(loc_op) => run_binop_step(env, scope, whole_region, arg_stack, op_stack, loc_op), + Skip => Ok(()), + } +} + +fn binop_step<'a>( + env: &mut SoloEnv<'a>, + scope: &mut SoloScope, + whole_region: Region, + arg_stack: &mut Vec<&'a Loc>>, + op_stack: &mut Vec>, + next_op: Loc, +) -> Step<'a> { + use roc_module::called_via::Associativity::*; + use std::cmp::Ordering; + + match op_stack.pop() { + Some(stack_op) => { + match next_op.value.cmp(&stack_op.value) { + Ordering::Less => { + // Inline + let right = arg_stack.pop().unwrap(); + let left = arg_stack.pop().unwrap(); + + arg_stack.push( + env.arena + .alloc(new_op_call_expr(env, scope, left, stack_op, right)), + ); + + Step::Push(next_op) + } + + Ordering::Greater => { + // Swap + op_stack.push(stack_op); + op_stack.push(next_op); + + Step::Skip + } + + Ordering::Equal => { + match ( + next_op.value.associativity(), + stack_op.value.associativity(), + ) { + (LeftAssociative, LeftAssociative) => { + // Inline + let right = arg_stack.pop().unwrap(); + let left = arg_stack.pop().unwrap(); + + arg_stack.push( + env.arena + .alloc(new_op_call_expr(env, scope, left, stack_op, right)), + ); + + Step::Push(next_op) + } + + (RightAssociative, RightAssociative) => { + // Swap + op_stack.push(stack_op); + op_stack.push(next_op); + + Step::Skip + } + + (NonAssociative, NonAssociative) => { + // Both operators were non-associative, e.g. (True == False == False). + // We should tell the author to disambiguate by grouping them with parens. + let bad_op = next_op; + let right = arg_stack.pop().unwrap(); + let left = arg_stack.pop().unwrap(); + let broken_expr = env + .arena + .alloc(new_op_call_expr(env, scope, left, stack_op, right)); + let region = broken_expr.region; + let data = roc_parse::ast::PrecedenceConflict { + whole_region, + binop1_position: stack_op.region.start(), + binop1: stack_op.value, + binop2_position: bad_op.region.start(), + binop2: bad_op.value, + expr: env.arena.alloc(broken_expr), + }; + let value = Expr::PrecedenceConflict(env.arena.alloc(data)); + + Step::Error(env.arena.alloc(Loc { region, value })) + } + + _ => { + // The operators had the same precedence but different associativity. + // + // In many languages, this case can happen due to (for example) <| and |> having the same + // precedence but different associativity. Languages which support custom operators with + // (e.g. Haskell) can potentially have arbitrarily many of these cases. + // + // By design, Roc neither allows custom operators nor has any built-in operators with + // the same precedence and different associativity, so this should never happen! + internal_error!("BinOps had the same associativity, but different precedence. This should never happen!"); + } + } + } + } + } + None => { + op_stack.push(next_op); + Step::Skip + } + } +} diff --git a/crates/check/can_solo/src/env.rs b/crates/check/can_solo/src/env.rs new file mode 100644 index 00000000000..a789e071239 --- /dev/null +++ b/crates/check/can_solo/src/env.rs @@ -0,0 +1,48 @@ +use std::path::Path; + +use bumpalo::Bump; +use roc_module::symbol::ModuleId; +use roc_problem::can::Problem; +use roc_region::all::LineInfo; + +/// The canonicalization environment for a particular module. +#[derive(Debug)] +pub struct SoloEnv<'a> { + pub arena: &'a Bump, + + pub module_path: &'a Path, + + pub solo_home: ModuleId, + + /// Problems we've encountered along the way, which will be reported to the user at the end. + pub problems: Vec, + + pub src: &'a str, + + /// Lazily calculated line info. This data is only needed if the code contains calls to `dbg`, + /// otherwise we can leave it as `None` and never pay the cost of scanning the source an extra + /// time. + pub lazy_line_info: &'a mut Option, +} + +impl<'a> SoloEnv<'a> { + #[allow(clippy::too_many_arguments)] + pub fn new(arena: &'a Bump, src: &'a str, module_path: &'a Path) -> SoloEnv<'a> { + SoloEnv { + arena, + module_path, + solo_home: ModuleId::first_after_builtins(), + src, + problems: Vec::new(), + lazy_line_info: arena.alloc(None), + } + } + + pub fn line_info(&mut self) -> &LineInfo { + if self.lazy_line_info.is_none() { + *self.lazy_line_info = Some(LineInfo::new(self.src)); + } + + self.lazy_line_info.as_ref().unwrap() + } +} diff --git a/crates/check/can_solo/src/lib.rs b/crates/check/can_solo/src/lib.rs new file mode 100644 index 00000000000..7758f554ac9 --- /dev/null +++ b/crates/check/can_solo/src/lib.rs @@ -0,0 +1,5 @@ +#![warn(clippy::dbg_macro)] +pub mod desugar; +pub mod env; +pub mod module; +pub mod scope; diff --git a/crates/check/can_solo/src/module.rs b/crates/check/can_solo/src/module.rs new file mode 100644 index 00000000000..9fd93bc4a97 --- /dev/null +++ b/crates/check/can_solo/src/module.rs @@ -0,0 +1,81 @@ +use std::path::PathBuf; + +use bumpalo::Bump; +use roc_module::symbol::ModuleId; +use roc_parse::{ + ast::{Collection, Defs, Pattern}, + header::HeaderType, +}; +use roc_problem::can::Problem; +use roc_region::all::{LineInfo, Loc, Region}; + +use crate::{ + desugar::{desugar_defs_node_values, desugar_record_destructures}, + env::SoloEnv, + scope::SoloScope, +}; + +#[derive(Debug)] +pub struct SoloCanOutput<'a> { + pub scope: SoloScope, + pub loc_defs: Defs<'a>, + pub solo_home: ModuleId, + + /// Problems we've encountered along the way, which will be reported to the user at the end. + pub problems: Vec, + + pub src: &'a str, + + /// Lazily calculated line info. This data is only needed if the code contains calls to `dbg`, + /// otherwise we can leave it as `None` and never pay the cost of scanning the source an extra + /// time. + pub lazy_line_info: &'a mut Option, + + pub module_params: Option<(Region, Collection<'a, Loc>>)>, +} + +// TODO trim these down +#[allow(clippy::too_many_arguments)] +pub fn solo_canonicalize_module_defs<'a>( + arena: &'a Bump, + header_type: HeaderType<'a>, + loc_defs: &'a mut Defs<'a>, + module_path: PathBuf, + src: &'a str, +) -> SoloCanOutput<'a> { + let mut scope = SoloScope::new(); + let mut env = SoloEnv::new(arena, src, arena.alloc(module_path)); + + // Desugar operators (convert them to Apply calls, taking into account + // operator precedence and associativity rules), before doing other canonicalization. + // + // If we did this *during* canonicalization, then each time we + // visited a BinOp node we'd recursively try to apply this to each of its nested + // operators, and then again on *their* nested operators, ultimately applying the + // rules multiple times unnecessarily. + + desugar_defs_node_values(&mut env, &mut scope, loc_defs); + + let module_params = header_type.get_params().as_ref().map( + |roc_parse::header::ModuleParams { + pattern, + before_arrow: _, + after_arrow: _, + }| { + let desugared_patterns = + desugar_record_destructures(&mut env, &mut scope, pattern.value); + + (pattern.region, desugared_patterns) + }, + ); + + SoloCanOutput { + scope, + solo_home: env.solo_home, + loc_defs: loc_defs.clone(), + problems: env.problems, + src: env.src, + lazy_line_info: env.lazy_line_info, + module_params, + } +} diff --git a/crates/check/can_solo/src/scope.rs b/crates/check/can_solo/src/scope.rs new file mode 100644 index 00000000000..83313bcb57a --- /dev/null +++ b/crates/check/can_solo/src/scope.rs @@ -0,0 +1,229 @@ +use roc_collections::VecMap; +use roc_module::ident::ModuleName; +use roc_module::symbol::{IdentId, IdentIds, ModuleId, ModuleIds, Symbol}; +use roc_problem::can::ScopeModuleSource; +use roc_region::all::Region; +use roc_types::subs::Variable; +use roc_types::types::{Alias, EarlyReturnKind}; + +use bitvec::vec::BitVec; + +#[derive(Clone, Debug)] +pub struct SoloScope { + /// The type aliases currently in scope + pub aliases: VecMap, + + #[allow(dead_code)] + /// The current module being processed. This will be used to turn + /// unqualified idents into Symbols. + solo_home: ModuleId, + + /// Modules that are imported + pub modules: ScopeModules, + + /// Identifiers that are in scope, and defined in the current module + pub locals: ScopedIdentIds, + + pub early_returns: Vec<(Variable, Region, EarlyReturnKind)>, +} + +impl Default for SoloScope { + fn default() -> Self { + Self::new() + } +} + +impl SoloScope { + pub fn new() -> Self { + let solo_home = ModuleId::first_after_builtins(); + + Self { + solo_home, + locals: ScopedIdentIds::from_ident_ids(solo_home), + aliases: VecMap::default(), + modules: ScopeModules::new(solo_home), + early_returns: Vec::default(), + } + } + + /// Generates a unique new symbol and return the symbol's unqualified identifier name. + pub fn gen_unique_symbol_name(&mut self) -> &str { + let ident_id = self.locals.gen_unique(); + self.locals.ident_ids.get_name(ident_id).unwrap() + } +} + +#[derive(Clone, Debug)] +pub struct ScopedIdentIds { + pub ident_ids: IdentIds, + in_scope: BitVec, + regions: Vec, + #[allow(dead_code)] + solo_home: ModuleId, +} + +impl ScopedIdentIds { + fn from_ident_ids(solo_home: ModuleId) -> Self { + Self { + in_scope: BitVec::repeat(false, 0), + ident_ids: IdentIds::default(), + regions: vec![Region::zero(); 0], + solo_home, + } + } + + fn gen_unique(&mut self) -> IdentId { + let id = self.ident_ids.gen_unique(); + + debug_assert_eq!(id.index(), self.in_scope.len()); + debug_assert_eq!(id.index(), self.regions.len()); + + self.in_scope.push(false); + self.regions.push(Region::zero()); + + id + } +} + +#[derive(Debug, Clone)] +pub struct ScopeModules { + /// The ids of all modules in scope + ids: Vec, + /// The alias or original name of each module in scope + names: Vec, + /// Why is this module in scope? + sources: Vec, + /// The params of a module if any + params: Vec>, +} + +impl ScopeModules { + pub fn new(home_id: ModuleId) -> Self { + let builtins = ModuleIds::default(); + let builtins_iter = builtins.iter(); + let count = builtins_iter.len(); + + let mut ids = Vec::with_capacity(count + 1); + let mut names = Vec::with_capacity(count + 1); + let mut sources = vec![ScopeModuleSource::Builtin; count]; + let mut params = vec![None; count]; + + for (module_id, module_name) in builtins_iter { + ids.push(module_id); + names.push(module_name.clone()); + } + + if !home_id.is_builtin() { + ids.push(home_id); + names.push("".into()); + sources.push(ScopeModuleSource::Current); + params.push(None); + } + + Self { + ids, + names, + sources, + params, + } + } + + pub fn lookup(&self, module_name: &ModuleName) -> Option { + self.names + .iter() + .position(|name| name == module_name) + .map(|index| ModuleLookup { + id: self.ids[index], + params: self.params[index], + }) + } + + pub fn lookup_by_id(&self, module_id: &ModuleId) -> Option { + self.ids + .iter() + .position(|id| id == module_id) + .map(|index| ModuleLookup { + id: self.ids[index], + params: self.params[index], + }) + } + + pub fn available_names(&self) -> impl Iterator { + self.names.iter() + } + + pub fn insert( + &mut self, + module_name: ModuleName, + module_id: ModuleId, + params: Option<(Variable, Symbol)>, + region: Region, + ) -> Result<(), ScopeModuleSource> { + if let Some(index) = self.names.iter().position(|name| name == &module_name) { + if self.ids[index] == module_id { + return Ok(()); + } + + return Err(self.sources[index]); + } + + self.ids.push(module_id); + self.names.push(module_name); + self.sources.push(ScopeModuleSource::Import(region)); + self.params.push(params); + Ok(()) + } + + pub fn len(&self) -> usize { + debug_assert_eq!(self.ids.len(), self.names.len()); + debug_assert_eq!(self.ids.len(), self.sources.len()); + debug_assert_eq!(self.ids.len(), self.params.len()); + self.ids.len() + } + + pub fn is_empty(&self) -> bool { + self.ids.is_empty() + } + + pub fn truncate(&mut self, len: usize) { + self.ids.truncate(len); + self.names.truncate(len); + self.sources.truncate(len); + self.params.truncate(len); + } +} + +#[derive(Debug, Clone, Copy)] +pub struct SymbolLookup { + pub symbol: Symbol, + pub module_params: Option<(Variable, Symbol)>, +} + +impl SymbolLookup { + pub fn new(symbol: Symbol, params: Option<(Variable, Symbol)>) -> Self { + Self { + symbol, + module_params: params, + } + } + + pub fn no_params(symbol: Symbol) -> Self { + Self::new(symbol, None) + } +} + +pub struct ModuleLookup { + pub id: ModuleId, + pub params: Option<(Variable, Symbol)>, +} + +impl ModuleLookup { + pub fn into_symbol(&self, symbol: Symbol) -> SymbolLookup { + debug_assert_eq!(symbol.module_id(), self.id); + + SymbolLookup { + symbol, + module_params: self.params, + } + } +} diff --git a/crates/compiler/can/Cargo.toml b/crates/compiler/can/Cargo.toml index 78b1805f652..875220facd4 100644 --- a/crates/compiler/can/Cargo.toml +++ b/crates/compiler/can/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true version.workspace = true [dependencies] +roc_can_solo.workspace = true roc_collections.workspace = true roc_error_macros.workspace = true roc_exhaustive.workspace = true diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index 2acc94e1e26..1d147f0cd43 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -2,1555 +2,12 @@ use crate::env::Env; use crate::scope::Scope; -use bumpalo::collections::Vec; -use roc_error_macros::internal_error; -use roc_module::called_via::{BinOp, CalledVia}; +use roc_module::called_via::CalledVia; use roc_module::ident::ModuleName; use roc_parse::ast::Expr::{self, *}; -use roc_parse::ast::{ - AssignedField, Collection, Defs, ModuleImportParams, Pattern, ResultTryKind, StrLiteral, - StrSegment, ValueDef, WhenBranch, -}; -use roc_problem::can::Problem; +use roc_parse::ast::{Collection, Defs, Pattern, ValueDef}; use roc_region::all::{Loc, Region}; -// BinOp precedence logic adapted from Gluon by Markus Westerlind -// https://github.com/gluon-lang/gluon - license information can be found in -// the LEGAL_DETAILS file in the root directory of this distribution. -// -// Thank you, Markus! - -/// Desugar a single binary operation. -/// -/// When using this function, don't desugar `left` and `right` before calling so that -/// we can properly desugar `|> try` expressions! -fn new_op_call_expr<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - left: &'a Loc>, - loc_op: Loc, - right: &'a Loc>, -) -> Loc> { - let region = Region::span_across(&left.region, &right.region); - - let value = match loc_op.value { - // Rewrite the Pizza operator into an Apply - BinOp::Pizza => { - // Allow `left |> try (optional)` to desugar to `try left (optional)` - let right_without_spaces = without_spaces(&right.value); - match right_without_spaces { - Try => { - let desugared_left = desugar_expr(env, scope, left); - return Loc::at( - region, - Expr::LowLevelTry(desugared_left, ResultTryKind::KeywordPrefix), - ); - } - PncApply(&Loc { value: Try, .. }, arguments) => { - let try_fn = desugar_expr(env, scope, arguments.items.first().unwrap()); - - let mut args = Vec::with_capacity_in(arguments.len(), env.arena); - args.push(desugar_expr(env, scope, left)); - args.extend( - arguments - .iter() - .skip(1) - .map(|a| desugar_expr(env, scope, a)), - ); - - return Loc::at( - region, - Expr::LowLevelTry( - env.arena.alloc(Loc::at( - region, - Expr::Apply(try_fn, args.into_bump_slice(), CalledVia::Try), - )), - ResultTryKind::KeywordPrefix, - ), - ); - } - Apply(&Loc { value: Try, .. }, arguments, _called_via) => { - let try_fn = desugar_expr(env, scope, arguments.first().unwrap()); - - let mut args = Vec::with_capacity_in(arguments.len(), env.arena); - args.push(desugar_expr(env, scope, left)); - args.extend( - arguments - .iter() - .skip(1) - .map(|a| desugar_expr(env, scope, a)), - ); - - return Loc::at( - region, - Expr::LowLevelTry( - env.arena.alloc(Loc::at( - region, - Expr::Apply(try_fn, args.into_bump_slice(), CalledVia::Try), - )), - ResultTryKind::KeywordPrefix, - ), - ); - } - TrySuffix(fn_expr) => { - let loc_fn = env.arena.alloc(Loc::at(right.region, **fn_expr)); - let function = desugar_expr(env, scope, loc_fn); - - return Loc::at( - region, - LowLevelTry( - env.arena.alloc(Loc::at( - region, - Expr::Apply( - function, - env.arena.alloc([desugar_expr(env, scope, left)]), - CalledVia::Try, - ), - )), - ResultTryKind::OperatorSuffix, - ), - ); - } - PncApply( - &Loc { - value: TrySuffix(fn_expr), - region: fn_region, - }, - loc_args, - ) => { - let loc_fn = env.arena.alloc(Loc::at(fn_region, *fn_expr)); - let function = desugar_expr(env, scope, loc_fn); - - let mut desugared_args = Vec::with_capacity_in(loc_args.len() + 1, env.arena); - desugared_args.push(desugar_expr(env, scope, left)); - for loc_arg in loc_args.items { - desugared_args.push(desugar_expr(env, scope, loc_arg)); - } - - return Loc::at( - region, - LowLevelTry( - env.arena.alloc(Loc::at( - region, - Expr::Apply( - function, - desugared_args.into_bump_slice(), - CalledVia::Try, - ), - )), - ResultTryKind::OperatorSuffix, - ), - ); - } - Apply( - &Loc { - value: TrySuffix(fn_expr), - region: fn_region, - }, - loc_args, - _called_via, - ) => { - let loc_fn = env.arena.alloc(Loc::at(fn_region, *fn_expr)); - let function = desugar_expr(env, scope, loc_fn); - - let mut desugared_args = Vec::with_capacity_in(loc_args.len() + 1, env.arena); - desugared_args.push(desugar_expr(env, scope, left)); - for loc_arg in &loc_args[..] { - desugared_args.push(desugar_expr(env, scope, loc_arg)); - } - - return Loc::at( - region, - LowLevelTry( - env.arena.alloc(Loc::at( - region, - Expr::Apply( - function, - desugared_args.into_bump_slice(), - CalledVia::Try, - ), - )), - ResultTryKind::OperatorSuffix, - ), - ); - } - _ => {} - } - - let left = desugar_expr(env, scope, left); - let right = desugar_expr(env, scope, right); - - match right.value { - Apply(function, arguments, _called_via) => { - let mut args = Vec::with_capacity_in(1 + arguments.len(), env.arena); - - args.push(left); - args.extend(arguments.iter()); - - let args = args.into_bump_slice(); - - Apply(function, args, CalledVia::BinOp(BinOp::Pizza)) - } - PncApply(function, arguments) => { - let mut args = Vec::with_capacity_in(1 + arguments.len(), env.arena); - - args.push(left); - args.extend(arguments.iter()); - - let args = args.into_bump_slice(); - - Apply(function, args, CalledVia::BinOp(BinOp::Pizza)) - } - Dbg => *desugar_dbg_expr(env, scope, left, region), - _ => { - // e.g. `1 |> (if b then (\a -> a) else (\c -> c))` - Apply( - right, - env.arena.alloc([left]), - CalledVia::BinOp(BinOp::Pizza), - ) - } - } - } - BinOp::DoubleQuestion => { - let left = desugar_expr(env, scope, left); - let right = desugar_expr(env, scope, right); - - let ok_var = env.arena.alloc_str(&format!( - "#double_question_ok_{}_{}", - left.region.start().offset, - left.region.end().offset - )); - - let ok_branch_pattern_args = env - .arena - .alloc([Loc::at(left.region, Pattern::Identifier { ident: ok_var })]); - let ok_branch_patterns = env.arena.alloc([Loc::at( - left.region, - Pattern::PncApply( - env.arena.alloc(Loc::at(left.region, Pattern::Tag("Ok"))), - Collection::with_items(ok_branch_pattern_args), - ), - )]); - let ok_branch = &*env.arena.alloc(WhenBranch { - patterns: ok_branch_patterns, - value: Loc::at( - left.region, - Expr::Var { - module_name: "", - ident: ok_var, - }, - ), - guard: None, - }); - - let err_branch_pattern_args = env - .arena - .alloc([(Loc::at(right.region, Pattern::Underscore("")))]); - let err_branch_patterns = env.arena.alloc([Loc::at( - right.region, - Pattern::PncApply( - env.arena.alloc(Loc::at(left.region, Pattern::Tag("Err"))), - Collection::with_items(err_branch_pattern_args), - ), - )]); - let err_branch = &*env.arena.alloc(WhenBranch { - patterns: err_branch_patterns, - value: *right, - guard: None, - }); - - When(left, &*env.arena.alloc([ok_branch, err_branch])) - } - BinOp::SingleQuestion => { - let left = desugar_expr(env, scope, left); - let right = desugar_expr(env, scope, right); - - let ok_var = env.arena.alloc_str(&format!( - "#single_question_ok_{}_{}", - left.region.start().offset, - left.region.end().offset - )); - - let ok_branch_pattern_args = env - .arena - .alloc([Loc::at(left.region, Pattern::Identifier { ident: ok_var })]); - let ok_branch_patterns = env.arena.alloc([Loc::at( - left.region, - Pattern::PncApply( - env.arena.alloc(Loc::at(left.region, Pattern::Tag("Ok"))), - Collection::with_items(ok_branch_pattern_args), - ), - )]); - let ok_branch = &*env.arena.alloc(WhenBranch { - patterns: ok_branch_patterns, - value: Loc::at( - left.region, - Expr::Var { - module_name: "", - ident: ok_var, - }, - ), - guard: None, - }); - - let err_var = env.arena.alloc_str(&format!( - "#single_question_err_{}_{}", - left.region.start().offset, - left.region.end().offset - )); - - let err_branch_pattern_args = env - .arena - .alloc([(Loc::at(right.region, Pattern::Identifier { ident: err_var }))]); - let err_branch_patterns = env.arena.alloc([Loc::at( - right.region, - Pattern::PncApply( - env.arena.alloc(Loc::at(left.region, Pattern::Tag("Err"))), - Collection::with_items(err_branch_pattern_args), - ), - )]); - let map_err_expr = &*env.arena.alloc(Loc::at( - right.region, - Expr::PncApply( - right, - Collection::with_items(&*env.arena.alloc([&*env.arena.alloc(Loc::at( - left.region, - Expr::Var { - module_name: "", - ident: err_var, - }, - ))])), - ), - )); - let err_branch = &*env.arena.alloc(WhenBranch { - patterns: err_branch_patterns, - value: Loc::at( - region, - Expr::Return( - env.arena.alloc(Loc::at( - region, - Expr::PncApply( - env.arena.alloc(Loc::at(region, Expr::Tag("Err"))), - Collection::with_items(&*env.arena.alloc([map_err_expr])), - ), - )), - None, - ), - ), - guard: None, - }); - - When(left, &*env.arena.alloc([ok_branch, err_branch])) - } - BinOp::And => { - let left = desugar_expr(env, scope, left); - let right = desugar_expr(env, scope, right); - - Expr::If { - if_thens: env.arena.alloc([(*left, *right)]), - final_else: env.arena.alloc(Loc::at( - right.region, - Expr::Var { - module_name: ModuleName::BOOL, - ident: "false", - }, - )), - indented_else: false, - } - } - BinOp::Or => { - let left = desugar_expr(env, scope, left); - let right = desugar_expr(env, scope, right); - - Expr::If { - if_thens: env.arena.alloc([( - *left, - Loc::at( - right.region, - Expr::Var { - module_name: ModuleName::BOOL, - ident: "true", - }, - ), - )]), - final_else: right, - indented_else: false, - } - } - binop => { - let left = desugar_expr(env, scope, left); - let right = desugar_expr(env, scope, right); - - // This is a normal binary operator like (+), so desugar it - // into the appropriate function call. - let (module_name, ident) = binop_to_function(binop); - - let args = env.arena.alloc([left, right]); - - let loc_expr = env.arena.alloc(Loc { - value: Expr::Var { module_name, ident }, - region: loc_op.region, - }); - - Apply(loc_expr, args, CalledVia::BinOp(binop)) - } - }; - - Loc { region, value } -} - -fn without_spaces<'a>(expr: &'a Expr<'a>) -> &'a Expr<'a> { - match expr { - Expr::SpaceBefore(inner, _) | Expr::SpaceAfter(inner, _) => without_spaces(inner), - _ => expr, - } -} - -fn desugar_value_def<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - def: &'a ValueDef<'a>, -) -> ValueDef<'a> { - use ValueDef::*; - - match def { - Body(loc_pattern, loc_expr) => Body( - desugar_loc_pattern(env, scope, loc_pattern), - desugar_expr(env, scope, loc_expr), - ), - Annotation(ann_pattern, ann_type) => { - Annotation(*desugar_loc_pattern(env, scope, ann_pattern), *ann_type) - } - AnnotatedBody { - ann_pattern, - ann_type, - lines_between, - body_pattern, - body_expr, - } => AnnotatedBody { - ann_pattern: desugar_loc_pattern(env, scope, ann_pattern), - ann_type, - lines_between, - body_pattern: desugar_loc_pattern(env, scope, body_pattern), - body_expr: desugar_expr(env, scope, body_expr), - }, - - Dbg { - condition, - preceding_comment, - } => { - let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition)); - Dbg { - condition: desugared_condition, - preceding_comment: *preceding_comment, - } - } - Expect { - condition, - preceding_comment, - } => { - let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition)); - Expect { - condition: desugared_condition, - preceding_comment: *preceding_comment, - } - } - ModuleImport(roc_parse::ast::ModuleImport { - before_name, - name, - params, - alias, - exposed, - }) => { - let desugared_params = - params.map(|ModuleImportParams { before, params }| ModuleImportParams { - before, - params: params.map(|params| desugar_field_collection(env, scope, *params)), - }); - - ModuleImport(roc_parse::ast::ModuleImport { - before_name, - name: *name, - params: desugared_params, - alias: *alias, - exposed: *exposed, - }) - } - IngestedFileImport(_) => *def, - - StmtAfterExpr => internal_error!( - "StmtAfterExpression is only created during desugaring, so it shouldn't exist here." - ), - - Stmt(stmt_expr) => Stmt(desugar_expr(env, scope, stmt_expr)), - } -} - -pub fn desugar_defs_node_values<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - defs: &mut roc_parse::ast::Defs<'a>, -) { - for value_def in defs.value_defs.iter_mut() { - *value_def = desugar_value_def(env, scope, env.arena.alloc(*value_def)); - } -} - -/// Reorder the expression tree based on operator precedence and associativity rules, -/// then replace the BinOp nodes with Apply nodes. Also drop SpaceBefore and SpaceAfter nodes. -pub fn desugar_expr<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - loc_expr: &'a Loc>, -) -> &'a Loc> { - match &loc_expr.value { - Float(..) - | Num(..) - | NonBase10Int { .. } - | SingleQuote(_) - | Var { .. } - | AccessorFunction(_) - | Underscore { .. } - | MalformedIdent(_, _) - | PrecedenceConflict { .. } - | EmptyRecordBuilder(_) - | SingleFieldRecordBuilder(_) - | OptionalFieldInRecordBuilder { .. } - | Tag(_) - | OpaqueRef(_) - | Crash - | Try => loc_expr, - - Str(str_literal) => match str_literal { - StrLiteral::PlainLine(_) => loc_expr, - StrLiteral::Line(segments) => { - let region = loc_expr.region; - let value = Str(StrLiteral::Line(desugar_str_segments(env, scope, segments))); - - env.arena.alloc(Loc { region, value }) - } - StrLiteral::Block(lines) => { - let region = loc_expr.region; - let mut new_lines = Vec::with_capacity_in(lines.len(), env.arena); - for segments in lines.iter() { - new_lines.push(desugar_str_segments(env, scope, segments)); - } - let value = Str(StrLiteral::Block(new_lines.into_bump_slice())); - - env.arena.alloc(Loc { region, value }) - } - }, - - TupleAccess(sub_expr, paths) => { - let region = loc_expr.region; - let loc_sub_expr = Loc { - region, - value: **sub_expr, - }; - let value = TupleAccess( - &desugar_expr(env, scope, env.arena.alloc(loc_sub_expr)).value, - paths, - ); - - env.arena.alloc(Loc { region, value }) - } - TrySuffix(sub_expr) => { - let intermediate = env.arena.alloc(Loc::at(loc_expr.region, **sub_expr)); - let new_sub_loc_expr = desugar_expr(env, scope, intermediate); - - env.arena.alloc(Loc::at( - loc_expr.region, - LowLevelTry(new_sub_loc_expr, ResultTryKind::OperatorSuffix), - )) - } - RecordAccess(sub_expr, paths) => { - let region = loc_expr.region; - let loc_sub_expr = Loc { - region, - value: **sub_expr, - }; - let value = RecordAccess( - &desugar_expr(env, scope, env.arena.alloc(loc_sub_expr)).value, - paths, - ); - - env.arena.alloc(Loc { region, value }) - } - List(items) => { - let mut new_items = Vec::with_capacity_in(items.len(), env.arena); - - for item in items.iter() { - new_items.push(desugar_expr(env, scope, item)); - } - let new_items = new_items.into_bump_slice(); - let value: Expr<'a> = List(items.replace_items(new_items)); - - env.arena.alloc(Loc { - region: loc_expr.region, - value, - }) - } - Record(fields) => { - let fields = desugar_field_collection(env, scope, *fields); - env.arena.alloc(Loc { - region: loc_expr.region, - value: Record(fields), - }) - } - Tuple(fields) => { - let mut allocated = Vec::with_capacity_in(fields.len(), env.arena); - for field in fields.iter() { - let expr = desugar_expr(env, scope, field); - allocated.push(expr); - } - let fields = fields.replace_items(allocated.into_bump_slice()); - env.arena.alloc(Loc { - region: loc_expr.region, - value: Tuple(fields), - }) - } - RecordUpdate { fields, update } => { - // NOTE the `update` field is always a `Var { .. }`, we only desugar it to get rid of - // any spaces before/after - let new_update = desugar_expr(env, scope, update); - - let mut allocated = Vec::with_capacity_in(fields.len(), env.arena); - for field in fields.iter() { - let value = desugar_field(env, scope, &field.value); - allocated.push(Loc { - value, - region: field.region, - }); - } - let new_fields = fields.replace_items(allocated.into_bump_slice()); - - env.arena.alloc(Loc { - region: loc_expr.region, - value: RecordUpdate { - update: new_update, - fields: new_fields, - }, - }) - } - RecordUpdater(field_name) => { - let region = loc_expr.region; - - let closure_body = RecordUpdate { - update: env.arena.alloc(Loc { - region, - value: Expr::Var { - module_name: "", - ident: "#record_updater_record", - }, - }), - fields: Collection::with_items( - Vec::from_iter_in( - [Loc::at( - region, - AssignedField::RequiredValue( - Loc::at(region, field_name), - &[], - &*env.arena.alloc(Loc { - region, - value: Expr::Var { - module_name: "", - ident: "#record_updater_field", - }, - }), - ), - )], - env.arena, - ) - .into_bump_slice(), - ), - }; - - env.arena.alloc(Loc { - region, - value: Closure( - env.arena.alloc_slice_copy(&[ - Loc::at( - region, - Pattern::Identifier { - ident: "#record_updater_record", - }, - ), - Loc::at( - region, - Pattern::Identifier { - ident: "#record_updater_field", - }, - ), - ]), - env.arena.alloc(Loc::at(region, closure_body)), - ), - }) - } - Closure(loc_patterns, loc_ret) => env.arena.alloc(Loc { - region: loc_expr.region, - value: Closure( - desugar_loc_patterns(env, scope, loc_patterns), - desugar_expr(env, scope, loc_ret), - ), - }), - RecordBuilder { mapper, fields } => { - // NOTE the `mapper` is always a `Var { .. }`, we only desugar it to get rid of - // any spaces before/after - let new_mapper = desugar_expr(env, scope, mapper); - - if fields.is_empty() { - return env.arena.alloc(Loc { - value: EmptyRecordBuilder(loc_expr), - region: loc_expr.region, - }); - } else if fields.len() == 1 { - return env.arena.alloc(Loc { - value: SingleFieldRecordBuilder(loc_expr), - region: loc_expr.region, - }); - } - - struct FieldData<'d> { - name: Loc<&'d str>, - value: &'d Loc>, - ignored: bool, - } - - let mut field_data = Vec::with_capacity_in(fields.len(), env.arena); - - for field in fields.items { - let desugared_field = desugar_field(env, scope, &field.value); - let (name, value, ignored) = match desugared_field { - AssignedField::RequiredValue(loc_name, _, loc_val) => { - (loc_name, loc_val, false) - } - AssignedField::IgnoredValue(loc_name, _, loc_val) => (loc_name, loc_val, true), - AssignedField::LabelOnly(loc_name) => ( - loc_name, - &*env.arena.alloc(Loc { - region: loc_name.region, - value: Expr::Var { - module_name: "", - ident: loc_name.value, - }, - }), - false, - ), - AssignedField::OptionalValue(loc_name, _, loc_val) => { - return env.arena.alloc(Loc { - region: loc_expr.region, - value: OptionalFieldInRecordBuilder(env.arena.alloc(loc_name), loc_val), - }); - } - AssignedField::SpaceBefore(_, _) | AssignedField::SpaceAfter(_, _) => { - unreachable!("Should have been desugared in `desugar_field`") - } - }; - - field_data.push(FieldData { - name, - value, - ignored, - }); - } - - let closure_arg_from_field = - |FieldData { - name, - value: _, - ignored, - }: &FieldData<'a>| Loc { - region: name.region, - value: if *ignored { - Pattern::Underscore(name.value) - } else { - Pattern::Identifier { - ident: env.arena.alloc_str(&format!("#{}", name.value)), - } - }, - }; - - let combiner_closure_in_region = |region| { - let closure_body = Tuple(Collection::with_items( - Vec::from_iter_in( - [ - &*env.arena.alloc(Loc::at( - region, - Expr::Var { - module_name: "", - ident: "#record_builder_closure_arg_a", - }, - )), - &*env.arena.alloc(Loc::at( - region, - Expr::Var { - module_name: "", - ident: "#record_builder_closure_arg_b", - }, - )), - ], - env.arena, - ) - .into_bump_slice(), - )); - - env.arena.alloc(Loc::at( - region, - Closure( - env.arena.alloc_slice_copy(&[ - Loc::at( - region, - Pattern::Identifier { - ident: "#record_builder_closure_arg_a", - }, - ), - Loc::at( - region, - Pattern::Identifier { - ident: "#record_builder_closure_arg_b", - }, - ), - ]), - env.arena.alloc(Loc::at(region, closure_body)), - ), - )) - }; - - let closure_args = { - if field_data.len() == 2 { - env.arena.alloc_slice_copy(&[ - closure_arg_from_field(&field_data[0]), - closure_arg_from_field(&field_data[1]), - ]) - } else { - let second_to_last_arg = - closure_arg_from_field(&field_data[field_data.len() - 2]); - let last_arg = closure_arg_from_field(&field_data[field_data.len() - 1]); - - let mut second_arg = Pattern::Tuple(Collection::with_items( - env.arena.alloc_slice_copy(&[second_to_last_arg, last_arg]), - )); - let mut second_arg_region = - Region::span_across(&second_to_last_arg.region, &last_arg.region); - - for index in (1..(field_data.len() - 2)).rev() { - second_arg = - Pattern::Tuple(Collection::with_items(env.arena.alloc_slice_copy(&[ - closure_arg_from_field(&field_data[index]), - Loc::at(second_arg_region, second_arg), - ]))); - second_arg_region = - Region::span_across(&field_data[index].name.region, &second_arg_region); - } - - env.arena.alloc_slice_copy(&[ - closure_arg_from_field(&field_data[0]), - Loc::at(second_arg_region, second_arg), - ]) - } - }; - - let record_val = Record(Collection::with_items( - Vec::from_iter_in( - field_data - .iter() - .filter(|field| !field.ignored) - .map(|field| { - Loc::at( - field.name.region, - AssignedField::RequiredValue( - field.name, - &[], - env.arena.alloc(Loc::at( - field.name.region, - Expr::Var { - module_name: "", - ident: env - .arena - .alloc_str(&format!("#{}", field.name.value)), - }, - )), - ), - ) - }), - env.arena, - ) - .into_bump_slice(), - )); - - let record_combiner_closure = env.arena.alloc(Loc { - region: loc_expr.region, - value: Closure( - closure_args, - env.arena.alloc(Loc::at(loc_expr.region, record_val)), - ), - }); - - if field_data.len() == 2 { - return env.arena.alloc(Loc { - region: loc_expr.region, - value: Apply( - new_mapper, - env.arena.alloc_slice_copy(&[ - field_data[0].value, - field_data[1].value, - record_combiner_closure, - ]), - CalledVia::RecordBuilder, - ), - }); - } - - let mut inner_combined = env.arena.alloc(Loc { - region: Region::span_across( - &field_data[field_data.len() - 2].value.region, - &field_data[field_data.len() - 1].value.region, - ), - value: Apply( - new_mapper, - env.arena.alloc_slice_copy(&[ - field_data[field_data.len() - 2].value, - field_data[field_data.len() - 1].value, - combiner_closure_in_region(loc_expr.region), - ]), - CalledVia::RecordBuilder, - ), - }); - - for index in (1..(field_data.len() - 2)).rev() { - inner_combined = env.arena.alloc(Loc { - region: Region::span_across( - &field_data[index].value.region, - &inner_combined.region, - ), - value: Apply( - new_mapper, - env.arena.alloc_slice_copy(&[ - field_data[index].value, - inner_combined, - combiner_closure_in_region(loc_expr.region), - ]), - CalledVia::RecordBuilder, - ), - }); - } - - env.arena.alloc(Loc { - region: loc_expr.region, - value: Apply( - new_mapper, - env.arena.alloc_slice_copy(&[ - field_data[0].value, - inner_combined, - record_combiner_closure, - ]), - CalledVia::RecordBuilder, - ), - }) - } - BinOps(lefts, right) => desugar_bin_ops(env, scope, loc_expr.region, lefts, right), - Defs(defs, loc_ret) => { - let mut defs = (*defs).clone(); - desugar_defs_node_values(env, scope, &mut defs); - let loc_ret = desugar_expr(env, scope, loc_ret); - - env.arena.alloc(Loc::at( - loc_expr.region, - Defs(env.arena.alloc(defs), loc_ret), - )) - } - Apply(Loc { value: Dbg, .. }, loc_args, _called_via) => { - debug_assert!(!loc_args.is_empty()); - - if loc_args.len() > 1 { - let args_region = Region::span_across( - &loc_args.first().unwrap().region, - &loc_args.last().unwrap().region, - ); - env.problem(Problem::OverAppliedDbg { - region: args_region, - }); - - env.arena.alloc(Loc { - value: *desugar_invalid_dbg_expr(env, scope, loc_expr.region), - region: loc_expr.region, - }) - } else { - let desugared_arg = desugar_expr(env, scope, loc_args.first().unwrap()); - - env.arena.alloc(Loc { - value: *desugar_dbg_expr(env, scope, desugared_arg, loc_expr.region), - region: loc_expr.region, - }) - } - } - Apply( - Loc { - value: Try, - region: _, - }, - loc_args, - _called_via, - ) => { - let result_expr = if loc_args.len() == 1 { - desugar_expr(env, scope, loc_args[0]) - } else { - let function = desugar_expr(env, scope, loc_args.first().unwrap()); - let mut desugared_args = Vec::with_capacity_in(loc_args.len() - 1, env.arena); - for loc_arg in &loc_args[1..] { - desugared_args.push(desugar_expr(env, scope, loc_arg)); - } - - let args_region = - Region::span_across(&loc_args[0].region, &loc_args[loc_args.len() - 1].region); - - env.arena.alloc(Loc::at( - args_region, - Expr::Apply(function, desugared_args.into_bump_slice(), CalledVia::Try), - )) - }; - - env.arena.alloc(Loc::at( - loc_expr.region, - Expr::LowLevelTry(result_expr, ResultTryKind::KeywordPrefix), - )) - } - Apply( - Loc { - value: TrySuffix(fn_expr), - region: fn_region, - }, - loc_args, - _called_via, - ) => { - let loc_fn = env.arena.alloc(Loc::at(*fn_region, **fn_expr)); - let function = desugar_expr(env, scope, loc_fn); - - let mut desugared_args = Vec::with_capacity_in(loc_args.len(), env.arena); - for loc_arg in &loc_args[..] { - desugared_args.push(desugar_expr(env, scope, loc_arg)); - } - - let args_region = - Region::span_across(&loc_args[0].region, &loc_args[loc_args.len() - 1].region); - - let result_expr = env.arena.alloc(Loc::at( - args_region, - Expr::Apply(function, desugared_args.into_bump_slice(), CalledVia::Try), - )); - - env.arena.alloc(Loc::at( - loc_expr.region, - Expr::LowLevelTry(result_expr, ResultTryKind::OperatorSuffix), - )) - } - Apply(loc_fn, loc_args, called_via) => { - let mut desugared_args = Vec::with_capacity_in(loc_args.len(), env.arena); - - for loc_arg in loc_args.iter() { - let mut current = loc_arg.value; - let arg = loop { - match current { - SpaceBefore(expr, _) | SpaceAfter(expr, _) => { - current = *expr; - } - _ => break loc_arg, - } - }; - - desugared_args.push(desugar_expr(env, scope, arg)); - } - - let desugared_args = desugared_args.into_bump_slice(); - - env.arena.alloc(Loc { - value: Apply( - desugar_expr(env, scope, loc_fn), - desugared_args, - *called_via, - ), - region: loc_expr.region, - }) - } - PncApply(Loc { value: Dbg, .. }, loc_args) => { - if loc_args.is_empty() { - env.problem(Problem::UnappliedDbg { - region: loc_expr.region, - }); - env.arena.alloc(Loc { - value: *desugar_invalid_dbg_expr(env, scope, loc_expr.region), - region: loc_expr.region, - }) - } else if loc_args.len() > 1 { - let args_region = Region::span_across( - &loc_args.items.first().unwrap().region, - &loc_args.items.last().unwrap().region, - ); - env.problem(Problem::OverAppliedDbg { - region: args_region, - }); - - env.arena.alloc(Loc { - value: *desugar_invalid_dbg_expr(env, scope, loc_expr.region), - region: loc_expr.region, - }) - } else { - let desugared_arg = desugar_expr(env, scope, loc_args.items.first().unwrap()); - - env.arena.alloc(Loc { - value: *desugar_dbg_expr(env, scope, desugared_arg, loc_expr.region), - region: loc_expr.region, - }) - } - } - PncApply( - Loc { - value: Try, - region: _, - }, - loc_args, - ) => { - let result_expr = if loc_args.is_empty() { - env.problem(Problem::UnderAppliedTry { - region: loc_expr.region, - }); - // Replace with a dummy expression to avoid cascading errors - env.arena.alloc(Loc { - value: Record(Collection::empty()), - region: loc_expr.region, - }) - } else if loc_args.len() == 1 { - desugar_expr(env, scope, loc_args.items[0]) - } else { - let function = desugar_expr(env, scope, loc_args.items.first().unwrap()); - let mut desugared_args = Vec::with_capacity_in(loc_args.len() - 1, env.arena); - for loc_arg in &loc_args.items[1..] { - desugared_args.push(desugar_expr(env, scope, loc_arg)); - } - - let args_region = Region::span_across( - &loc_args.items[0].region, - &loc_args.items[loc_args.items.len() - 1].region, - ); - - env.arena.alloc(Loc::at( - args_region, - Expr::Apply(function, desugared_args.into_bump_slice(), CalledVia::Try), - )) - }; - - env.arena.alloc(Loc::at( - loc_expr.region, - Expr::LowLevelTry(result_expr, ResultTryKind::KeywordPrefix), - )) - } - PncApply(loc_fn, loc_args) => { - let mut desugared_args = Vec::with_capacity_in(loc_args.len(), env.arena); - - for loc_arg in loc_args.iter() { - let mut current = loc_arg.value; - let arg = loop { - match current { - SpaceBefore(expr, _) | SpaceAfter(expr, _) => { - current = *expr; - } - _ => break loc_arg, - } - }; - - desugared_args.push(desugar_expr(env, scope, arg)); - } - - let desugared_args = Collection::with_items(desugared_args.into_bump_slice()); - - env.arena.alloc(Loc { - value: PncApply(desugar_expr(env, scope, loc_fn), desugared_args), - region: loc_expr.region, - }) - } - - When(loc_cond_expr, branches) => { - let loc_desugared_cond = &*env.arena.alloc(desugar_expr(env, scope, loc_cond_expr)); - let mut desugared_branches = Vec::with_capacity_in(branches.len(), env.arena); - - for branch in branches.iter() { - let desugared_expr = desugar_expr(env, scope, &branch.value); - let desugared_patterns = desugar_loc_patterns(env, scope, branch.patterns); - - let desugared_guard = if let Some(guard) = &branch.guard { - Some(*desugar_expr(env, scope, guard)) - } else { - None - }; - - desugared_branches.push(&*env.arena.alloc(WhenBranch { - patterns: desugared_patterns, - value: *desugared_expr, - guard: desugared_guard, - })); - } - - let desugared_branches = desugared_branches.into_bump_slice(); - - env.arena.alloc(Loc { - value: When(loc_desugared_cond, desugared_branches), - region: loc_expr.region, - }) - } - UnaryOp(loc_arg, loc_op) => { - use roc_module::called_via::UnaryOp::*; - - let region = loc_op.region; - let op = loc_op.value; - // TODO desugar this in canonicalization instead, so we can work - // in terms of integers exclusively and not need to create strings - // which canonicalization then needs to look up, check if they're exposed, etc - let value = match op { - Negate => Var { - module_name: ModuleName::NUM, - ident: "neg", - }, - Not => Var { - module_name: ModuleName::BOOL, - ident: "not", - }, - }; - let loc_fn_var = env.arena.alloc(Loc { region, value }); - let desugared_args = env.arena.alloc([desugar_expr(env, scope, loc_arg)]); - - env.arena.alloc(Loc { - value: Apply(loc_fn_var, desugared_args, CalledVia::UnaryOp(op)), - region: loc_expr.region, - }) - } - SpaceBefore(expr, _) | SpaceAfter(expr, _) => { - // Since we've already begun canonicalization, spaces and parens - // are no longer needed and should be dropped. - desugar_expr( - env, - scope, - env.arena.alloc(Loc { - value: **expr, - region: loc_expr.region, - }), - ) - } - ParensAround(expr) => { - let desugared = desugar_expr( - env, - scope, - env.arena.alloc(Loc { - value: **expr, - region: loc_expr.region, - }), - ); - - env.arena.alloc(Loc { - value: ParensAround(&desugared.value), - region: loc_expr.region, - }) - } - If { - if_thens, - final_else, - indented_else, - } => { - // If does not get desugared into `when` so we can give more targeted error messages during type checking. - let desugared_final_else = &*env.arena.alloc(desugar_expr(env, scope, final_else)); - - let mut desugared_if_thens = Vec::with_capacity_in(if_thens.len(), env.arena); - - for (condition, then_branch) in if_thens.iter() { - let desugared_condition = *desugar_expr(env, scope, condition); - let desugared_then_branch = *desugar_expr(env, scope, then_branch); - - desugared_if_thens.push((desugared_condition, desugared_then_branch)); - } - - env.arena.alloc(Loc { - value: If { - if_thens: desugared_if_thens.into_bump_slice(), - final_else: desugared_final_else, - indented_else: *indented_else, - }, - region: loc_expr.region, - }) - } - Dbg => { - // Allow naked dbg, necessary for piping values into dbg with the `Pizza` binop - loc_expr - } - DbgStmt { - first: condition, - extra_args, - continuation, - pnc_style: _, - } => { - let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition)); - let desugared_continuation = &*env.arena.alloc(desugar_expr(env, scope, continuation)); - - if let Some(last) = extra_args.last() { - let args_region = Region::span_across(&condition.region, &last.region); - env.problem(Problem::OverAppliedDbg { - region: args_region, - }); - } - - env.arena.alloc(Loc { - value: *desugar_dbg_stmt(env, desugared_condition, desugared_continuation), - region: loc_expr.region, - }) - } - Return(return_value, after_return) => { - let desugared_return_value = &*env.arena.alloc(desugar_expr(env, scope, return_value)); - - env.arena.alloc(Loc { - // Do not desugar after_return since it isn't run anyway - value: Return(desugared_return_value, *after_return), - region: loc_expr.region, - }) - } - - // note these only exist after desugaring - LowLevelDbg(_, _, _) | LowLevelTry(_, _) => loc_expr, - } -} - -fn desugar_str_segments<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - segments: &'a [StrSegment<'a>], -) -> &'a [StrSegment<'a>] { - let mut allocated = Vec::with_capacity_in(segments.len(), env.arena); - - for segment in segments.iter() { - allocated.push(match segment { - StrSegment::Plaintext(_) | StrSegment::Unicode(_) | StrSegment::EscapedChar(_) => { - *segment - } - StrSegment::Interpolated(loc_expr) => { - let loc_desugared = desugar_expr( - env, - scope, - env.arena.alloc(Loc { - region: loc_expr.region, - value: *loc_expr.value, - }), - ); - StrSegment::Interpolated(Loc { - region: loc_desugared.region, - value: env.arena.alloc(loc_desugared.value), - }) - } - }); - } - - allocated.into_bump_slice() -} - -fn desugar_field_collection<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - fields: Collection<'a, Loc>>>, -) -> Collection<'a, Loc>>> { - let mut allocated = Vec::with_capacity_in(fields.len(), env.arena); - - for field in fields.iter() { - let value = desugar_field(env, scope, &field.value); - - allocated.push(Loc::at(field.region, value)); - } - - fields.replace_items(allocated.into_bump_slice()) -} - -fn desugar_field<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - field: &'a AssignedField<'a, Expr<'a>>, -) -> AssignedField<'a, Expr<'a>> { - use roc_parse::ast::AssignedField::*; - - match field { - RequiredValue(loc_str, spaces, loc_expr) => RequiredValue( - Loc { - value: loc_str.value, - region: loc_str.region, - }, - spaces, - desugar_expr(env, scope, loc_expr), - ), - OptionalValue(loc_str, spaces, loc_expr) => OptionalValue( - Loc { - value: loc_str.value, - region: loc_str.region, - }, - spaces, - desugar_expr(env, scope, loc_expr), - ), - IgnoredValue(loc_str, spaces, loc_expr) => IgnoredValue( - Loc { - value: loc_str.value, - region: loc_str.region, - }, - spaces, - desugar_expr(env, scope, loc_expr), - ), - LabelOnly(loc_str) => { - // Desugar { x } into { x: x } - let loc_expr = Loc { - value: Var { - module_name: "", - ident: loc_str.value, - }, - region: loc_str.region, - }; - - RequiredValue( - Loc { - value: loc_str.value, - region: loc_str.region, - }, - &[], - desugar_expr(env, scope, env.arena.alloc(loc_expr)), - ) - } - SpaceBefore(field, _spaces) => desugar_field(env, scope, field), - SpaceAfter(field, _spaces) => desugar_field(env, scope, field), - } -} - -fn desugar_loc_patterns<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - loc_patterns: &'a [Loc>], -) -> &'a [Loc>] { - let mut allocated = Vec::with_capacity_in(loc_patterns.len(), env.arena); - - for loc_pattern in loc_patterns.iter() { - allocated.push(Loc { - region: loc_pattern.region, - value: desugar_pattern(env, scope, loc_pattern.value), - }); - } - - allocated.into_bump_slice() -} - -fn desugar_loc_pattern<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - loc_pattern: &'a Loc>, -) -> &'a Loc> { - env.arena.alloc(Loc { - region: loc_pattern.region, - value: desugar_pattern(env, scope, loc_pattern.value), - }) -} - -fn desugar_pattern<'a>(env: &mut Env<'a>, scope: &mut Scope, pattern: Pattern<'a>) -> Pattern<'a> { - use roc_parse::ast::Pattern::*; - - match pattern { - Identifier { .. } - | Tag(_) - | OpaqueRef(_) - | NumLiteral(_) - | NonBase10Literal { .. } - | FloatLiteral(_) - | StrLiteral(_) - | Underscore(_) - | SingleQuote(_) - | ListRest(_) - | Malformed(_) - | MalformedIdent(_, _) - | MalformedExpr(_) - | QualifiedIdentifier { .. } => pattern, - - Apply(tag, arg_patterns) => { - // Skip desugaring the tag, it should either be a Tag or OpaqueRef - let mut desugared_arg_patterns = Vec::with_capacity_in(arg_patterns.len(), env.arena); - for arg_pattern in arg_patterns.iter() { - desugared_arg_patterns.push(Loc { - region: arg_pattern.region, - value: desugar_pattern(env, scope, arg_pattern.value), - }); - } - - Apply(tag, desugared_arg_patterns.into_bump_slice()) - } - PncApply(tag, arg_patterns) => { - // Skip desugaring the tag, it should either be a Tag or OpaqueRef - let mut desugared_arg_patterns = Vec::with_capacity_in(arg_patterns.len(), env.arena); - for arg_pattern in arg_patterns.iter() { - desugared_arg_patterns.push(Loc { - region: arg_pattern.region, - value: desugar_pattern(env, scope, arg_pattern.value), - }); - } - - PncApply( - tag, - Collection::with_items(desugared_arg_patterns.into_bump_slice()), - ) - } - RecordDestructure(field_patterns) => { - RecordDestructure(desugar_record_destructures(env, scope, field_patterns)) - } - RequiredField(name, field_pattern) => { - RequiredField(name, desugar_loc_pattern(env, scope, field_pattern)) - } - OptionalField(name, expr) => OptionalField(name, desugar_expr(env, scope, expr)), - Tuple(patterns) => { - let mut allocated = Vec::with_capacity_in(patterns.len(), env.arena); - for pattern in patterns.iter() { - let value = desugar_pattern(env, scope, pattern.value); - allocated.push(Loc { - value, - region: pattern.region, - }); - } - let patterns = patterns.replace_items(allocated.into_bump_slice()); - - Tuple(patterns) - } - List(patterns) => { - let mut allocated = Vec::with_capacity_in(patterns.len(), env.arena); - for pattern in patterns.iter() { - let value = desugar_pattern(env, scope, pattern.value); - allocated.push(Loc { - value, - region: pattern.region, - }); - } - let patterns = patterns.replace_items(allocated.into_bump_slice()); - - List(patterns) - } - As(sub_pattern, symbol) => As(desugar_loc_pattern(env, scope, sub_pattern), symbol), - SpaceBefore(sub_pattern, _spaces) => desugar_pattern(env, scope, *sub_pattern), - SpaceAfter(sub_pattern, _spaces) => desugar_pattern(env, scope, *sub_pattern), - } -} - -pub fn desugar_record_destructures<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - field_patterns: Collection<'a, Loc>>, -) -> Collection<'a, Loc>> { - let mut allocated = Vec::with_capacity_in(field_patterns.len(), env.arena); - for field_pattern in field_patterns.iter() { - let value = desugar_pattern(env, scope, field_pattern.value); - allocated.push(Loc { - value, - region: field_pattern.region, - }); - } - - field_patterns.replace_items(allocated.into_bump_slice()) -} - /// Desugars a `dbg expr` expression into a statement block that prints and returns the /// value produced by `expr`. Essentially: /// ( @@ -1659,195 +116,3 @@ fn desugar_dbg_stmt<'a>( continuation, )) } - -// TODO move this desugaring to canonicalization, so we can use Symbols instead of strings -#[inline(always)] -fn binop_to_function(binop: BinOp) -> (&'static str, &'static str) { - use self::BinOp::*; - - match binop { - Caret => (ModuleName::NUM, "pow"), - Star => (ModuleName::NUM, "mul"), - Slash => (ModuleName::NUM, "div"), - DoubleSlash => (ModuleName::NUM, "div_trunc"), - Percent => (ModuleName::NUM, "rem"), - Plus => (ModuleName::NUM, "add"), - Minus => (ModuleName::NUM, "sub"), - Equals => (ModuleName::BOOL, "is_eq"), - NotEquals => (ModuleName::BOOL, "is_not_eq"), - LessThan => (ModuleName::NUM, "is_lt"), - GreaterThan => (ModuleName::NUM, "is_gt"), - LessThanOrEq => (ModuleName::NUM, "is_lte"), - GreaterThanOrEq => (ModuleName::NUM, "is_gte"), - And => unreachable!("Cannot desugar the `and` operator"), - Or => unreachable!("Cannot desugar the `or` operator"), - Pizza => unreachable!("Cannot desugar the |> operator"), - DoubleQuestion => unreachable!("Cannot desugar the ?? operator"), - SingleQuestion => unreachable!("Cannot desugar the ? operator"), - } -} - -fn desugar_bin_ops<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - whole_region: Region, - lefts: &'a [(Loc>, Loc)], - right: &'a Loc>, -) -> &'a Loc> { - let mut arg_stack: Vec<&'a Loc> = Vec::with_capacity_in(lefts.len() + 1, env.arena); - let mut op_stack: Vec> = Vec::with_capacity_in(lefts.len(), env.arena); - - for (loc_expr, loc_op) in lefts { - arg_stack.push(loc_expr); - match run_binop_step( - env, - scope, - whole_region, - &mut arg_stack, - &mut op_stack, - *loc_op, - ) { - Err(problem) => return problem, - Ok(()) => continue, - } - } - - let mut expr = right; - - for (left, loc_op) in arg_stack.into_iter().zip(op_stack.into_iter()).rev() { - expr = env - .arena - .alloc(new_op_call_expr(env, scope, left, loc_op, expr)); - } - - expr -} - -enum Step<'a> { - Error(&'a Loc>), - Push(Loc), - Skip, -} - -fn run_binop_step<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - whole_region: Region, - arg_stack: &mut Vec<&'a Loc>>, - op_stack: &mut Vec>, - next_op: Loc, -) -> Result<(), &'a Loc>> { - use Step::*; - - match binop_step(env, scope, whole_region, arg_stack, op_stack, next_op) { - Error(problem) => Err(problem), - Push(loc_op) => run_binop_step(env, scope, whole_region, arg_stack, op_stack, loc_op), - Skip => Ok(()), - } -} - -fn binop_step<'a>( - env: &mut Env<'a>, - scope: &mut Scope, - whole_region: Region, - arg_stack: &mut Vec<&'a Loc>>, - op_stack: &mut Vec>, - next_op: Loc, -) -> Step<'a> { - use roc_module::called_via::Associativity::*; - use std::cmp::Ordering; - - match op_stack.pop() { - Some(stack_op) => { - match next_op.value.cmp(&stack_op.value) { - Ordering::Less => { - // Inline - let right = arg_stack.pop().unwrap(); - let left = arg_stack.pop().unwrap(); - - arg_stack.push( - env.arena - .alloc(new_op_call_expr(env, scope, left, stack_op, right)), - ); - - Step::Push(next_op) - } - - Ordering::Greater => { - // Swap - op_stack.push(stack_op); - op_stack.push(next_op); - - Step::Skip - } - - Ordering::Equal => { - match ( - next_op.value.associativity(), - stack_op.value.associativity(), - ) { - (LeftAssociative, LeftAssociative) => { - // Inline - let right = arg_stack.pop().unwrap(); - let left = arg_stack.pop().unwrap(); - - arg_stack.push( - env.arena - .alloc(new_op_call_expr(env, scope, left, stack_op, right)), - ); - - Step::Push(next_op) - } - - (RightAssociative, RightAssociative) => { - // Swap - op_stack.push(stack_op); - op_stack.push(next_op); - - Step::Skip - } - - (NonAssociative, NonAssociative) => { - // Both operators were non-associative, e.g. (True == False == False). - // We should tell the author to disambiguate by grouping them with parens. - let bad_op = next_op; - let right = arg_stack.pop().unwrap(); - let left = arg_stack.pop().unwrap(); - let broken_expr = env - .arena - .alloc(new_op_call_expr(env, scope, left, stack_op, right)); - let region = broken_expr.region; - let data = roc_parse::ast::PrecedenceConflict { - whole_region, - binop1_position: stack_op.region.start(), - binop1: stack_op.value, - binop2_position: bad_op.region.start(), - binop2: bad_op.value, - expr: env.arena.alloc(broken_expr), - }; - let value = Expr::PrecedenceConflict(env.arena.alloc(data)); - - Step::Error(env.arena.alloc(Loc { region, value })) - } - - _ => { - // The operators had the same precedence but different associativity. - // - // In many languages, this case can happen due to (for example) <| and |> having the same - // precedence but different associativity. Languages which support custom operators with - // (e.g. Haskell) can potentially have arbitrarily many of these cases. - // - // By design, Roc neither allows custom operators nor has any built-in operators with - // the same precedence and different associativity, so this should never happen! - internal_error!("BinOps had the same associativity, but different precedence. This should never happen!"); - } - } - } - } - } - None => { - op_stack.push(next_op); - Step::Skip - } - } -} diff --git a/crates/compiler/can/src/env.rs b/crates/compiler/can/src/env.rs index 176fcefebcd..1328b311276 100644 --- a/crates/compiler/can/src/env.rs +++ b/crates/compiler/can/src/env.rs @@ -11,6 +11,7 @@ use roc_region::all::{LineInfo, Loc, Region}; use roc_types::subs::Variable; /// The canonicalization environment for a particular module. +#[derive(Debug)] pub struct Env<'a> { /// The module's path. Opaques and unqualified references to identifiers /// are assumed to be relative to this path. @@ -51,6 +52,36 @@ pub struct Env<'a> { } impl<'a> Env<'a> { + #[allow(clippy::too_many_arguments)] + pub fn from_solo_can( + arena: &'a Bump, + module_path: &'a Path, + home: ModuleId, + dep_idents: &'a IdentIdsByModule, + qualified_module_ids: &'a PackageModuleIds<'a>, + problems: Vec, + opt_shorthand: Option<&'a str>, + src: &'a str, + line_info: &'a mut Option, + ) -> Self { + Env { + arena, + src, + home, + module_path, + dep_idents, + qualified_module_ids, + problems, + closures: MutMap::default(), + qualified_value_lookups: Default::default(), + tailcallable_symbol: None, + top_level_symbols: Default::default(), + home_params_record: None, + opt_shorthand, + line_info, + } + } + #[allow(clippy::too_many_arguments)] pub fn new( arena: &'a Bump, diff --git a/crates/compiler/can/src/module.rs b/crates/compiler/can/src/module.rs index fd61d0682b5..40673b807e9 100644 --- a/crates/compiler/can/src/module.rs +++ b/crates/compiler/can/src/module.rs @@ -1,9 +1,6 @@ -use std::path::Path; - use crate::abilities::{AbilitiesStore, ImplKey, PendingAbilitiesStore, ResolvedImpl}; use crate::annotation::{canonicalize_annotation, AnnotationFor}; use crate::def::{canonicalize_defs, report_unused_imports, Def, DefKind}; -use crate::desugar::desugar_record_destructures; use crate::env::Env; use crate::expr::{ClosureData, Declarations, ExpectLookup, Expr, Output, PendingDerives}; use crate::pattern::{ @@ -16,8 +13,8 @@ use roc_collections::{MutMap, SendMap, VecMap, VecSet}; use roc_error_macros::internal_error; use roc_module::ident::Ident; use roc_module::ident::Lowercase; -use roc_module::symbol::{IdentId, IdentIds, IdentIdsByModule, ModuleId, PackageModuleIds, Symbol}; -use roc_parse::ast::{Defs, TypeAnnotation}; +use roc_module::symbol::{IdentId, ModuleId, Symbol}; +use roc_parse::ast::{Collection, Defs, Pattern as ParsePattern, TypeAnnotation}; use roc_parse::header::HeaderType; use roc_parse::pattern::PatternType; use roc_problem::can::{Problem, RuntimeError}; @@ -209,55 +206,19 @@ fn has_no_implementation(expr: &Expr) -> bool { #[allow(clippy::too_many_arguments)] pub fn canonicalize_module_defs<'a>( arena: &'a Bump, - loc_defs: &'a mut Defs<'a>, header_type: &'a roc_parse::header::HeaderType, home: ModuleId, - module_path: &'a str, - src: &'a str, - qualified_module_ids: &'a PackageModuleIds<'a>, - exposed_ident_ids: IdentIds, - dep_idents: &'a IdentIdsByModule, - aliases: MutMap, - imported_abilities_state: PendingAbilitiesStore, initial_scope: MutMap, exposed_symbols: VecSet, symbols_from_requires: &[(Loc, Loc>)], var_store: &mut VarStore, - opt_shorthand: Option<&'a str>, + mut scope: Scope, + mut env: Env<'a>, + loc_defs: Defs<'a>, + module_params: Option<(Region, Collection<'a, Loc>>)>, ) -> ModuleOutput { let mut can_exposed_imports = MutMap::default(); - let mut scope = Scope::new( - home, - qualified_module_ids - .get_name(home) - .expect("home module not found") - .as_inner() - .to_owned(), - exposed_ident_ids, - imported_abilities_state, - ); - let mut env = Env::new( - arena, - src, - home, - arena.alloc(Path::new(module_path)), - dep_idents, - qualified_module_ids, - opt_shorthand, - ); - - for (name, alias) in aliases.into_iter() { - scope.add_alias( - name, - alias.region, - alias.type_variables, - alias.infer_ext_in_output_variables, - alias.typ, - alias.kind, - ); - } - // Desugar operators (convert them to Apply calls, taking into account // operator precedence and associativity rules), before doing other canonicalization. // @@ -266,8 +227,6 @@ pub fn canonicalize_module_defs<'a>( // operators, and then again on *their* nested operators, ultimately applying the // rules multiple times unnecessarily. - crate::desugar::desugar_defs_node_values(&mut env, &mut scope, loc_defs); - let mut rigid_variables = RigidVariables::default(); // Initial scope values are treated like defs that appear before any others. @@ -319,51 +278,42 @@ pub fn canonicalize_module_defs<'a>( let mut output = Output::default(); - let module_params = header_type.get_params().as_ref().map( - |roc_parse::header::ModuleParams { - pattern, - before_arrow: _, - after_arrow: _, - }| { - let desugared_patterns = - desugar_record_destructures(&mut env, &mut scope, pattern.value); - - let (destructs, _) = canonicalize_record_destructs( - &mut env, - var_store, - &mut scope, - &mut output, - PatternType::ModuleParams, - &desugared_patterns, - pattern.region, - PermitShadows(false), - ); + let module_params = module_params.map(|(params_region, desugared_patterns)| { + let (destructs, _) = canonicalize_record_destructs( + &mut env, + var_store, + &mut scope, + &mut output, + PatternType::ModuleParams, + &desugared_patterns, + params_region, + PermitShadows(false), + ); - let whole_symbol = scope.gen_unique_symbol(); - env.top_level_symbols.insert(whole_symbol); + let whole_symbol = scope.gen_unique_symbol(); + env.top_level_symbols.insert(whole_symbol); - let whole_var = var_store.fresh(); + let whole_var = var_store.fresh(); - env.home_params_record = Some((whole_symbol, whole_var)); + env.home_params_record = Some((whole_symbol, whole_var)); - ModuleParams { - region: pattern.region, - whole_var, - whole_symbol, - record_var: var_store.fresh(), - record_ext_var: var_store.fresh(), - destructs, - arity_by_name: Default::default(), - } - }, - ); + ModuleParams { + region: params_region, + whole_var, + whole_symbol, + record_var: var_store.fresh(), + record_ext_var: var_store.fresh(), + destructs, + arity_by_name: Default::default(), + } + }); let (defs, output, symbols_introduced, imports_introduced) = canonicalize_defs( &mut env, output, var_store, &mut scope, - loc_defs, + arena.alloc(loc_defs), PatternType::TopLevelDef, ); diff --git a/crates/compiler/can/tests/helpers/mod.rs b/crates/compiler/can/tests/helpers/mod.rs index 2cf41f4c034..8bd7569026b 100644 --- a/crates/compiler/can/tests/helpers/mod.rs +++ b/crates/compiler/can/tests/helpers/mod.rs @@ -1,10 +1,11 @@ extern crate bumpalo; use self::bumpalo::Bump; -use roc_can::desugar; use roc_can::env::Env; use roc_can::expr::{canonicalize_expr, Expr}; use roc_can::scope::Scope; +use roc_can_solo::env::SoloEnv; +use roc_can_solo::scope::SoloScope; use roc_collections::all::MutMap; use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, PackageModuleIds, Symbol}; use roc_problem::can::Problem; @@ -65,7 +66,9 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut // visited a BinOp node we'd recursively try to apply this to each of its nested // operators, and then again on *their* nested operators, ultimately applying the // rules multiple times unnecessarily. - let loc_expr = desugar::desugar_expr(&mut env, &mut scope, &loc_expr); + let mut solo_env = SoloEnv::new(arena, expr_str, Path::new("Test.roc")); + let mut solo_scope = SoloScope::new(); + let loc_expr = roc_can_solo::desugar::desugar_expr(&mut solo_env, &mut solo_scope, &loc_expr); scope.add_alias( Symbol::NUM_INT, diff --git a/crates/compiler/load/Cargo.toml b/crates/compiler/load/Cargo.toml index 8dc9d214fe3..aa719b6b384 100644 --- a/crates/compiler/load/Cargo.toml +++ b/crates/compiler/load/Cargo.toml @@ -9,6 +9,7 @@ version.workspace = true [dependencies] roc_can.workspace = true +roc_can_solo.workspace = true roc_collections.workspace = true roc_load_internal.workspace = true roc_module.workspace = true diff --git a/crates/compiler/load/tests/helpers/mod.rs b/crates/compiler/load/tests/helpers/mod.rs index 393d9b5b6c1..4f0432c36f9 100644 --- a/crates/compiler/load/tests/helpers/mod.rs +++ b/crates/compiler/load/tests/helpers/mod.rs @@ -3,11 +3,12 @@ extern crate bumpalo; use self::bumpalo::Bump; use roc_can::abilities::AbilitiesStore; use roc_can::constraint::{Constraint, Constraints}; -use roc_can::desugar; use roc_can::env::Env; use roc_can::expected::Expected; use roc_can::expr::{canonicalize_expr, Expr, Output, PendingDerives}; use roc_can::scope::Scope; +use roc_can_solo::env::SoloEnv; +use roc_can_solo::scope::SoloScope; use roc_collections::all::{ImMap, MutMap, SendSet}; use roc_constrain::expr::constrain_expr; use roc_derive::SharedDerivedModule; @@ -162,24 +163,6 @@ pub fn can_expr_with<'a>( // ensure the Test module is accessible in our tests module_ids.get_or_insert(&PQModuleName::Unqualified("Test".into())); - let mut scope = Scope::new( - home, - "TestPath".into(), - IdentIds::default(), - Default::default(), - ); - - let dep_idents = IdentIds::exposed_builtins(0); - let mut env = Env::new( - arena, - expr_str, - home, - Path::new("Test.roc"), - &dep_idents, - &module_ids, - None, - ); - // Desugar operators (convert them to Apply calls, taking into account // operator precedence and associativity rules), before doing other canonicalization. // @@ -187,7 +170,9 @@ pub fn can_expr_with<'a>( // visited a BinOp node we'd recursively try to apply this to each of its nested // operators, and then again on *their* nested operators, ultimately applying the // rules multiple times unnecessarily. - let loc_expr = desugar::desugar_expr(&mut env, &mut scope, &loc_expr); + let mut solo_env = SoloEnv::new(arena, expr_str, Path::new("Test.roc")); + let mut solo_scope = SoloScope::new(); + let loc_expr = roc_can_solo::desugar::desugar_expr(&mut solo_env, &mut solo_scope, &loc_expr); let mut scope = Scope::new( home, diff --git a/crates/compiler/load_internal/Cargo.toml b/crates/compiler/load_internal/Cargo.toml index d062bf21d9c..e957090353d 100644 --- a/crates/compiler/load_internal/Cargo.toml +++ b/crates/compiler/load_internal/Cargo.toml @@ -10,6 +10,7 @@ version.workspace = true [dependencies] roc_builtins.workspace = true roc_can.workspace = true +roc_can_solo.workspace = true roc_work.workspace = true roc_checkmate.workspace = true roc_collections.workspace = true @@ -39,6 +40,8 @@ bumpalo.workspace = true crossbeam.workspace = true parking_lot.workspace = true tempfile.workspace = true +base64-url.workspace = true +blake3.workspace = true [dev-dependencies] roc_test_utils_dir.workspace = true diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index ec50636f067..5a223558981 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -15,11 +15,14 @@ use parking_lot::Mutex; use roc_builtins::roc::module_source; use roc_can::abilities::{AbilitiesStore, PendingAbilitiesStore, ResolvedImpl}; use roc_can::constraint::{Constraint as ConstraintSoa, Constraints, TypeOrVar}; +use roc_can::env::Env; use roc_can::expr::{Declarations, ExpectLookup, PendingDerives}; use roc_can::module::{ canonicalize_module_defs, ExposedByModule, ExposedForModule, ExposedModuleTypes, Module, ModuleParams, ResolvedImplementations, TypeState, }; +use roc_can::scope::Scope; +use roc_can_solo::module::{solo_canonicalize_module_defs, SoloCanOutput}; use roc_collections::soa::slice_extend_new; use roc_collections::{default_hasher, BumpMap, MutMap, MutSet, VecMap, VecSet}; use roc_constrain::module::constrain_module; @@ -204,9 +207,20 @@ fn start_phase<'a>( root_type: state.root_type.clone(), } } + Phase::SoloCanonicalize => { + // canonicalize the file + let parsed = state.module_cache.parsed.get(&module_id).unwrap().clone(); + + BuildTask::SoloCanonicalize { parsed } + } Phase::CanonicalizeAndConstrain => { // canonicalize the file let parsed = state.module_cache.parsed.remove(&module_id).unwrap(); + let solo_can_output = state + .module_cache + .solo_canonicalized + .remove(&module_id) + .unwrap(); let deps_by_name = &parsed.deps_by_name; let num_deps = deps_by_name.len(); @@ -318,6 +332,7 @@ fn start_phase<'a>( exposed_module_ids: state.exposed_modules, exec_mode: state.exec_mode, imported_module_params, + solo_can_output, } } @@ -577,6 +592,7 @@ enum Msg<'a> { Many(Vec>), Header(ModuleHeader<'a>), Parsed(ParsedModule<'a>), + SoloCanonicalized(ModuleId, CanSolo<'a>), CanonicalizedAndConstrained(CanAndCon), SolvedTypes { module_id: ModuleId, @@ -651,6 +667,9 @@ enum Msg<'a> { IncorrectModuleName(FileError<'a, IncorrectModuleName<'a>>), } +#[derive(Debug)] +struct CanSolo<'a>(SoloCanOutput<'a>); + #[derive(Debug)] struct CanAndCon { constrained_module: ConstrainedModule, @@ -890,6 +909,9 @@ enum BuildTask<'a> { ident_ids_by_module: SharedIdentIdsByModule, root_type: RootType, }, + SoloCanonicalize { + parsed: ParsedModule<'a>, + }, CanonicalizeAndConstrain { parsed: ParsedModule<'a>, qualified_module_ids: PackageModuleIds<'a>, @@ -901,6 +923,7 @@ enum BuildTask<'a> { skip_constraint_gen: bool, exec_mode: ExecutionMode, imported_module_params: VecMap, + solo_can_output: SoloCanOutput<'a>, }, Solve { module: Module, @@ -2411,6 +2434,23 @@ fn update<'a>( Ok(state) } + SoloCanonicalized(module_id, CanSolo(solo_can_output)) => { + log!("solo canonicalized module {:?}", module_id); + + state + .module_cache + .solo_canonicalized + .insert(module_id, solo_can_output); + + let work = state + .dependencies + .notify(module_id, Phase::SoloCanonicalize); + + start_tasks(arena, &mut state, work, injector, worker_wakers)?; + + Ok(state) + } + CanonicalizedAndConstrained(CanAndCon { constrained_module, canonicalization_problems, @@ -2462,6 +2502,7 @@ fn update<'a>( Ok(state) } + SolvedTypes { module_id, ident_ids, @@ -5082,6 +5123,31 @@ fn build_platform_header<'a>( build_header(info, parse_state, module_ids, module_timing) } +#[allow(clippy::unnecessary_wraps)] +fn canonicalize_solo<'a>(arena: &'a Bump, parsed: ParsedModule<'a>) -> CanSolo<'a> { + let canonicalize_solo_start = Instant::now(); + + let ParsedModule { + module_path, + header_type, + src, + parsed_defs, + mut module_timing, + .. + } = parsed; + + let parsed_defs = arena.alloc(parsed_defs); + + let solo_can_output = + solo_canonicalize_module_defs(arena, header_type, parsed_defs, module_path, src); + + let canonicalize_solo_end = Instant::now(); + + module_timing.canonicalize_solo = canonicalize_solo_end.duration_since(canonicalize_solo_start); + + CanSolo(solo_can_output) +} + #[allow(clippy::unnecessary_wraps)] fn canonicalize_and_constrain<'a>( arena: &'a Bump, @@ -5095,21 +5161,21 @@ fn canonicalize_and_constrain<'a>( exposed_module_ids: &[ModuleId], exec_mode: ExecutionMode, imported_module_params: VecMap, + solo_can_output: SoloCanOutput<'a>, ) -> CanAndCon { let canonicalize_start = Instant::now(); let ParsedModule { module_id, module_path, - src, header_type, - exposed_ident_ids, parsed_defs, initial_scope, available_modules, mut module_timing, symbols_from_requires, opt_shorthand, + exposed_ident_ids, .. } = parsed; @@ -5117,27 +5183,55 @@ fn canonicalize_and_constrain<'a>( let _before = roc_types::types::get_type_clone_count(); let parsed_defs_for_docs = parsed_defs.clone(); - let parsed_defs = arena.alloc(parsed_defs); let mut var_store = VarStore::default(); - let mut module_output = canonicalize_module_defs( + let env = Env::from_solo_can( arena, - parsed_defs, - &header_type, + &module_path, module_id, - &*arena.alloc(module_path.to_string_lossy()), - src, + &dep_idents, qualified_module_ids, + solo_can_output.problems, + opt_shorthand, + solo_can_output.src, + solo_can_output.lazy_line_info, + ); + + let mut scope = Scope::new( + module_id, + qualified_module_ids + .get_name(module_id) + .expect("home module not found") + .as_inner() + .to_owned(), exposed_ident_ids, - &dep_idents, - aliases, imported_abilities_state, + ); + + for (name, alias) in aliases.into_iter() { + scope.add_alias( + name, + alias.region, + alias.type_variables, + alias.infer_ext_in_output_variables, + alias.typ, + alias.kind, + ); + } + + let mut module_output = canonicalize_module_defs( + arena, + &header_type, + module_id, initial_scope, exposed_symbols, &symbols_from_requires, &mut var_store, - opt_shorthand, + scope, + env, + solo_can_output.loc_defs, + solo_can_output.module_params, ); let mut types = Types::new(); @@ -6237,6 +6331,12 @@ fn run_task<'a>( ident_ids_by_module, root_type, ), + SoloCanonicalize { parsed } => { + let module_id = parsed.module_id; + let solo_can = canonicalize_solo(arena, parsed); + + Ok(Msg::SoloCanonicalized(module_id, solo_can)) + } CanonicalizeAndConstrain { parsed, qualified_module_ids, @@ -6248,6 +6348,7 @@ fn run_task<'a>( exposed_module_ids, exec_mode, imported_module_params, + solo_can_output, } => { let can_and_con = canonicalize_and_constrain( arena, @@ -6261,6 +6362,7 @@ fn run_task<'a>( exposed_module_ids, exec_mode, imported_module_params, + solo_can_output, ); Ok(Msg::CanonicalizedAndConstrained(can_and_con)) diff --git a/crates/compiler/load_internal/src/module.rs b/crates/compiler/load_internal/src/module.rs index e29c5385781..17be884c2a4 100644 --- a/crates/compiler/load_internal/src/module.rs +++ b/crates/compiler/load_internal/src/module.rs @@ -189,7 +189,7 @@ pub struct MonomorphizedModule<'a> { pub glue_layouts: GlueLayouts<'a>, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ParsedModule<'a> { pub module_id: ModuleId, pub module_path: PathBuf, @@ -237,11 +237,12 @@ pub struct ExposedToHost { pub getters: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ModuleTiming { pub read_roc_file: Duration, pub parse_header: Duration, pub parse_body: Duration, + pub canonicalize_solo: Duration, pub canonicalize: Duration, pub constrain: Duration, pub solve: Duration, @@ -261,6 +262,7 @@ impl ModuleTiming { read_roc_file: Duration::default(), parse_header: Duration::default(), parse_body: Duration::default(), + canonicalize_solo: Duration::default(), canonicalize: Duration::default(), constrain: Duration::default(), solve: Duration::default(), @@ -281,6 +283,7 @@ impl ModuleTiming { read_roc_file, parse_header, parse_body, + canonicalize_solo, canonicalize, constrain, solve, @@ -297,6 +300,7 @@ impl ModuleTiming { .checked_sub(*find_specializations)? .checked_sub(*solve)? .checked_sub(*constrain)? + .checked_sub(*canonicalize_solo)? .checked_sub(*canonicalize)? .checked_sub(*parse_body)? .checked_sub(*parse_header)? diff --git a/crates/compiler/load_internal/src/module_cache.rs b/crates/compiler/load_internal/src/module_cache.rs index 73e81f1dd86..0e6b4e3bdba 100644 --- a/crates/compiler/load_internal/src/module_cache.rs +++ b/crates/compiler/load_internal/src/module_cache.rs @@ -5,6 +5,7 @@ use crate::module::{ }; use roc_can::abilities::PendingAbilitiesStore; use roc_can::module::ModuleParams; +use roc_can_solo::module::SoloCanOutput; use roc_collections::{MutMap, MutSet, VecMap}; use roc_module::ident::ModuleName; use roc_module::symbol::{ModuleId, PQModuleName, Symbol}; @@ -26,6 +27,7 @@ pub(crate) struct ModuleCache<'a> { pub(crate) parsed: MutMap>, pub(crate) aliases: MutMap>, pub(crate) pending_abilities: MutMap, + pub(crate) solo_canonicalized: MutMap>, pub(crate) constrained: MutMap, pub(crate) module_params: MutMap, pub(crate) typechecked: MutMap>, @@ -45,6 +47,8 @@ pub(crate) struct ModuleCache<'a> { pub(crate) type_problems: MutMap>, pub(crate) sources: MutMap, + #[allow(dead_code)] + pub(crate) content_hashes: MutMap, } impl<'a> ModuleCache<'a> { @@ -65,6 +69,19 @@ impl<'a> ModuleCache<'a> { pub fn has_errors(&self) -> bool { self.has_can_errors() || self.has_type_errors() } + + #[allow(dead_code)] + pub fn add_module_content_hash(&mut self, module_id: ModuleId, contents: &str) -> String { + let hash = Self::hash_contents(contents); + self.content_hashes.insert(module_id, hash.clone()); + + hash + } + + #[allow(dead_code)] + pub fn hash_contents(contents: &str) -> String { + base64_url::encode(blake3::hash(contents.as_bytes()).as_bytes()) + } } impl Default for ModuleCache<'_> { @@ -101,6 +118,7 @@ impl Default for ModuleCache<'_> { parsed: Default::default(), aliases: Default::default(), pending_abilities: Default::default(), + solo_canonicalized: Default::default(), constrained: Default::default(), module_params: Default::default(), typechecked: Default::default(), @@ -116,6 +134,7 @@ impl Default for ModuleCache<'_> { can_problems: Default::default(), type_problems: Default::default(), sources: Default::default(), + content_hashes: Default::default(), } } } diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index d5a89e78fbd..02dcda1b14d 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -986,6 +986,10 @@ macro_rules! define_builtins { self.to_zero_indexed() < $total } + pub const fn first_after_builtins() -> Self { + ModuleId::from_zero_indexed($total) + } + $( pub const $module_const: ModuleId = ModuleId::from_zero_indexed($module_id); )+ diff --git a/crates/compiler/parse/src/header.rs b/crates/compiler/parse/src/header.rs index b885915929f..e664bc32dd1 100644 --- a/crates/compiler/parse/src/header.rs +++ b/crates/compiler/parse/src/header.rs @@ -927,7 +927,7 @@ impl<'a> HeaderType<'a> { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum HeaderType<'a> { App { provides: &'a [Loc>], 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 61a426dcb3f..1e12a614317 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 @@ -51,7 +51,7 @@ procedure List.72 (#Attr.2, #Attr.3, #Attr.4): let List.681 : List U8 = lowlevel ListSublist #Attr.2 #Attr.3 #Attr.4; ret List.681; -procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.80 (Bool.22, Bool.23, Bool.24, Bool.25, Bool.26): joinpoint List.695 List.566 List.567 List.568 List.569 List.570: let List.697 : Int1 = CallByName Num.22 List.569 List.570; if List.697 then @@ -75,8 +75,8 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen. let List.696 : [C U64, C U64] = TagId(1) List.567; ret List.696; in - inc #Derived_gen.0; - jump List.695 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.22; + jump List.695 Bool.22 Bool.23 Bool.24 Bool.25 Bool.26; procedure Num.22 (#Attr.2, #Attr.3): let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; diff --git a/crates/compiler/test_mono/generated/binary_tree_fbip.txt b/crates/compiler/test_mono/generated/binary_tree_fbip.txt index ac3783701f7..0622a229f3e 100644 --- a/crates/compiler/test_mono/generated/binary_tree_fbip.txt +++ b/crates/compiler/test_mono/generated/binary_tree_fbip.txt @@ -8,7 +8,7 @@ procedure Test.4 (Test.27): let Test.38 : I64 = CallByName Test.5 Test.27 Test.39 Test.40; ret Test.38; -procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): +procedure Test.5 (Bool.21, Bool.22, Bool.23): joinpoint Test.41 Test.29 Test.30 Test.31: let Test.51 : U8 = 0i64; let Test.52 : U8 = GetTagId Test.29; @@ -16,22 +16,22 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): if Test.53 then let Test.32 : [, C *self *self] = UnionAtIndex (Id 0) (Index 0) Test.29; let Test.33 : [, C *self *self] = UnionAtIndex (Id 0) (Index 1) Test.29; - joinpoint #Derived_gen.3 #Derived_gen.6: - let #Derived_gen.7 : [C [, C *self *self] *self, ] = lowlevel PtrCast #Derived_gen.6; - let Test.43 : [C [, C *self *self] *self, ] = Reuse #Derived_gen.7 UpdateModeId { id: 1 } TagId(1) Test.33 Test.30; + joinpoint Bool.24 Bool.27: + let Bool.28 : [C [, C *self *self] *self, ] = lowlevel PtrCast Bool.27; + let Test.43 : [C [, C *self *self] *self, ] = Reuse Bool.28 UpdateModeId { id: 1 } TagId(1) Test.33 Test.30; let Test.45 : I64 = 1i64; let Test.44 : I64 = CallByName Num.19 Test.31 Test.45; jump Test.41 Test.32 Test.43 Test.44; in - let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.29; - if #Derived_gen.4 then - jump #Derived_gen.3 Test.29; + let Bool.25 : Int1 = lowlevel RefCountIsUnique Test.29; + if Bool.25 then + jump Bool.24 Test.29; else inc Test.32; inc Test.33; decref Test.29; - let #Derived_gen.8 : [, C *self *self] = NullPointer; - jump #Derived_gen.3 #Derived_gen.8; + let Bool.29 : [, C *self *self] = NullPointer; + jump Bool.24 Bool.29; else let Test.48 : U8 = 1i64; let Test.49 : U8 = GetTagId Test.30; @@ -39,8 +39,8 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): if Test.50 then let Test.35 : [, C *self *self] = UnionAtIndex (Id 1) (Index 0) Test.30; let Test.36 : [C [, C *self *self] *self, ] = UnionAtIndex (Id 1) (Index 1) Test.30; - let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.30; - if #Derived_gen.5 then + let Bool.26 : Int1 = lowlevel RefCountIsUnique Test.30; + if Bool.26 then free Test.30; jump Test.41 Test.35 Test.36 Test.31; else @@ -51,7 +51,7 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): else ret Test.31; in - jump Test.41 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2; + jump Test.41 Bool.21 Bool.22 Bool.23; procedure Test.0 (): let Test.64 : [, C *self *self] = TagId(1) ; diff --git a/crates/compiler/test_mono/generated/call_function_in_empty_list.txt b/crates/compiler/test_mono/generated/call_function_in_empty_list.txt index 51eb3529413..e1b6c162224 100644 --- a/crates/compiler/test_mono/generated/call_function_in_empty_list.txt +++ b/crates/compiler/test_mono/generated/call_function_in_empty_list.txt @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25): joinpoint List.681 List.175 List.176 List.177 List.178 List.179: let List.683 : Int1 = CallByName Num.22 List.178 List.179; if List.683 then @@ -11,8 +11,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.0; - jump List.681 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.21; + jump List.681 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25; procedure List.18 (List.172, List.173, List.174): let List.679 : U64 = 0i64; diff --git a/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt b/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt index 11ac4c443df..a7edf0433a5 100644 --- a/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt +++ b/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25): joinpoint List.681 List.175 List.176 List.177 List.178 List.179: let List.683 : Int1 = CallByName Num.22 List.178 List.179; if List.683 then @@ -11,8 +11,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.0; - jump List.681 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.21; + jump List.681 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25; procedure List.18 (List.172, List.173, List.174): let List.679 : U64 = 0i64; diff --git a/crates/compiler/test_mono/generated/capture_void_layout_task.txt b/crates/compiler/test_mono/generated/capture_void_layout_task.txt index 58667468aec..571eaa1758c 100644 --- a/crates/compiler/test_mono/generated/capture_void_layout_task.txt +++ b/crates/compiler/test_mono/generated/capture_void_layout_task.txt @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_gen.17): +procedure List.101 (Bool.34, Bool.35, Bool.36, Bool.37, Bool.38): joinpoint List.678 List.175 List.176 List.177 List.178 List.179: let List.680 : Int1 = CallByName Num.22 List.178 List.179; if List.680 then @@ -11,8 +11,8 @@ procedure List.101 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_ dec List.175; ret List.176; in - inc #Derived_gen.13; - jump List.678 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17; + inc Bool.34; + jump List.678 Bool.34 Bool.35 Bool.36 Bool.37 Bool.38; procedure List.18 (List.172, List.173, List.174): let List.676 : U64 = 0i64; @@ -38,8 +38,8 @@ procedure Num.51 (#Attr.2, #Attr.3): procedure Test.10 (Test.69, #Attr.12): let Test.72 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12; - let #Derived_gen.18 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.18 then + let Bool.39 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.39 then free #Attr.12; ret Test.72; else @@ -53,7 +53,7 @@ procedure Test.10 (Test.69, #Attr.12): procedure Test.14 (Test.45, #Attr.12): let Test.55 : {{}, []} = UnionAtIndex (Id 1) (Index 1) #Attr.12; let Test.54 : [C {}, C *self {{}, []}] = UnionAtIndex (Id 1) (Index 0) #Attr.12; - joinpoint #Derived_gen.19: + joinpoint Bool.40: let Test.50 : {} = Struct {}; let Test.51 : U8 = GetTagId Test.54; joinpoint Test.52 Test.15: @@ -80,14 +80,14 @@ procedure Test.14 (Test.45, #Attr.12): jump Test.52 Test.53; in - let #Derived_gen.20 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.20 then + let Bool.41 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.41 then free #Attr.12; - jump #Derived_gen.19; + jump Bool.40; else inc Test.54; decref #Attr.12; - jump #Derived_gen.19; + jump Bool.40; procedure Test.20 (Test.21, Test.18): let Test.23 : [C {}, C []] = CallByName Test.32 Test.21 Test.18; 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 0ae2cd1543c..42bb6295dc4 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 @@ -8,7 +8,7 @@ procedure Test.2 (Test.6): let Test.24 : Int1 = lowlevel Eq Test.22 Test.23; if Test.24 then let Test.7 : [C List *self, C *self] = UnionAtIndex (Id 1) (Index 0) Test.6; - joinpoint #Derived_gen.1: + joinpoint Bool.23: let Test.8 : Str = CallByName Test.2 Test.7; let Test.18 : Int1 = CallByName Bool.1; if Test.18 then @@ -18,29 +18,29 @@ procedure Test.2 (Test.6): let Test.17 : Str = "foo"; ret Test.17; in - let #Derived_gen.2 : Int1 = lowlevel RefCountIsUnique Test.6; - if #Derived_gen.2 then + let Bool.24 : Int1 = lowlevel RefCountIsUnique Test.6; + if Bool.24 then free Test.6; - jump #Derived_gen.1; + jump Bool.23; else inc Test.7; decref Test.6; - jump #Derived_gen.1; + jump Bool.23; else let Test.9 : List [C List [C List *self, C *self], C [C List *self, C *self]] = UnionAtIndex (Id 0) (Index 0) Test.6; - joinpoint #Derived_gen.3: + joinpoint Bool.25: dec Test.9; let Test.21 : Str = "ValueNotExposed { module_name: ModuleName(IdentStr { string: \"Result\" }), ident: Ident(IdentStr { string: \"withDefault\" }), region: @662-680, exposed_values: ['is_err', 'on_err', 'map_ok', 'map_err', 'with_default', 'try', 'is_ok', 'map_both', 'map2', 'on_err!'] }"; Crash Test.21 in - let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.6; - if #Derived_gen.4 then + let Bool.26 : Int1 = lowlevel RefCountIsUnique Test.6; + if Bool.26 then free Test.6; - jump #Derived_gen.3; + jump Bool.25; else inc Test.9; decref Test.6; - jump #Derived_gen.3; + jump Bool.25; procedure Test.0 (): let Test.25 : List [C List [C List *self, C *self], C [C List *self, C *self]] = Array []; 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 d005809bac3..82b7ba1ee71 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 @@ -2,7 +2,7 @@ procedure Bool.2 (): let Bool.21 : Int1 = true; ret Bool.21; -procedure List.101 (#Derived_gen.7, #Derived_gen.8, #Derived_gen.9, #Derived_gen.10, #Derived_gen.11): +procedure List.101 (Bool.29, Bool.30, Bool.31, Bool.32, Bool.33): joinpoint List.678 List.175 List.176 List.177 List.178 List.179: let List.680 : Int1 = CallByName Num.22 List.178 List.179; if List.680 then @@ -15,8 +15,8 @@ procedure List.101 (#Derived_gen.7, #Derived_gen.8, #Derived_gen.9, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.7; - jump List.678 #Derived_gen.7 #Derived_gen.8 #Derived_gen.9 #Derived_gen.10 #Derived_gen.11; + inc Bool.29; + jump List.678 Bool.29 Bool.30 Bool.31 Bool.32 Bool.33; procedure List.18 (List.172, List.173, List.174): let List.676 : U64 = 0i64; @@ -47,11 +47,11 @@ procedure Str.3 (#Attr.2, #Attr.3): procedure Test.1 (Test.5): ret Test.5; -procedure Test.11 (#Derived_gen.5, #Derived_gen.6): +procedure Test.11 (Bool.27, Bool.28): joinpoint Test.27 Test.12 #Attr.12: let Test.34 : Int1 = UnionAtIndex (Id 2) (Index 1) #Attr.12; let Test.33 : [, C *self Int1, C *self Int1] = UnionAtIndex (Id 2) (Index 0) #Attr.12; - joinpoint #Derived_gen.14: + joinpoint Bool.36: joinpoint Test.31 Test.29: let Test.30 : U8 = GetTagId Test.33; switch Test.30: @@ -78,16 +78,16 @@ procedure Test.11 (#Derived_gen.5, #Derived_gen.6): jump Test.31 Test.32; in - let #Derived_gen.15 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.15 then + let Bool.37 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.37 then free #Attr.12; - jump #Derived_gen.14; + jump Bool.36; else inc Test.33; decref #Attr.12; - jump #Derived_gen.14; + jump Bool.36; in - jump Test.27 #Derived_gen.5 #Derived_gen.6; + jump Test.27 Bool.27 Bool.28; procedure Test.2 (Test.13): ret Test.13; @@ -118,7 +118,7 @@ procedure Test.6 (Test.7, Test.8, Test.5): procedure Test.9 (Test.10, #Attr.12): let Test.43 : Int1 = UnionAtIndex (Id 1) (Index 1) #Attr.12; let Test.42 : [, C *self Int1, C *self Int1] = UnionAtIndex (Id 1) (Index 0) #Attr.12; - joinpoint #Derived_gen.12: + joinpoint Bool.34: let Test.39 : U8 = GetTagId Test.42; joinpoint Test.40 Test.38: switch Test.43: @@ -146,14 +146,14 @@ procedure Test.9 (Test.10, #Attr.12): jump Test.40 Test.41; in - let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.13 then + let Bool.35 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.35 then free #Attr.12; - jump #Derived_gen.12; + jump Bool.34; else inc Test.42; decref #Attr.12; - jump #Derived_gen.12; + jump Bool.34; procedure Test.0 (): let Test.45 : Int1 = false; diff --git a/crates/compiler/test_mono/generated/dbg_expr.txt b/crates/compiler/test_mono/generated/dbg_expr.txt index 2d8c0f74809..fc8559b8835 100644 --- a/crates/compiler/test_mono/generated/dbg_expr.txt +++ b/crates/compiler/test_mono/generated/dbg_expr.txt @@ -47,10 +47,10 @@ procedure Str.3 (#Attr.2, #Attr.3): ret Str.246; procedure Test.0 (): - let Test.5 : I64 = 1i64; - let Test.2 : I64 = 2i64; - let Test.3 : Str = CallByName Inspect.33 Test.2; - dbg Test.3; - dec Test.3; - let Test.4 : I64 = CallByName Num.19 Test.5 Test.2; - ret Test.4; + let Test.4 : I64 = 1i64; + let Test.1 : I64 = 2i64; + let Test.2 : Str = CallByName Inspect.33 Test.1; + dbg Test.2; + dec Test.2; + let Test.3 : I64 = CallByName Num.19 Test.4 Test.1; + ret Test.3; diff --git a/crates/compiler/test_mono/generated/dbg_inside_string.txt b/crates/compiler/test_mono/generated/dbg_inside_string.txt index 5dd628551a9..ee50fe25bee 100644 --- a/crates/compiler/test_mono/generated/dbg_inside_string.txt +++ b/crates/compiler/test_mono/generated/dbg_inside_string.txt @@ -167,7 +167,7 @@ procedure Str.45 (Str.91, Str.92, Str.93): dec Str.344; ret Str.91; -procedure Str.56 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3): +procedure Str.56 (Bool.24, Bool.25, Bool.26, Bool.27): joinpoint Str.252 Str.96 Str.97 Str.98 Str.99: inc Str.97; let Str.253 : [C {}, C {Str, Str}] = CallByName Str.38 Str.97 Str.98; @@ -191,9 +191,9 @@ procedure Str.56 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3 dec Str.97; ret Str.257; in - inc #Derived_gen.3; - inc #Derived_gen.2; - jump Str.252 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3; + inc Bool.26; + inc Bool.27; + jump Str.252 Bool.24 Bool.25 Bool.26 Bool.27; procedure Str.57 (Str.121, Str.122): let Str.123 : U64 = CallByName Str.36 Str.121; @@ -203,7 +203,7 @@ procedure Str.57 (Str.121, Str.122): let Str.278 : [C , C U64] = CallByName Str.58 Str.121 Str.122 Str.279 Str.125; ret Str.278; -procedure Str.58 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7): +procedure Str.58 (Bool.28, Bool.29, Bool.30, Bool.31): joinpoint Str.280 Str.126 Str.127 Str.128 Str.129: let Str.282 : Int1 = CallByName Num.23 Str.128 Str.129; if Str.282 then @@ -223,9 +223,9 @@ procedure Str.58 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7 let Str.281 : [C , C U64] = TagId(0) ; ret Str.281; in - inc #Derived_gen.5; - inc #Derived_gen.4; - jump Str.280 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7; + inc Bool.29; + inc Bool.28; + jump Str.280 Bool.28 Bool.29 Bool.30 Bool.31; procedure Str.61 (Str.152, Str.153): let Str.311 : Int1 = CallByName Num.22 Str.152 Str.153; @@ -280,15 +280,15 @@ procedure Str.63 (Str.160): ret Str.291; procedure Test.0 (): - let Test.5 : Str = "Hello "; - let Test.2 : Str = "world"; - inc Test.2; - let Test.3 : Str = CallByName Inspect.33 Test.2; - dbg Test.3; - dec Test.3; - let Test.8 : Str = "!"; - let Test.6 : Str = CallByName Str.3 Test.2 Test.8; - dec Test.8; - let Test.4 : Str = CallByName Str.3 Test.5 Test.6; - dec Test.6; - ret Test.4; + let Test.4 : Str = "Hello "; + let Test.1 : Str = "world"; + inc Test.1; + let Test.2 : Str = CallByName Inspect.33 Test.1; + dbg Test.2; + dec Test.2; + let Test.7 : Str = "!"; + let Test.5 : Str = CallByName Str.3 Test.1 Test.7; + dec Test.7; + let Test.3 : Str = CallByName Str.3 Test.4 Test.5; + dec Test.5; + ret Test.3; diff --git a/crates/compiler/test_mono/generated/dbg_nested_expr.txt b/crates/compiler/test_mono/generated/dbg_nested_expr.txt index c3b19c61fcb..6f7e470d418 100644 --- a/crates/compiler/test_mono/generated/dbg_nested_expr.txt +++ b/crates/compiler/test_mono/generated/dbg_nested_expr.txt @@ -43,14 +43,14 @@ procedure Str.3 (#Attr.2, #Attr.3): ret Str.246; procedure Test.0 (): - let Test.6 : I64 = 1i64; - let Test.7 : Str = CallByName Inspect.33 Test.6; - dbg Test.7; - dec Test.7; - let Test.8 : Str = CallByName Inspect.33 Test.6; - dbg Test.8; - dec Test.8; - let Test.9 : Str = CallByName Inspect.33 Test.6; - dbg Test.9; - dec Test.9; - ret Test.6; + let Test.3 : I64 = 1i64; + let Test.4 : Str = CallByName Inspect.33 Test.3; + dbg Test.4; + dec Test.4; + let Test.5 : Str = CallByName Inspect.33 Test.3; + dbg Test.5; + dec Test.5; + let Test.6 : Str = CallByName Inspect.33 Test.3; + dbg Test.6; + dec Test.6; + ret Test.3; diff --git a/crates/compiler/test_mono/generated/dbg_str_followed_by_number.txt b/crates/compiler/test_mono/generated/dbg_str_followed_by_number.txt index 9c452c03c17..0f5a6235dc7 100644 --- a/crates/compiler/test_mono/generated/dbg_str_followed_by_number.txt +++ b/crates/compiler/test_mono/generated/dbg_str_followed_by_number.txt @@ -167,7 +167,7 @@ procedure Str.45 (Str.91, Str.92, Str.93): dec Str.342; ret Str.91; -procedure Str.56 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3): +procedure Str.56 (Bool.24, Bool.25, Bool.26, Bool.27): joinpoint Str.250 Str.96 Str.97 Str.98 Str.99: inc Str.97; let Str.251 : [C {}, C {Str, Str}] = CallByName Str.38 Str.97 Str.98; @@ -191,9 +191,9 @@ procedure Str.56 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3 dec Str.97; ret Str.255; in - inc #Derived_gen.3; - inc #Derived_gen.2; - jump Str.250 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3; + inc Bool.26; + inc Bool.27; + jump Str.250 Bool.24 Bool.25 Bool.26 Bool.27; procedure Str.57 (Str.121, Str.122): let Str.123 : U64 = CallByName Str.36 Str.121; @@ -203,7 +203,7 @@ procedure Str.57 (Str.121, Str.122): let Str.276 : [C , C U64] = CallByName Str.58 Str.121 Str.122 Str.277 Str.125; ret Str.276; -procedure Str.58 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7): +procedure Str.58 (Bool.28, Bool.29, Bool.30, Bool.31): joinpoint Str.278 Str.126 Str.127 Str.128 Str.129: let Str.280 : Int1 = CallByName Num.23 Str.128 Str.129; if Str.280 then @@ -223,9 +223,9 @@ procedure Str.58 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7 let Str.279 : [C , C U64] = TagId(0) ; ret Str.279; in - inc #Derived_gen.5; - inc #Derived_gen.4; - jump Str.278 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7; + inc Bool.29; + inc Bool.28; + jump Str.278 Bool.28 Bool.29 Bool.30 Bool.31; procedure Str.61 (Str.152, Str.153): let Str.309 : Int1 = CallByName Num.22 Str.152 Str.153; diff --git a/crates/compiler/test_mono/generated/dict.txt b/crates/compiler/test_mono/generated/dict.txt index e550ff18e64..2529f1d4f55 100644 --- a/crates/compiler/test_mono/generated/dict.txt +++ b/crates/compiler/test_mono/generated/dict.txt @@ -9,8 +9,8 @@ procedure Dict.1 (Dict.732): procedure Dict.4 (Dict.738): let Dict.163 : List {[], []} = StructAtIndex 1 Dict.738; - let #Derived_gen.0 : List {U32, U32} = StructAtIndex 0 Dict.738; - dec #Derived_gen.0; + let Bool.21 : List {U32, U32} = StructAtIndex 0 Dict.738; + dec Bool.21; let Dict.739 : U64 = CallByName List.6 Dict.163; dec Dict.163; ret Dict.739; diff --git a/crates/compiler/test_mono/generated/factorial.txt b/crates/compiler/test_mono/generated/factorial.txt index 35fceaa3128..e0084ad6f60 100644 --- a/crates/compiler/test_mono/generated/factorial.txt +++ b/crates/compiler/test_mono/generated/factorial.txt @@ -6,7 +6,7 @@ procedure Num.21 (#Attr.2, #Attr.3): let Num.283 : I64 = lowlevel NumMul #Attr.2 #Attr.3; ret Num.283; -procedure Test.1 (#Derived_gen.0, #Derived_gen.1): +procedure Test.1 (Bool.21, Bool.22): joinpoint Test.7 Test.2 Test.3: let Test.13 : I64 = 0i64; let Test.14 : Int1 = lowlevel Eq Test.13 Test.2; @@ -18,7 +18,7 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1): let Test.11 : I64 = CallByName Num.21 Test.2 Test.3; jump Test.7 Test.10 Test.11; in - jump Test.7 #Derived_gen.0 #Derived_gen.1; + jump Test.7 Bool.21 Bool.22; procedure Test.0 (): let Test.5 : I64 = 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 ff03b72b1be..003ee98b538 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 @@ -9,7 +9,7 @@ procedure Num.19 (#Attr.2, #Attr.3): procedure Test.3 (Test.4): ret Test.4; -procedure Test.0 (#Derived_gen.0): +procedure Test.0 (Bool.22): joinpoint Test.5 Test.1: joinpoint Test.10 Test.2: let Test.8 : I64 = 1i64; @@ -31,4 +31,4 @@ procedure Test.0 (#Derived_gen.0): let Test.9 : Int1 = true; jump Test.10 Test.9; in - jump Test.5 #Derived_gen.0; + jump Test.5 Bool.22; 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 dc3a6260ea8..9575fe4970a 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 @@ -34,7 +34,7 @@ procedure Test.8 (Test.9): let Test.23 : I64 = CallByName Num.19 Test.9 Test.24; ret Test.23; -procedure Test.0 (#Derived_gen.0): +procedure Test.0 (Bool.21): joinpoint Test.11 Test.1: let Test.25 : I64 = 1i64; let Test.13 : I64 = CallByName Num.19 Test.1 Test.25; @@ -57,4 +57,4 @@ procedure Test.0 (#Derived_gen.0): ret Test.12; in - jump Test.11 #Derived_gen.0; + jump Test.11 Bool.21; 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 30a62bd1bcf..df12cde15ef 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 @@ -17,7 +17,7 @@ procedure Test.4 (Test.5, #Attr.12): let Test.16 : I64 = CallByName Num.19 Test.5 Test.17; ret Test.16; -procedure Test.0 (#Derived_gen.0): +procedure Test.0 (Bool.21): joinpoint Test.7 Test.1: let Test.21 : I64 = 1i64; let Test.9 : I64 = CallByName Num.19 Test.1 Test.21; @@ -33,4 +33,4 @@ procedure Test.0 (#Derived_gen.0): ret Test.8; in - jump Test.7 #Derived_gen.0; + jump Test.7 Bool.21; diff --git a/crates/compiler/test_mono/generated/inspect_derived_dict.txt b/crates/compiler/test_mono/generated/inspect_derived_dict.txt index 67f7d62bb50..ad419202e81 100644 --- a/crates/compiler/test_mono/generated/inspect_derived_dict.txt +++ b/crates/compiler/test_mono/generated/inspect_derived_dict.txt @@ -49,32 +49,32 @@ procedure Dict.1 (Dict.732): procedure Dict.10 (Dict.733, Dict.186, Dict.187): let Dict.185 : List {Str, I64} = StructAtIndex 1 Dict.733; - let #Derived_gen.70 : List {U32, U32} = StructAtIndex 0 Dict.733; - dec #Derived_gen.70; - let Dict.1110 : {Str, Int1} = CallByName List.18 Dict.185 Dict.186 Dict.187; + let #Derived_gen.71 : List {U32, U32} = StructAtIndex 0 Dict.733; + dec #Derived_gen.71; + let Dict.909 : {Str, Int1} = CallByName List.18 Dict.185 Dict.186 Dict.187; dec Dict.185; - ret Dict.1110; + ret Dict.909; procedure Dict.100 (Dict.546, Dict.547, Dict.548): - let Dict.1063 : U8 = CallByName Dict.22 Dict.546 Dict.547; - let Dict.549 : U64 = CallByName Num.133 Dict.1063; - let Dict.1062 : U8 = 1i64; - let Dict.1061 : U64 = CallByName Num.74 Dict.548 Dict.1062; - let Dict.1060 : U64 = CallByName Num.51 Dict.1061 Dict.547; - let Dict.1059 : U8 = CallByName Dict.22 Dict.546 Dict.1060; - let Dict.550 : U64 = CallByName Num.133 Dict.1059; - let Dict.1058 : U64 = 1i64; - let Dict.1057 : U64 = CallByName Num.75 Dict.548 Dict.1058; - let Dict.1056 : U64 = CallByName Num.51 Dict.1057 Dict.547; - let Dict.1055 : U8 = CallByName Dict.22 Dict.546 Dict.1056; - let Dict.551 : U64 = CallByName Num.133 Dict.1055; - let Dict.1054 : U8 = 16i64; - let Dict.1051 : U64 = CallByName Num.72 Dict.549 Dict.1054; - let Dict.1053 : U8 = 8i64; - let Dict.1052 : U64 = CallByName Num.72 Dict.550 Dict.1053; - let Dict.552 : U64 = CallByName Num.71 Dict.1051 Dict.1052; - let Dict.1050 : U64 = CallByName Num.71 Dict.552 Dict.551; - ret Dict.1050; + let Dict.1076 : U8 = CallByName Dict.22 Dict.546 Dict.547; + let Dict.549 : U64 = CallByName Num.133 Dict.1076; + let Dict.1075 : U8 = 1i64; + let Dict.1074 : U64 = CallByName Num.74 Dict.548 Dict.1075; + let Dict.1073 : U64 = CallByName Num.51 Dict.1074 Dict.547; + let Dict.1072 : U8 = CallByName Dict.22 Dict.546 Dict.1073; + let Dict.550 : U64 = CallByName Num.133 Dict.1072; + let Dict.1071 : U64 = 1i64; + let Dict.1070 : U64 = CallByName Num.75 Dict.548 Dict.1071; + let Dict.1069 : U64 = CallByName Num.51 Dict.1070 Dict.547; + let Dict.1068 : U8 = CallByName Dict.22 Dict.546 Dict.1069; + let Dict.551 : U64 = CallByName Num.133 Dict.1068; + let Dict.1067 : U8 = 16i64; + let Dict.1064 : U64 = CallByName Num.72 Dict.549 Dict.1067; + let Dict.1066 : U8 = 8i64; + let Dict.1065 : U64 = CallByName Num.72 Dict.550 Dict.1066; + let Dict.552 : U64 = CallByName Num.71 Dict.1064 Dict.1065; + let Dict.1063 : U64 = CallByName Num.71 Dict.552 Dict.551; + ret Dict.1063; procedure Dict.12 (Dict.158): let Dict.892 : {} = Struct {}; @@ -84,12 +84,12 @@ procedure Dict.12 (Dict.158): ret Dict.739; procedure Dict.127 (Dict.128, Dict.126): - let Dict.1107 : {} = Struct {}; - let Dict.1108 : {} = Struct {}; - let Dict.1109 : {} = Struct {}; - let Dict.1106 : {{List {U32, U32}, List {Str, I64}, U64, Float32, U8}, {}, {}, {}} = CallByName Inspect.42 Dict.126 Dict.1107 Dict.1108 Dict.1109; - let Dict.1105 : Str = CallByName Inspect.31 Dict.1106 Dict.128; - ret Dict.1105; + let Dict.906 : {} = Struct {}; + let Dict.907 : {} = Struct {}; + let Dict.908 : {} = Struct {}; + let Dict.905 : {{List {U32, U32}, List {Str, I64}, U64, Float32, U8}, {}, {}, {}} = CallByName Inspect.42 Dict.126 Dict.906 Dict.907 Dict.908; + let Dict.904 : Str = CallByName Inspect.31 Dict.905 Dict.128; + ret Dict.904; procedure Dict.159 (Dict.160, Dict.742): let Dict.161 : Str = StructAtIndex 0 Dict.742; @@ -97,11 +97,11 @@ procedure Dict.159 (Dict.160, Dict.742): let Dict.743 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = CallByName Dict.8 Dict.160 Dict.161 Dict.162; ret Dict.743; -procedure Dict.188 (Dict.189, Dict.1112, Dict.187): - let Dict.190 : Str = StructAtIndex 0 Dict.1112; - let Dict.191 : I64 = StructAtIndex 1 Dict.1112; - let Dict.1114 : {Str, Int1} = CallByName Inspect.189 Dict.189 Dict.190 Dict.191 Dict.187; - ret Dict.1114; +procedure Dict.188 (Dict.189, Dict.911, Dict.187): + let Dict.190 : Str = StructAtIndex 0 Dict.911; + let Dict.191 : I64 = StructAtIndex 1 Dict.911; + let Dict.913 : {Str, Int1} = CallByName Inspect.189 Dict.189 Dict.190 Dict.191 Dict.187; + ret Dict.913; procedure Dict.20 (Dict.729): let Dict.155 : U64 = StructAtIndex 2 Dict.729; @@ -120,8 +120,8 @@ procedure Dict.22 (#Attr.2, #Attr.3): ret Dict.790; procedure Dict.22 (#Attr.2, #Attr.3): - let Dict.953 : U8 = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret Dict.953; + let Dict.966 : U8 = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret Dict.966; procedure Dict.23 (#Attr.2): let Dict.826 : U64 = lowlevel DictPseudoSeed #Attr.2; @@ -146,8 +146,8 @@ procedure Dict.407 (Dict.408, Dict.849, Dict.410, Dict.406): ret Dict.851; procedure Dict.43 (Dict.126): - let Dict.1102 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = CallByName Inspect.30 Dict.126; - ret Dict.1102; + let Dict.901 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = CallByName Inspect.30 Dict.126; + ret Dict.901; procedure Dict.45 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7, #Derived_gen.8): joinpoint Dict.745 Dict.228 Dict.229 Dict.230 Dict.231 Dict.232 Dict.233 Dict.234 Dict.235 Dict.236: @@ -243,8 +243,8 @@ procedure Dict.66 (Dict.728): let Dict.386 : U64 = StructAtIndex 2 Dict.728; let Dict.387 : Float32 = StructAtIndex 3 Dict.728; let Dict.388 : U8 = StructAtIndex 4 Dict.728; - let #Derived_gen.71 : List {U32, U32} = StructAtIndex 0 Dict.728; - dec #Derived_gen.71; + let #Derived_gen.70 : List {U32, U32} = StructAtIndex 0 Dict.728; + dec #Derived_gen.70; let Dict.886 : U64 = CallByName Dict.54; let Dict.845 : Int1 = CallByName Bool.5 Dict.386 Dict.886; if Dict.845 then @@ -427,21 +427,21 @@ procedure Dict.81 (Dict.717, Dict.718): let Dict.443 : U64 = StructAtIndex 3 Dict.718; let Dict.439 : U64 = StructAtIndex 0 Dict.717; let Dict.440 : U64 = StructAtIndex 1 Dict.717; - let Dict.922 : U64 = CallByName Dict.93; - let Dict.920 : U64 = CallByName Num.70 Dict.441 Dict.922; - let Dict.921 : U64 = CallByName Num.70 Dict.442 Dict.443; - let Dict.445 : {U64, U64} = CallByName Dict.97 Dict.920 Dict.921; - let Dict.917 : U64 = StructAtIndex 0 Dict.445; - let Dict.918 : U64 = CallByName Dict.92; - let Dict.916 : U64 = CallByName Num.70 Dict.917 Dict.918; - let Dict.446 : U64 = CallByName Num.70 Dict.916 Dict.444; - let Dict.913 : U64 = StructAtIndex 1 Dict.445; - let Dict.914 : U64 = CallByName Dict.93; - let Dict.447 : U64 = CallByName Num.70 Dict.913 Dict.914; + let Dict.935 : U64 = CallByName Dict.93; + let Dict.933 : U64 = CallByName Num.70 Dict.441 Dict.935; + let Dict.934 : U64 = CallByName Num.70 Dict.442 Dict.443; + let Dict.445 : {U64, U64} = CallByName Dict.97 Dict.933 Dict.934; + let Dict.930 : U64 = StructAtIndex 0 Dict.445; + let Dict.931 : U64 = CallByName Dict.92; + let Dict.929 : U64 = CallByName Num.70 Dict.930 Dict.931; + let Dict.446 : U64 = CallByName Num.70 Dict.929 Dict.444; + let Dict.926 : U64 = StructAtIndex 1 Dict.445; + let Dict.927 : U64 = CallByName Dict.93; + let Dict.447 : U64 = CallByName Num.70 Dict.926 Dict.927; let Dict.448 : U64 = CallByName Dict.96 Dict.446 Dict.447; - let Dict.905 : U64 = CallByName Dict.96 Dict.440 Dict.448; - let Dict.904 : {U64, U64} = Struct {Dict.439, Dict.905}; - ret Dict.904; + let Dict.918 : U64 = CallByName Dict.96 Dict.440 Dict.448; + let Dict.917 : {U64, U64} = Struct {Dict.439, Dict.918}; + ret Dict.917; procedure Dict.82 (Dict.449): let Dict.821 : U64 = CallByName Dict.92; @@ -459,284 +459,284 @@ procedure Dict.89 (Dict.711, Dict.489): let Dict.487 : U64 = StructAtIndex 0 Dict.711; let Dict.488 : U64 = StructAtIndex 1 Dict.711; let Dict.490 : U64 = CallByName List.6 Dict.489; - joinpoint Dict.927 Dict.491: - let Dict.902 : {U64, U64} = Struct {Dict.487, Dict.488}; - let Dict.923 : U64 = StructAtIndex 0 Dict.491; - let Dict.924 : U64 = StructAtIndex 1 Dict.491; - let Dict.925 : U64 = StructAtIndex 2 Dict.491; - let Dict.903 : {U64, U64, U64, U64} = Struct {Dict.923, Dict.924, Dict.490, Dict.925}; - let Dict.901 : {U64, U64} = CallByName Dict.81 Dict.902 Dict.903; - ret Dict.901; + joinpoint Dict.940 Dict.491: + let Dict.915 : {U64, U64} = Struct {Dict.487, Dict.488}; + let Dict.936 : U64 = StructAtIndex 0 Dict.491; + let Dict.937 : U64 = StructAtIndex 1 Dict.491; + let Dict.938 : U64 = StructAtIndex 2 Dict.491; + let Dict.916 : {U64, U64, U64, U64} = Struct {Dict.936, Dict.937, Dict.490, Dict.938}; + let Dict.914 : {U64, U64} = CallByName Dict.81 Dict.915 Dict.916; + ret Dict.914; in - let Dict.1101 : U64 = 16i64; - let Dict.1041 : Int1 = CallByName Num.23 Dict.490 Dict.1101; - if Dict.1041 then - joinpoint Dict.1043 Dict.926: - jump Dict.927 Dict.926; + let Dict.1114 : U64 = 16i64; + let Dict.1054 : Int1 = CallByName Num.23 Dict.490 Dict.1114; + if Dict.1054 then + joinpoint Dict.1056 Dict.939: + jump Dict.940 Dict.939; in - let Dict.1100 : U64 = 4i64; - let Dict.1065 : Int1 = CallByName Num.25 Dict.490 Dict.1100; - if Dict.1065 then - let Dict.1099 : U8 = 3i64; - let Dict.1097 : U64 = CallByName Num.74 Dict.490 Dict.1099; - let Dict.1098 : U8 = 2i64; - let Dict.492 : U64 = CallByName Num.72 Dict.1097 Dict.1098; - let Dict.1096 : U64 = 0i64; - let Dict.1094 : U64 = CallByName Dict.99 Dict.489 Dict.1096; - let Dict.1095 : U8 = 32i64; - let Dict.1092 : U64 = CallByName Num.72 Dict.1094 Dict.1095; - let Dict.1093 : U64 = CallByName Dict.99 Dict.489 Dict.492; - let Dict.493 : U64 = CallByName Num.71 Dict.1092 Dict.1093; - let Dict.1091 : U64 = 4i64; - let Dict.1090 : U64 = CallByName Num.75 Dict.490 Dict.1091; - let Dict.1088 : U64 = CallByName Dict.99 Dict.489 Dict.1090; - let Dict.1089 : U8 = 32i64; - let Dict.1066 : U64 = CallByName Num.72 Dict.1088 Dict.1089; - let Dict.1087 : U64 = 4i64; - let Dict.1086 : U64 = CallByName Num.75 Dict.490 Dict.1087; - let Dict.1068 : U64 = CallByName Num.75 Dict.1086 Dict.492; - let Dict.1067 : U64 = CallByName Dict.99 Dict.489 Dict.1068; - let Dict.494 : U64 = CallByName Num.71 Dict.1066 Dict.1067; - let Dict.1042 : {U64, U64, U64} = Struct {Dict.493, Dict.494, Dict.487}; - jump Dict.1043 Dict.1042; + let Dict.1113 : U64 = 4i64; + let Dict.1078 : Int1 = CallByName Num.25 Dict.490 Dict.1113; + if Dict.1078 then + let Dict.1112 : U8 = 3i64; + let Dict.1110 : U64 = CallByName Num.74 Dict.490 Dict.1112; + let Dict.1111 : U8 = 2i64; + let Dict.492 : U64 = CallByName Num.72 Dict.1110 Dict.1111; + let Dict.1109 : U64 = 0i64; + let Dict.1107 : U64 = CallByName Dict.99 Dict.489 Dict.1109; + let Dict.1108 : U8 = 32i64; + let Dict.1105 : U64 = CallByName Num.72 Dict.1107 Dict.1108; + let Dict.1106 : U64 = CallByName Dict.99 Dict.489 Dict.492; + let Dict.493 : U64 = CallByName Num.71 Dict.1105 Dict.1106; + let Dict.1104 : U64 = 4i64; + let Dict.1103 : U64 = CallByName Num.75 Dict.490 Dict.1104; + let Dict.1101 : U64 = CallByName Dict.99 Dict.489 Dict.1103; + let Dict.1102 : U8 = 32i64; + let Dict.1079 : U64 = CallByName Num.72 Dict.1101 Dict.1102; + let Dict.1100 : U64 = 4i64; + let Dict.1099 : U64 = CallByName Num.75 Dict.490 Dict.1100; + let Dict.1081 : U64 = CallByName Num.75 Dict.1099 Dict.492; + let Dict.1080 : U64 = CallByName Dict.99 Dict.489 Dict.1081; + let Dict.494 : U64 = CallByName Num.71 Dict.1079 Dict.1080; + let Dict.1055 : {U64, U64, U64} = Struct {Dict.493, Dict.494, Dict.487}; + jump Dict.1056 Dict.1055; else - let Dict.1064 : U64 = 0i64; - let Dict.1046 : Int1 = CallByName Num.24 Dict.490 Dict.1064; - if Dict.1046 then - let Dict.1049 : U64 = 0i64; - let Dict.1047 : U64 = CallByName Dict.100 Dict.489 Dict.1049 Dict.490; - let Dict.1048 : U64 = 0i64; - let Dict.1042 : {U64, U64, U64} = Struct {Dict.1047, Dict.1048, Dict.487}; - jump Dict.1043 Dict.1042; + let Dict.1077 : U64 = 0i64; + let Dict.1059 : Int1 = CallByName Num.24 Dict.490 Dict.1077; + if Dict.1059 then + let Dict.1062 : U64 = 0i64; + let Dict.1060 : U64 = CallByName Dict.100 Dict.489 Dict.1062 Dict.490; + let Dict.1061 : U64 = 0i64; + let Dict.1055 : {U64, U64, U64} = Struct {Dict.1060, Dict.1061, Dict.487}; + jump Dict.1056 Dict.1055; else - let Dict.1044 : U64 = 0i64; - let Dict.1045 : U64 = 0i64; - let Dict.1042 : {U64, U64, U64} = Struct {Dict.1044, Dict.1045, Dict.487}; - jump Dict.1043 Dict.1042; + let Dict.1057 : U64 = 0i64; + let Dict.1058 : U64 = 0i64; + let Dict.1055 : {U64, U64, U64} = Struct {Dict.1057, Dict.1058, Dict.487}; + jump Dict.1056 Dict.1055; else - let Dict.1040 : U64 = 48i64; - let Dict.1038 : Int1 = CallByName Num.23 Dict.490 Dict.1040; - if Dict.1038 then - let Dict.1039 : U64 = 0i64; - let Dict.926 : {U64, U64, U64} = CallByName Dict.91 Dict.487 Dict.489 Dict.1039 Dict.490; - jump Dict.927 Dict.926; + let Dict.1053 : U64 = 48i64; + let Dict.1051 : Int1 = CallByName Num.23 Dict.490 Dict.1053; + if Dict.1051 then + let Dict.1052 : U64 = 0i64; + let Dict.939 : {U64, U64, U64} = CallByName Dict.91 Dict.487 Dict.489 Dict.1052 Dict.490; + jump Dict.940 Dict.939; else - let Dict.928 : U64 = 0i64; - let Dict.926 : {U64, U64, U64} = CallByName Dict.90 Dict.487 Dict.487 Dict.487 Dict.489 Dict.928 Dict.490; - jump Dict.927 Dict.926; + let Dict.941 : U64 = 0i64; + let Dict.939 : {U64, U64, U64} = CallByName Dict.90 Dict.487 Dict.487 Dict.487 Dict.489 Dict.941 Dict.490; + jump Dict.940 Dict.939; procedure Dict.90 (#Derived_gen.24, #Derived_gen.25, #Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_gen.29): - joinpoint Dict.929 Dict.495 Dict.496 Dict.497 Dict.498 Dict.499 Dict.500: - let Dict.1036 : U64 = CallByName Dict.98 Dict.498 Dict.499; - let Dict.1037 : U64 = CallByName Dict.93; - let Dict.1031 : U64 = CallByName Num.70 Dict.1036 Dict.1037; - let Dict.1035 : U64 = 8i64; - let Dict.1034 : U64 = CallByName Num.51 Dict.499 Dict.1035; - let Dict.1033 : U64 = CallByName Dict.98 Dict.498 Dict.1034; - let Dict.1032 : U64 = CallByName Num.70 Dict.1033 Dict.495; - let Dict.501 : U64 = CallByName Dict.96 Dict.1031 Dict.1032; - let Dict.1030 : U64 = 16i64; - let Dict.1029 : U64 = CallByName Num.51 Dict.499 Dict.1030; - let Dict.1026 : U64 = CallByName Dict.98 Dict.498 Dict.1029; - let Dict.1027 : U64 = CallByName Dict.94; - let Dict.1021 : U64 = CallByName Num.70 Dict.1026 Dict.1027; - let Dict.1025 : U64 = 24i64; - let Dict.1024 : U64 = CallByName Num.51 Dict.499 Dict.1025; - let Dict.1023 : U64 = CallByName Dict.98 Dict.498 Dict.1024; - let Dict.1022 : U64 = CallByName Num.70 Dict.1023 Dict.496; - let Dict.502 : U64 = CallByName Dict.96 Dict.1021 Dict.1022; - let Dict.1020 : U64 = 32i64; - let Dict.1019 : U64 = CallByName Num.51 Dict.499 Dict.1020; - let Dict.1016 : U64 = CallByName Dict.98 Dict.498 Dict.1019; - let Dict.1017 : U64 = CallByName Dict.95; - let Dict.1011 : U64 = CallByName Num.70 Dict.1016 Dict.1017; - let Dict.1015 : U64 = 40i64; - let Dict.1014 : U64 = CallByName Num.51 Dict.499 Dict.1015; - let Dict.1013 : U64 = CallByName Dict.98 Dict.498 Dict.1014; - let Dict.1012 : U64 = CallByName Num.70 Dict.1013 Dict.497; - let Dict.503 : U64 = CallByName Dict.96 Dict.1011 Dict.1012; - let Dict.1010 : U64 = 48i64; - let Dict.504 : U64 = CallByName Num.75 Dict.500 Dict.1010; - let Dict.1009 : U64 = 48i64; - let Dict.505 : U64 = CallByName Num.51 Dict.499 Dict.1009; - let Dict.1008 : U64 = 48i64; - let Dict.1006 : Int1 = CallByName Num.24 Dict.504 Dict.1008; - if Dict.1006 then - jump Dict.929 Dict.501 Dict.502 Dict.503 Dict.498 Dict.505 Dict.504; + joinpoint Dict.942 Dict.495 Dict.496 Dict.497 Dict.498 Dict.499 Dict.500: + let Dict.1049 : U64 = CallByName Dict.98 Dict.498 Dict.499; + let Dict.1050 : U64 = CallByName Dict.93; + let Dict.1044 : U64 = CallByName Num.70 Dict.1049 Dict.1050; + let Dict.1048 : U64 = 8i64; + let Dict.1047 : U64 = CallByName Num.51 Dict.499 Dict.1048; + let Dict.1046 : U64 = CallByName Dict.98 Dict.498 Dict.1047; + let Dict.1045 : U64 = CallByName Num.70 Dict.1046 Dict.495; + let Dict.501 : U64 = CallByName Dict.96 Dict.1044 Dict.1045; + let Dict.1043 : U64 = 16i64; + let Dict.1042 : U64 = CallByName Num.51 Dict.499 Dict.1043; + let Dict.1039 : U64 = CallByName Dict.98 Dict.498 Dict.1042; + let Dict.1040 : U64 = CallByName Dict.94; + let Dict.1034 : U64 = CallByName Num.70 Dict.1039 Dict.1040; + let Dict.1038 : U64 = 24i64; + let Dict.1037 : U64 = CallByName Num.51 Dict.499 Dict.1038; + let Dict.1036 : U64 = CallByName Dict.98 Dict.498 Dict.1037; + let Dict.1035 : U64 = CallByName Num.70 Dict.1036 Dict.496; + let Dict.502 : U64 = CallByName Dict.96 Dict.1034 Dict.1035; + let Dict.1033 : U64 = 32i64; + let Dict.1032 : U64 = CallByName Num.51 Dict.499 Dict.1033; + let Dict.1029 : U64 = CallByName Dict.98 Dict.498 Dict.1032; + let Dict.1030 : U64 = CallByName Dict.95; + let Dict.1024 : U64 = CallByName Num.70 Dict.1029 Dict.1030; + let Dict.1028 : U64 = 40i64; + let Dict.1027 : U64 = CallByName Num.51 Dict.499 Dict.1028; + let Dict.1026 : U64 = CallByName Dict.98 Dict.498 Dict.1027; + let Dict.1025 : U64 = CallByName Num.70 Dict.1026 Dict.497; + let Dict.503 : U64 = CallByName Dict.96 Dict.1024 Dict.1025; + let Dict.1023 : U64 = 48i64; + let Dict.504 : U64 = CallByName Num.75 Dict.500 Dict.1023; + let Dict.1022 : U64 = 48i64; + let Dict.505 : U64 = CallByName Num.51 Dict.499 Dict.1022; + let Dict.1021 : U64 = 48i64; + let Dict.1019 : Int1 = CallByName Num.24 Dict.504 Dict.1021; + if Dict.1019 then + jump Dict.942 Dict.501 Dict.502 Dict.503 Dict.498 Dict.505 Dict.504; else - let Dict.1005 : U64 = 16i64; - let Dict.980 : Int1 = CallByName Num.24 Dict.504 Dict.1005; - if Dict.980 then - let Dict.1004 : U64 = CallByName Num.70 Dict.502 Dict.501; - let Dict.506 : U64 = CallByName Num.70 Dict.503 Dict.1004; - let Dict.981 : {U64, U64, U64} = CallByName Dict.91 Dict.506 Dict.498 Dict.505 Dict.504; + let Dict.1018 : U64 = 16i64; + let Dict.993 : Int1 = CallByName Num.24 Dict.504 Dict.1018; + if Dict.993 then + let Dict.1017 : U64 = CallByName Num.70 Dict.502 Dict.501; + let Dict.506 : U64 = CallByName Num.70 Dict.503 Dict.1017; + let Dict.994 : {U64, U64, U64} = CallByName Dict.91 Dict.506 Dict.498 Dict.505 Dict.504; dec Dict.498; - ret Dict.981; + ret Dict.994; else - let Dict.979 : U64 = CallByName Num.70 Dict.502 Dict.501; - let Dict.507 : U64 = CallByName Num.70 Dict.503 Dict.979; - let Dict.978 : U64 = 16i64; - let Dict.977 : U64 = CallByName Num.75 Dict.504 Dict.978; - let Dict.976 : U64 = CallByName Num.51 Dict.977 Dict.505; - let Dict.931 : U64 = CallByName Dict.98 Dict.498 Dict.976; - let Dict.975 : U64 = 8i64; - let Dict.974 : U64 = CallByName Num.75 Dict.504 Dict.975; - let Dict.933 : U64 = CallByName Num.51 Dict.974 Dict.505; - let Dict.932 : U64 = CallByName Dict.98 Dict.498 Dict.933; + let Dict.992 : U64 = CallByName Num.70 Dict.502 Dict.501; + let Dict.507 : U64 = CallByName Num.70 Dict.503 Dict.992; + let Dict.991 : U64 = 16i64; + let Dict.990 : U64 = CallByName Num.75 Dict.504 Dict.991; + let Dict.989 : U64 = CallByName Num.51 Dict.990 Dict.505; + let Dict.944 : U64 = CallByName Dict.98 Dict.498 Dict.989; + let Dict.988 : U64 = 8i64; + let Dict.987 : U64 = CallByName Num.75 Dict.504 Dict.988; + let Dict.946 : U64 = CallByName Num.51 Dict.987 Dict.505; + let Dict.945 : U64 = CallByName Dict.98 Dict.498 Dict.946; dec Dict.498; - let Dict.930 : {U64, U64, U64} = Struct {Dict.931, Dict.932, Dict.507}; - ret Dict.930; + let Dict.943 : {U64, U64, U64} = Struct {Dict.944, Dict.945, Dict.507}; + ret Dict.943; in inc #Derived_gen.27; - jump Dict.929 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28 #Derived_gen.29; + jump Dict.942 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28 #Derived_gen.29; procedure Dict.91 (#Derived_gen.30, #Derived_gen.31, #Derived_gen.32, #Derived_gen.33): - joinpoint Dict.982 Dict.508 Dict.509 Dict.510 Dict.511: - let Dict.1002 : U64 = CallByName Dict.98 Dict.509 Dict.510; - let Dict.1003 : U64 = CallByName Dict.93; - let Dict.997 : U64 = CallByName Num.70 Dict.1002 Dict.1003; - let Dict.1001 : U64 = 8i64; - let Dict.1000 : U64 = CallByName Num.51 Dict.510 Dict.1001; - let Dict.999 : U64 = CallByName Dict.98 Dict.509 Dict.1000; - let Dict.998 : U64 = CallByName Num.70 Dict.999 Dict.508; - let Dict.512 : U64 = CallByName Dict.96 Dict.997 Dict.998; - let Dict.996 : U64 = 16i64; - let Dict.513 : U64 = CallByName Num.75 Dict.511 Dict.996; - let Dict.995 : U64 = 16i64; - let Dict.514 : U64 = CallByName Num.51 Dict.510 Dict.995; - let Dict.994 : U64 = 16i64; - let Dict.984 : Int1 = CallByName Num.23 Dict.513 Dict.994; - if Dict.984 then - let Dict.993 : U64 = 16i64; - let Dict.992 : U64 = CallByName Num.75 Dict.513 Dict.993; - let Dict.991 : U64 = CallByName Num.51 Dict.992 Dict.514; - let Dict.986 : U64 = CallByName Dict.98 Dict.509 Dict.991; - let Dict.990 : U64 = 8i64; - let Dict.989 : U64 = CallByName Num.75 Dict.513 Dict.990; - let Dict.988 : U64 = CallByName Num.51 Dict.989 Dict.514; - let Dict.987 : U64 = CallByName Dict.98 Dict.509 Dict.988; + joinpoint Dict.995 Dict.508 Dict.509 Dict.510 Dict.511: + let Dict.1015 : U64 = CallByName Dict.98 Dict.509 Dict.510; + let Dict.1016 : U64 = CallByName Dict.93; + let Dict.1010 : U64 = CallByName Num.70 Dict.1015 Dict.1016; + let Dict.1014 : U64 = 8i64; + let Dict.1013 : U64 = CallByName Num.51 Dict.510 Dict.1014; + let Dict.1012 : U64 = CallByName Dict.98 Dict.509 Dict.1013; + let Dict.1011 : U64 = CallByName Num.70 Dict.1012 Dict.508; + let Dict.512 : U64 = CallByName Dict.96 Dict.1010 Dict.1011; + let Dict.1009 : U64 = 16i64; + let Dict.513 : U64 = CallByName Num.75 Dict.511 Dict.1009; + let Dict.1008 : U64 = 16i64; + let Dict.514 : U64 = CallByName Num.51 Dict.510 Dict.1008; + let Dict.1007 : U64 = 16i64; + let Dict.997 : Int1 = CallByName Num.23 Dict.513 Dict.1007; + if Dict.997 then + let Dict.1006 : U64 = 16i64; + let Dict.1005 : U64 = CallByName Num.75 Dict.513 Dict.1006; + let Dict.1004 : U64 = CallByName Num.51 Dict.1005 Dict.514; + let Dict.999 : U64 = CallByName Dict.98 Dict.509 Dict.1004; + let Dict.1003 : U64 = 8i64; + let Dict.1002 : U64 = CallByName Num.75 Dict.513 Dict.1003; + let Dict.1001 : U64 = CallByName Num.51 Dict.1002 Dict.514; + let Dict.1000 : U64 = CallByName Dict.98 Dict.509 Dict.1001; dec Dict.509; - let Dict.985 : {U64, U64, U64} = Struct {Dict.986, Dict.987, Dict.512}; - ret Dict.985; + let Dict.998 : {U64, U64, U64} = Struct {Dict.999, Dict.1000, Dict.512}; + ret Dict.998; else - jump Dict.982 Dict.512 Dict.509 Dict.514 Dict.513; + jump Dict.995 Dict.512 Dict.509 Dict.514 Dict.513; in inc #Derived_gen.31; - jump Dict.982 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33; + jump Dict.995 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33; procedure Dict.92 (): - let Dict.919 : U64 = 11562461410679940143i64; - ret Dict.919; + let Dict.932 : U64 = 11562461410679940143i64; + ret Dict.932; procedure Dict.93 (): - let Dict.915 : U64 = 16646288086500911323i64; - ret Dict.915; + let Dict.928 : U64 = 16646288086500911323i64; + ret Dict.928; procedure Dict.94 (): - let Dict.1028 : U64 = 10285213230658275043i64; - ret Dict.1028; + let Dict.1041 : U64 = 10285213230658275043i64; + ret Dict.1041; procedure Dict.95 (): - let Dict.1018 : U64 = 6384245875588680899i64; - ret Dict.1018; + let Dict.1031 : U64 = 6384245875588680899i64; + ret Dict.1031; procedure Dict.96 (Dict.515, Dict.516): - let Dict.907 : {U64, U64} = CallByName Dict.97 Dict.515 Dict.516; - let Dict.517 : U64 = StructAtIndex 0 Dict.907; - let Dict.518 : U64 = StructAtIndex 1 Dict.907; - let Dict.906 : U64 = CallByName Num.70 Dict.517 Dict.518; - ret Dict.906; + let Dict.920 : {U64, U64} = CallByName Dict.97 Dict.515 Dict.516; + let Dict.517 : U64 = StructAtIndex 0 Dict.920; + let Dict.518 : U64 = StructAtIndex 1 Dict.920; + let Dict.919 : U64 = CallByName Num.70 Dict.517 Dict.518; + ret Dict.919; procedure Dict.97 (Dict.519, Dict.520): - let Dict.911 : U128 = CallByName Num.135 Dict.519; - let Dict.912 : U128 = CallByName Num.135 Dict.520; - let Dict.521 : U128 = CallByName Num.78 Dict.911 Dict.912; + let Dict.924 : U128 = CallByName Num.135 Dict.519; + let Dict.925 : U128 = CallByName Num.135 Dict.520; + let Dict.521 : U128 = CallByName Num.78 Dict.924 Dict.925; let Dict.522 : U64 = CallByName Num.133 Dict.521; - let Dict.910 : U8 = 64i64; - let Dict.909 : U128 = CallByName Num.74 Dict.521 Dict.910; - let Dict.523 : U64 = CallByName Num.133 Dict.909; - let Dict.908 : {U64, U64} = Struct {Dict.522, Dict.523}; - ret Dict.908; + let Dict.923 : U8 = 64i64; + let Dict.922 : U128 = CallByName Num.74 Dict.521 Dict.923; + let Dict.523 : U64 = CallByName Num.133 Dict.922; + let Dict.921 : {U64, U64} = Struct {Dict.522, Dict.523}; + ret Dict.921; procedure Dict.98 (Dict.524, Dict.525): - let Dict.973 : U8 = CallByName Dict.22 Dict.524 Dict.525; - let Dict.526 : U64 = CallByName Num.133 Dict.973; - let Dict.972 : U64 = 1i64; - let Dict.971 : U64 = CallByName Num.51 Dict.525 Dict.972; - let Dict.970 : U8 = CallByName Dict.22 Dict.524 Dict.971; - let Dict.527 : U64 = CallByName Num.133 Dict.970; - let Dict.969 : U64 = 2i64; - let Dict.968 : U64 = CallByName Num.51 Dict.525 Dict.969; - let Dict.967 : U8 = CallByName Dict.22 Dict.524 Dict.968; - let Dict.528 : U64 = CallByName Num.133 Dict.967; - let Dict.966 : U64 = 3i64; - let Dict.965 : U64 = CallByName Num.51 Dict.525 Dict.966; + let Dict.986 : U8 = CallByName Dict.22 Dict.524 Dict.525; + let Dict.526 : U64 = CallByName Num.133 Dict.986; + let Dict.985 : U64 = 1i64; + let Dict.984 : U64 = CallByName Num.51 Dict.525 Dict.985; + let Dict.983 : U8 = CallByName Dict.22 Dict.524 Dict.984; + let Dict.527 : U64 = CallByName Num.133 Dict.983; + let Dict.982 : U64 = 2i64; + let Dict.981 : U64 = CallByName Num.51 Dict.525 Dict.982; + let Dict.980 : U8 = CallByName Dict.22 Dict.524 Dict.981; + let Dict.528 : U64 = CallByName Num.133 Dict.980; + let Dict.979 : U64 = 3i64; + let Dict.978 : U64 = CallByName Num.51 Dict.525 Dict.979; + let Dict.977 : U8 = CallByName Dict.22 Dict.524 Dict.978; + let Dict.529 : U64 = CallByName Num.133 Dict.977; + let Dict.976 : U64 = 4i64; + let Dict.975 : U64 = CallByName Num.51 Dict.525 Dict.976; + let Dict.974 : U8 = CallByName Dict.22 Dict.524 Dict.975; + let Dict.530 : U64 = CallByName Num.133 Dict.974; + let Dict.973 : U64 = 5i64; + let Dict.972 : U64 = CallByName Num.51 Dict.525 Dict.973; + let Dict.971 : U8 = CallByName Dict.22 Dict.524 Dict.972; + let Dict.531 : U64 = CallByName Num.133 Dict.971; + let Dict.970 : U64 = 6i64; + let Dict.969 : U64 = CallByName Num.51 Dict.525 Dict.970; + let Dict.968 : U8 = CallByName Dict.22 Dict.524 Dict.969; + let Dict.532 : U64 = CallByName Num.133 Dict.968; + let Dict.967 : U64 = 7i64; + let Dict.965 : U64 = CallByName Num.51 Dict.525 Dict.967; let Dict.964 : U8 = CallByName Dict.22 Dict.524 Dict.965; - let Dict.529 : U64 = CallByName Num.133 Dict.964; - let Dict.963 : U64 = 4i64; - let Dict.962 : U64 = CallByName Num.51 Dict.525 Dict.963; - let Dict.961 : U8 = CallByName Dict.22 Dict.524 Dict.962; - let Dict.530 : U64 = CallByName Num.133 Dict.961; - let Dict.960 : U64 = 5i64; - let Dict.959 : U64 = CallByName Num.51 Dict.525 Dict.960; - let Dict.958 : U8 = CallByName Dict.22 Dict.524 Dict.959; - let Dict.531 : U64 = CallByName Num.133 Dict.958; - let Dict.957 : U64 = 6i64; - let Dict.956 : U64 = CallByName Num.51 Dict.525 Dict.957; - let Dict.955 : U8 = CallByName Dict.22 Dict.524 Dict.956; - let Dict.532 : U64 = CallByName Num.133 Dict.955; - let Dict.954 : U64 = 7i64; - let Dict.952 : U64 = CallByName Num.51 Dict.525 Dict.954; - let Dict.951 : U8 = CallByName Dict.22 Dict.524 Dict.952; - let Dict.533 : U64 = CallByName Num.133 Dict.951; - let Dict.950 : U8 = 8i64; - let Dict.949 : U64 = CallByName Num.72 Dict.527 Dict.950; - let Dict.534 : U64 = CallByName Num.71 Dict.526 Dict.949; - let Dict.948 : U8 = 16i64; - let Dict.945 : U64 = CallByName Num.72 Dict.528 Dict.948; - let Dict.947 : U8 = 24i64; - let Dict.946 : U64 = CallByName Num.72 Dict.529 Dict.947; - let Dict.535 : U64 = CallByName Num.71 Dict.945 Dict.946; - let Dict.944 : U8 = 32i64; - let Dict.941 : U64 = CallByName Num.72 Dict.530 Dict.944; - let Dict.943 : U8 = 40i64; - let Dict.942 : U64 = CallByName Num.72 Dict.531 Dict.943; - let Dict.536 : U64 = CallByName Num.71 Dict.941 Dict.942; - let Dict.940 : U8 = 48i64; - let Dict.937 : U64 = CallByName Num.72 Dict.532 Dict.940; - let Dict.939 : U8 = 56i64; - let Dict.938 : U64 = CallByName Num.72 Dict.533 Dict.939; - let Dict.537 : U64 = CallByName Num.71 Dict.937 Dict.938; - let Dict.935 : U64 = CallByName Num.71 Dict.534 Dict.535; - let Dict.936 : U64 = CallByName Num.71 Dict.536 Dict.537; - let Dict.934 : U64 = CallByName Num.71 Dict.935 Dict.936; - ret Dict.934; + let Dict.533 : U64 = CallByName Num.133 Dict.964; + let Dict.963 : U8 = 8i64; + let Dict.962 : U64 = CallByName Num.72 Dict.527 Dict.963; + let Dict.534 : U64 = CallByName Num.71 Dict.526 Dict.962; + let Dict.961 : U8 = 16i64; + let Dict.958 : U64 = CallByName Num.72 Dict.528 Dict.961; + let Dict.960 : U8 = 24i64; + let Dict.959 : U64 = CallByName Num.72 Dict.529 Dict.960; + let Dict.535 : U64 = CallByName Num.71 Dict.958 Dict.959; + let Dict.957 : U8 = 32i64; + let Dict.954 : U64 = CallByName Num.72 Dict.530 Dict.957; + let Dict.956 : U8 = 40i64; + let Dict.955 : U64 = CallByName Num.72 Dict.531 Dict.956; + let Dict.536 : U64 = CallByName Num.71 Dict.954 Dict.955; + let Dict.953 : U8 = 48i64; + let Dict.950 : U64 = CallByName Num.72 Dict.532 Dict.953; + let Dict.952 : U8 = 56i64; + let Dict.951 : U64 = CallByName Num.72 Dict.533 Dict.952; + let Dict.537 : U64 = CallByName Num.71 Dict.950 Dict.951; + let Dict.948 : U64 = CallByName Num.71 Dict.534 Dict.535; + let Dict.949 : U64 = CallByName Num.71 Dict.536 Dict.537; + let Dict.947 : U64 = CallByName Num.71 Dict.948 Dict.949; + ret Dict.947; procedure Dict.99 (Dict.538, Dict.539): - let Dict.1085 : U8 = CallByName Dict.22 Dict.538 Dict.539; - let Dict.540 : U64 = CallByName Num.133 Dict.1085; - let Dict.1084 : U64 = 1i64; - let Dict.1083 : U64 = CallByName Num.51 Dict.539 Dict.1084; - let Dict.1082 : U8 = CallByName Dict.22 Dict.538 Dict.1083; - let Dict.541 : U64 = CallByName Num.133 Dict.1082; - let Dict.1081 : U64 = 2i64; - let Dict.1080 : U64 = CallByName Num.51 Dict.539 Dict.1081; - let Dict.1079 : U8 = CallByName Dict.22 Dict.538 Dict.1080; - let Dict.542 : U64 = CallByName Num.133 Dict.1079; - let Dict.1078 : U64 = 3i64; - let Dict.1077 : U64 = CallByName Num.51 Dict.539 Dict.1078; - let Dict.1076 : U8 = CallByName Dict.22 Dict.538 Dict.1077; - let Dict.543 : U64 = CallByName Num.133 Dict.1076; - let Dict.1075 : U8 = 8i64; - let Dict.1074 : U64 = CallByName Num.72 Dict.541 Dict.1075; - let Dict.544 : U64 = CallByName Num.71 Dict.540 Dict.1074; - let Dict.1073 : U8 = 16i64; - let Dict.1070 : U64 = CallByName Num.72 Dict.542 Dict.1073; - let Dict.1072 : U8 = 24i64; - let Dict.1071 : U64 = CallByName Num.72 Dict.543 Dict.1072; - let Dict.545 : U64 = CallByName Num.71 Dict.1070 Dict.1071; - let Dict.1069 : U64 = CallByName Num.71 Dict.544 Dict.545; - ret Dict.1069; + let Dict.1098 : U8 = CallByName Dict.22 Dict.538 Dict.539; + let Dict.540 : U64 = CallByName Num.133 Dict.1098; + let Dict.1097 : U64 = 1i64; + let Dict.1096 : U64 = CallByName Num.51 Dict.539 Dict.1097; + let Dict.1095 : U8 = CallByName Dict.22 Dict.538 Dict.1096; + let Dict.541 : U64 = CallByName Num.133 Dict.1095; + let Dict.1094 : U64 = 2i64; + let Dict.1093 : U64 = CallByName Num.51 Dict.539 Dict.1094; + let Dict.1092 : U8 = CallByName Dict.22 Dict.538 Dict.1093; + let Dict.542 : U64 = CallByName Num.133 Dict.1092; + let Dict.1091 : U64 = 3i64; + let Dict.1090 : U64 = CallByName Num.51 Dict.539 Dict.1091; + let Dict.1089 : U8 = CallByName Dict.22 Dict.538 Dict.1090; + let Dict.543 : U64 = CallByName Num.133 Dict.1089; + let Dict.1088 : U8 = 8i64; + let Dict.1087 : U64 = CallByName Num.72 Dict.541 Dict.1088; + let Dict.544 : U64 = CallByName Num.71 Dict.540 Dict.1087; + let Dict.1086 : U8 = 16i64; + let Dict.1083 : U64 = CallByName Num.72 Dict.542 Dict.1086; + let Dict.1085 : U8 = 24i64; + let Dict.1084 : U64 = CallByName Num.72 Dict.543 Dict.1085; + let Dict.545 : U64 = CallByName Num.71 Dict.1083 Dict.1084; + let Dict.1082 : U64 = CallByName Num.71 Dict.544 Dict.545; + ret Dict.1082; procedure Hash.19 (Hash.42, Hash.43): let Hash.75 : List U8 = CallByName Str.12 Hash.43; @@ -916,21 +916,21 @@ procedure List.101 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_ jump List.678 #Derived_gen.37 #Derived_gen.38 #Derived_gen.39 #Derived_gen.40 #Derived_gen.41; procedure List.101 (#Derived_gen.42, #Derived_gen.43, #Derived_gen.44, #Derived_gen.45, #Derived_gen.46): - joinpoint List.742 List.175 List.176 List.177 List.178 List.179: - let List.744 : Int1 = CallByName Num.22 List.178 List.179; - if List.744 then - let List.748 : {Str, I64} = CallByName List.66 List.175 List.178; - inc List.748; - let List.180 : {Str, Int1} = CallByName Dict.188 List.176 List.748 List.177; - let List.747 : U64 = 1i64; - let List.746 : U64 = CallByName Num.51 List.178 List.747; - jump List.742 List.175 List.180 List.177 List.746 List.179; + joinpoint List.741 List.175 List.176 List.177 List.178 List.179: + let List.743 : Int1 = CallByName Num.22 List.178 List.179; + if List.743 then + let List.747 : {Str, I64} = CallByName List.66 List.175 List.178; + inc List.747; + let List.180 : {Str, Int1} = CallByName Dict.188 List.176 List.747 List.177; + let List.746 : U64 = 1i64; + let List.745 : U64 = CallByName Num.51 List.178 List.746; + jump List.741 List.175 List.180 List.177 List.745 List.179; else dec List.175; ret List.176; in inc #Derived_gen.42; - jump List.742 #Derived_gen.42 #Derived_gen.43 #Derived_gen.44 #Derived_gen.45 #Derived_gen.46; + jump List.741 #Derived_gen.42 #Derived_gen.43 #Derived_gen.44 #Derived_gen.45 #Derived_gen.46; procedure List.102 (#Derived_gen.47, #Derived_gen.48, #Derived_gen.49, #Derived_gen.50, #Derived_gen.51): joinpoint List.717 List.184 List.185 List.186 List.187 List.188: @@ -961,10 +961,10 @@ procedure List.18 (List.172, List.173, List.174): ret List.675; procedure List.18 (List.172, List.173, List.174): - let List.740 : U64 = 0i64; - let List.741 : U64 = CallByName List.6 List.172; - let List.739 : {Str, Int1} = CallByName List.101 List.172 List.173 List.174 List.740 List.741; - ret List.739; + let List.739 : U64 = 0i64; + let List.740 : U64 = CallByName List.6 List.172; + let List.738 : {Str, Int1} = CallByName List.101 List.172 List.173 List.174 List.739 List.740; + ret List.738; procedure List.3 (List.128, List.129, List.130): let List.701 : {List {U32, U32}, {U32, U32}} = CallByName List.64 List.128 List.129 List.130; @@ -989,8 +989,8 @@ procedure List.6 (#Attr.2): ret List.691; procedure List.6 (#Attr.2): - let List.738 : U64 = lowlevel ListLenU64 #Attr.2; - ret List.738; + let List.749 : U64 = lowlevel ListLenU64 #Attr.2; + ret List.749; procedure List.6 (#Attr.2): let List.750 : U64 = lowlevel ListLenU64 #Attr.2; @@ -1017,8 +1017,8 @@ procedure List.64 (List.125, List.126, List.127): ret List.704; procedure List.66 (#Attr.2, #Attr.3): - let List.749 : {Str, I64} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.749; + let List.748 : {Str, I64} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.748; procedure List.67 (#Attr.2, #Attr.3, #Attr.4): let List.698 : {List {U32, U32}, {U32, U32}} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4; diff --git a/crates/compiler/test_mono/generated/inspect_derived_string.txt b/crates/compiler/test_mono/generated/inspect_derived_string.txt index b7a5139fb48..4b0967686e2 100644 --- a/crates/compiler/test_mono/generated/inspect_derived_string.txt +++ b/crates/compiler/test_mono/generated/inspect_derived_string.txt @@ -167,7 +167,7 @@ procedure Str.45 (Str.91, Str.92, Str.93): dec Str.342; ret Str.91; -procedure Str.56 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3): +procedure Str.56 (Bool.24, Bool.25, Bool.26, Bool.27): joinpoint Str.250 Str.96 Str.97 Str.98 Str.99: inc Str.97; let Str.251 : [C {}, C {Str, Str}] = CallByName Str.38 Str.97 Str.98; @@ -191,9 +191,9 @@ procedure Str.56 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3 dec Str.97; ret Str.255; in - inc #Derived_gen.3; - inc #Derived_gen.2; - jump Str.250 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3; + inc Bool.26; + inc Bool.27; + jump Str.250 Bool.24 Bool.25 Bool.26 Bool.27; procedure Str.57 (Str.121, Str.122): let Str.123 : U64 = CallByName Str.36 Str.121; @@ -203,7 +203,7 @@ procedure Str.57 (Str.121, Str.122): let Str.276 : [C , C U64] = CallByName Str.58 Str.121 Str.122 Str.277 Str.125; ret Str.276; -procedure Str.58 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7): +procedure Str.58 (Bool.28, Bool.29, Bool.30, Bool.31): joinpoint Str.278 Str.126 Str.127 Str.128 Str.129: let Str.280 : Int1 = CallByName Num.23 Str.128 Str.129; if Str.280 then @@ -223,9 +223,9 @@ procedure Str.58 (#Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7 let Str.279 : [C , C U64] = TagId(0) ; ret Str.279; in - inc #Derived_gen.5; - inc #Derived_gen.4; - jump Str.278 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7; + inc Bool.29; + inc Bool.28; + jump Str.278 Bool.28 Bool.29 Bool.30 Bool.31; procedure Str.61 (Str.152, Str.153): let Str.309 : Int1 = CallByName Num.22 Str.152 Str.153; diff --git a/crates/compiler/test_mono/generated/issue_3669.txt b/crates/compiler/test_mono/generated/issue_3669.txt index 93803a4d5be..e688b8910cd 100644 --- a/crates/compiler/test_mono/generated/issue_3669.txt +++ b/crates/compiler/test_mono/generated/issue_3669.txt @@ -2,7 +2,7 @@ procedure Bool.9 (#Attr.2, #Attr.3): let Bool.21 : Int1 = lowlevel Eq #Attr.2 #Attr.3; ret Bool.21; -procedure Test.2 (#Derived_gen.0): +procedure Test.2 (Bool.22): joinpoint Test.13 Test.7: let Test.16 : U8 = 1i64; let Test.17 : U8 = GetTagId Test.7; @@ -13,8 +13,8 @@ procedure Test.2 (#Derived_gen.0): ret Test.14; else let Test.5 : [, C *self] = UnionAtIndex (Id 0) (Index 0) Test.7; - let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.7; - if #Derived_gen.1 then + let Bool.23 : Int1 = lowlevel RefCountIsUnique Test.7; + if Bool.23 then free Test.7; jump Test.13 Test.5; else @@ -22,7 +22,7 @@ procedure Test.2 (#Derived_gen.0): decref Test.7; jump Test.13 Test.5; in - jump Test.13 #Derived_gen.0; + jump Test.13 Bool.22; procedure Test.0 (): let Test.12 : [, C *self] = TagId(1) ; diff --git a/crates/compiler/test_mono/generated/issue_4770.txt b/crates/compiler/test_mono/generated/issue_4770.txt index a81089b3b32..fe58ec3a8eb 100644 --- a/crates/compiler/test_mono/generated/issue_4770.txt +++ b/crates/compiler/test_mono/generated/issue_4770.txt @@ -6,7 +6,7 @@ procedure Bool.2 (): let Bool.22 : Int1 = true; ret Bool.22; -procedure List.106 (#Derived_gen.6, #Derived_gen.7, #Derived_gen.8, #Derived_gen.9, #Derived_gen.10, #Derived_gen.11): +procedure List.106 (Bool.30, Bool.31, Bool.32, Bool.33, Bool.34, Bool.35): joinpoint List.713 List.291 List.292 List.293 List.294 List.295 List.296: let List.715 : Int1 = CallByName Num.22 List.295 List.296; if List.715 then @@ -24,9 +24,9 @@ procedure List.106 (#Derived_gen.6, #Derived_gen.7, #Derived_gen.8, #Derived_gen dec List.292; ret List.293; in - inc #Derived_gen.6; - inc #Derived_gen.7; - jump List.713 #Derived_gen.6 #Derived_gen.7 #Derived_gen.8 #Derived_gen.9 #Derived_gen.10 #Derived_gen.11; + inc Bool.30; + inc Bool.31; + jump List.713 Bool.30 Bool.31 Bool.32 Bool.33 Bool.34 Bool.35; procedure List.116 (List.563, List.564, List.565): let List.689 : U64 = 0i64; @@ -91,7 +91,7 @@ procedure List.71 (#Attr.2, #Attr.3): let List.720 : List {[C I64, C List *self], [C I64, C List *self]} = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; ret List.720; -procedure List.80 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4, #Derived_gen.5): +procedure List.80 (Bool.25, Bool.26, Bool.27, Bool.28, Bool.29): joinpoint List.691 List.566 List.567 List.568 List.569 List.570: let List.693 : Int1 = CallByName Num.22 List.569 List.570; if List.693 then @@ -116,8 +116,8 @@ procedure List.80 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen. let List.692 : [C {}, C {}] = TagId(1) List.567; ret List.692; in - inc #Derived_gen.1; - jump List.691 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5; + inc Bool.25; + jump List.691 Bool.25 Bool.26 Bool.27 Bool.28 Bool.29; procedure Num.148 (Num.226, Num.227): let Num.290 : Int1 = CallByName Num.22 Num.226 Num.227; @@ -138,7 +138,7 @@ procedure Num.51 (#Attr.2, #Attr.3): let Num.286 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3; ret Num.286; -procedure Test.1 (#Derived_gen.0): +procedure Test.1 (Bool.24): joinpoint Test.26 Test.6: let Test.65 : [C I64, C List *self] = StructAtIndex 1 Test.6; let Test.66 : U8 = 0i64; @@ -155,17 +155,17 @@ procedure Test.1 (#Derived_gen.0): let Test.49 : [C I64, C List *self] = StructAtIndex 1 Test.6; dec Test.50; let Test.10 : I64 = UnionAtIndex (Id 0) (Index 0) Test.49; - joinpoint #Derived_gen.12: + joinpoint Bool.36: let Test.27 : Int1 = CallByName Num.22 Test.8 Test.10; ret Test.27; in - let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique Test.49; - if #Derived_gen.13 then + let Bool.37 : Int1 = lowlevel RefCountIsUnique Test.49; + if Bool.37 then free Test.49; - jump #Derived_gen.12; + jump Bool.36; else decref Test.49; - jump #Derived_gen.12; + jump Bool.36; else let Test.39 : [C I64, C List *self] = StructAtIndex 0 Test.6; let Test.42 : [C I64, C List *self] = StructAtIndex 1 Test.6; @@ -185,7 +185,7 @@ procedure Test.1 (#Derived_gen.0): let Test.51 : [C I64, C List *self] = StructAtIndex 1 Test.6; dec Test.52; let Test.14 : List [C I64, C List *self] = UnionAtIndex (Id 1) (Index 0) Test.51; - joinpoint #Derived_gen.14: + joinpoint Bool.38: let Test.35 : {} = Struct {}; let Test.33 : List {[C I64, C List *self], [C I64, C List *self]} = CallByName List.23 Test.12 Test.14 Test.35; let Test.34 : {} = Struct {}; @@ -204,14 +204,14 @@ procedure Test.1 (#Derived_gen.0): let Test.28 : Int1 = CallByName Bool.1; ret Test.28; in - let #Derived_gen.15 : Int1 = lowlevel RefCountIsUnique Test.51; - if #Derived_gen.15 then + let Bool.39 : Int1 = lowlevel RefCountIsUnique Test.51; + if Bool.39 then free Test.51; - jump #Derived_gen.14; + jump Bool.38; else inc Test.14; decref Test.51; - jump #Derived_gen.14; + jump Bool.38; else let Test.48 : [C I64, C List *self] = StructAtIndex 0 Test.6; let Test.47 : List [C I64, C List *self] = Array [Test.48]; @@ -220,7 +220,7 @@ procedure Test.1 (#Derived_gen.0): let Test.44 : {[C I64, C List *self], [C I64, C List *self]} = Struct {Test.45, Test.46}; jump Test.26 Test.44; in - jump Test.26 #Derived_gen.0; + jump Test.26 Bool.24; procedure Test.15 (Test.16, Test.17): let Test.36 : {[C I64, C List *self], [C I64, C List *self]} = Struct {Test.16, Test.17}; diff --git a/crates/compiler/test_mono/generated/issue_6196.txt b/crates/compiler/test_mono/generated/issue_6196.txt index fa1b1cdfe2c..6af7885957d 100644 --- a/crates/compiler/test_mono/generated/issue_6196.txt +++ b/crates/compiler/test_mono/generated/issue_6196.txt @@ -2,7 +2,7 @@ procedure Num.20 (#Attr.2, #Attr.3): let Num.283 : U64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.283; -procedure Test.1 (#Derived_gen.0, #Derived_gen.1): +procedure Test.1 (Bool.21, Bool.22): joinpoint Test.12 Test.2 Test.3: let Test.13 : {List Str, U64} = Struct {Test.2, Test.3}; let Test.31 : List Str = StructAtIndex 0 Test.13; @@ -37,8 +37,8 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1): let Test.14 : [C {}, C Str] = TagId(0) Test.15; ret Test.14; in - inc #Derived_gen.0; - jump Test.12 #Derived_gen.0 #Derived_gen.1; + inc Bool.21; + jump Test.12 Bool.21 Bool.22; procedure Test.0 (): let Test.35 : Str = "a"; 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 179e13022d8..7e163f19f51 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 @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25): joinpoint List.678 List.175 List.176 List.177 List.178 List.179: let List.680 : Int1 = CallByName Num.22 List.178 List.179; if List.680 then @@ -12,8 +12,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.0; - jump List.678 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.21; + jump List.678 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25; procedure List.18 (List.172, List.173, List.174): let List.676 : U64 = 0i64; diff --git a/crates/compiler/test_mono/generated/linked_list_filter.txt b/crates/compiler/test_mono/generated/linked_list_filter.txt index ef269d33487..43dfd75e9d8 100644 --- a/crates/compiler/test_mono/generated/linked_list_filter.txt +++ b/crates/compiler/test_mono/generated/linked_list_filter.txt @@ -8,19 +8,19 @@ procedure Test.2 (Test.4, Test.5): else let Test.7 : I64 = UnionAtIndex (Id 0) (Index 0) Test.4; let Test.8 : [, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.4; - joinpoint #Derived_gen.4: + joinpoint Bool.25: dec Test.8; let Test.22 : Str = "a Lambda Set is empty. Most likely there is a type error in your program."; Crash Test.22 in - let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.4; - if #Derived_gen.5 then + let Bool.26 : Int1 = lowlevel RefCountIsUnique Test.4; + if Bool.26 then free Test.4; - jump #Derived_gen.4; + jump Bool.25; else inc Test.8; decref Test.4; - jump #Derived_gen.4; + jump Bool.25; procedure Test.0 (): let Test.27 : I64 = 1i64; @@ -28,15 +28,15 @@ procedure Test.0 (): let Test.30 : [, C I64 *self] = TagId(1) ; let Test.28 : [, C I64 *self] = TagId(0) Test.29 Test.30; let Test.14 : [, C I64 *self] = TagId(0) Test.27 Test.28; - joinpoint #Derived_gen.2: + joinpoint Bool.23: let Test.26 : Str = "ValueNotExposed { module_name: ModuleName(IdentStr { string: \"Num\" }), ident: Ident(IdentStr { string: \"isEven\" }), region: @416-426, exposed_values: ['max_f32', 'min_f32', 'abs', 'neg', 'add', 'sub', 'mul', 'is_lt', 'is_lte', 'is_gt', 'is_gte', 'to_frac', 'sin', 'cos', 'tan', 'is_zero', 'is_even', 'is_odd', 'is_positive', 'is_negative', 'rem', 'rem_checked', 'div', 'div_checked', 'div_trunc', 'div_trunc_checked', 'sqrt', 'sqrt_checked', 'log', 'log_checked', 'round', 'compare', 'pow', 'ceiling', 'pow_int', 'floor', 'add_wrap', 'add_checked', 'add_saturated', 'atan', 'acos', 'asin', 'bitwise_and', 'bitwise_xor', 'bitwise_or', 'shift_left_by', 'shift_right_by', 'shift_right_zf_by', 'sub_wrap', 'sub_checked', 'sub_saturated', 'mul_wrap', 'mul_checked', 'mul_saturated', 'e', 'pi', 'tau', 'is_multiple_of', 'count_one_bits', 'abs_diff', 'is_nan', 'is_infinite', 'is_finite', 'count_leading_zero_bits', 'count_trailing_zero_bits', 'to_str', 'min_i8', 'max_i8', 'min_u8', 'max_u8', 'min_i16', 'max_i16', 'min_u16', 'max_u16', 'min_i32', 'max_i32', 'min_u32', 'max_u32', 'min_i64', 'max_i64', 'min_u64', 'max_u64', 'min_i128', 'max_i128', 'min_u128', 'max_u128', 'to_i8', 'to_i8_checked', 'to_i16', 'to_i16_checked', 'to_i32', 'to_i32_checked', 'to_i64', 'to_i64_checked', 'to_i128', 'to_i128_checked', 'to_u8', 'to_u8_checked', 'to_u16', 'to_u16_checked', 'to_u32', 'to_u32_checked', 'to_u64', 'to_u64_checked', 'to_u128', 'to_u128_checked', 'div_ceil', 'div_ceil_checked', 'to_f32', 'to_f32_checked', 'to_f64', 'to_f64_checked', 'max_f64', 'min_f64', 'add_checked_lowlevel', 'sub_checked_lowlevel', 'mul_checked_lowlevel', 'min', 'max', 'bitwise_not', 'int_cast', 'is_approx_eq', 'bytes_to_u16_owlevel', 'bytes_to_u32_lowlevel', 'bytes_to_u64_lowlevel', 'bytes_to_u128_lowlevel', 'div_trunc_unchecked', 'rem_unchecked', 'without_decimal_point', 'with_decimal_point', 'f32_to_parts', 'f64_to_parts', 'f32_from_parts', 'f64_from_parts', 'nan_f32', 'nan_f64', 'infinity_f32', 'infinity_f64', 'from_bool'] }"; Crash Test.26 in - let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique Test.14; - if #Derived_gen.3 then + let Bool.24 : Int1 = lowlevel RefCountIsUnique Test.14; + if Bool.24 then dec Test.28; free Test.14; - jump #Derived_gen.2; + jump Bool.23; else decref Test.14; - jump #Derived_gen.2; + jump Bool.23; diff --git a/crates/compiler/test_mono/generated/linked_list_map.txt b/crates/compiler/test_mono/generated/linked_list_map.txt index 3a6f81c737d..1a6aeb3728c 100644 --- a/crates/compiler/test_mono/generated/linked_list_map.txt +++ b/crates/compiler/test_mono/generated/linked_list_map.txt @@ -7,39 +7,39 @@ procedure Test.10 (Test.11): let Test.27 : I64 = CallByName Num.19 Test.11 Test.28; ret Test.27; -procedure Test.2 (#Derived_gen.0, #Derived_gen.1): - let #Derived_gen.3 : [, C I64 *self] = NullPointer; - let #Derived_gen.2 : Ptr([, C I64 *self]) = Alloca #Derived_gen.3; - joinpoint #Derived_gen.4 Test.4 Test.5 #Derived_gen.5 #Derived_gen.6: +procedure Test.2 (Bool.21, Bool.22): + let Bool.24 : [, C I64 *self] = NullPointer; + let Bool.23 : Ptr([, C I64 *self]) = Alloca Bool.24; + joinpoint Bool.25 Test.4 Test.5 Bool.26 Bool.27: let Test.22 : U8 = 1i64; let Test.23 : U8 = GetTagId Test.5; let Test.24 : Int1 = lowlevel Eq Test.22 Test.23; if Test.24 then let Test.18 : [, C I64 *self] = TagId(1) ; - let #Derived_gen.8 : {} = lowlevel PtrStore #Derived_gen.5 Test.18; - let #Derived_gen.7 : [, C I64 *self] = lowlevel PtrLoad #Derived_gen.6; - ret #Derived_gen.7; + let Bool.29 : {} = lowlevel PtrStore Bool.26 Test.18; + let Bool.28 : [, C I64 *self] = lowlevel PtrLoad Bool.27; + ret Bool.28; else let Test.7 : I64 = UnionAtIndex (Id 0) (Index 0) Test.5; let Test.8 : [, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.5; - joinpoint #Derived_gen.12 #Derived_gen.14: + joinpoint Bool.33 Bool.35: let Test.20 : I64 = CallByName Test.10 Test.7; - let #Derived_gen.9 : [, C I64 *self] = NullPointer; - let Test.19 : [, C I64 *self] = Reuse #Derived_gen.14 UpdateModeId { id: 1 } TagId(0) Test.20 #Derived_gen.9; - let #Derived_gen.10 : Ptr([, C I64 *self]) = GetElementPointer (Indices [0, 1]) Test.19; - let #Derived_gen.11 : {} = lowlevel PtrStore #Derived_gen.5 Test.19; - jump #Derived_gen.4 Test.4 Test.8 #Derived_gen.10 #Derived_gen.6; + let Bool.30 : [, C I64 *self] = NullPointer; + let Test.19 : [, C I64 *self] = Reuse Bool.35 UpdateModeId { id: 1 } TagId(0) Test.20 Bool.30; + let Bool.31 : Ptr([, C I64 *self]) = GetElementPointer (Indices [0, 1]) Test.19; + let Bool.32 : {} = lowlevel PtrStore Bool.26 Test.19; + jump Bool.25 Test.4 Test.8 Bool.31 Bool.27; in - let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique Test.5; - if #Derived_gen.13 then - jump #Derived_gen.12 Test.5; + let Bool.34 : Int1 = lowlevel RefCountIsUnique Test.5; + if Bool.34 then + jump Bool.33 Test.5; else inc Test.8; decref Test.5; - let #Derived_gen.15 : [, C I64 *self] = NullPointer; - jump #Derived_gen.12 #Derived_gen.15; + let Bool.36 : [, C I64 *self] = NullPointer; + jump Bool.33 Bool.36; in - jump #Derived_gen.4 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.2; + jump Bool.25 Bool.21 Bool.22 Bool.23 Bool.23; procedure Test.0 (): let Test.15 : {} = Struct {}; diff --git a/crates/compiler/test_mono/generated/linked_list_reverse.txt b/crates/compiler/test_mono/generated/linked_list_reverse.txt index 892df1a7132..6dbe985c785 100644 --- a/crates/compiler/test_mono/generated/linked_list_reverse.txt +++ b/crates/compiler/test_mono/generated/linked_list_reverse.txt @@ -3,7 +3,7 @@ procedure Test.2 (Test.5): let Test.16 : [, C I64 *self] = CallByName Test.3 Test.17 Test.5; ret Test.16; -procedure Test.3 (#Derived_gen.0, #Derived_gen.1): +procedure Test.3 (Bool.21, Bool.22): joinpoint Test.18 Test.7 Test.8: let Test.22 : U8 = 1i64; let Test.23 : U8 = GetTagId Test.8; @@ -13,20 +13,20 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1): else let Test.9 : I64 = UnionAtIndex (Id 0) (Index 0) Test.8; let Test.10 : [, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.8; - joinpoint #Derived_gen.2 #Derived_gen.4: - let Test.21 : [, C I64 *self] = Reuse #Derived_gen.4 UpdateModeId { id: 1 } TagId(0) Test.9 Test.7; + joinpoint Bool.23 Bool.25: + let Test.21 : [, C I64 *self] = Reuse Bool.25 UpdateModeId { id: 1 } TagId(0) Test.9 Test.7; jump Test.18 Test.21 Test.10; in - let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique Test.8; - if #Derived_gen.3 then - jump #Derived_gen.2 Test.8; + let Bool.24 : Int1 = lowlevel RefCountIsUnique Test.8; + if Bool.24 then + jump Bool.23 Test.8; else inc Test.10; decref Test.8; - let #Derived_gen.5 : [, C I64 *self] = NullPointer; - jump #Derived_gen.2 #Derived_gen.5; + let Bool.26 : [, C I64 *self] = NullPointer; + jump Bool.23 Bool.26; in - jump Test.18 #Derived_gen.0 #Derived_gen.1; + jump Test.18 Bool.21 Bool.22; procedure Test.0 (): let Test.25 : I64 = 42i64; 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 4da503bf4bd..f231d34488f 100644 --- a/crates/compiler/test_mono/generated/list_map_closure_borrows.txt +++ b/crates/compiler/test_mono/generated/list_map_closure_borrows.txt @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25): joinpoint List.689 List.175 List.176 List.177 List.178 List.179: let List.691 : Int1 = CallByName Num.22 List.178 List.179; if List.691 then @@ -13,8 +13,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.0; - jump List.689 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.21; + jump List.689 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25; procedure List.18 (List.172, List.173, List.174): let List.687 : U64 = 0i64; 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 14c83d6014c..c2bee90b64b 100644 --- a/crates/compiler/test_mono/generated/list_map_closure_owns.txt +++ b/crates/compiler/test_mono/generated/list_map_closure_owns.txt @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25): joinpoint List.689 List.175 List.176 List.177 List.178 List.179: let List.691 : Int1 = CallByName Num.22 List.178 List.179; if List.691 then @@ -12,8 +12,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.0; - jump List.689 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.21; + jump List.689 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25; procedure List.18 (List.172, List.173, List.174): let List.687 : U64 = 0i64; 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 a2fd6b60559..bedfabc3742 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 @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.101 (Bool.21, Bool.22, Bool.23, Bool.24, Bool.25): joinpoint List.681 List.175 List.176 List.177 List.178 List.179: let List.683 : Int1 = CallByName Num.22 List.178 List.179; if List.683 then @@ -11,8 +11,8 @@ procedure List.101 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.0; - jump List.681 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.21; + jump List.681 Bool.21 Bool.22 Bool.23 Bool.24 Bool.25; procedure List.18 (List.172, List.173, List.174): let List.679 : U64 = 0i64; diff --git a/crates/compiler/test_mono/generated/pattern_as_toplevel.txt b/crates/compiler/test_mono/generated/pattern_as_toplevel.txt index 1b71bcb5771..b06beea1570 100644 --- a/crates/compiler/test_mono/generated/pattern_as_toplevel.txt +++ b/crates/compiler/test_mono/generated/pattern_as_toplevel.txt @@ -21,11 +21,11 @@ procedure Test.0 (): let Test.6 : {I64, Str} = CallByName Test.1; let Test.5 : Int1 = CallByName Bool.9 Test.6 Test.4; dec Test.6; - let #Derived_gen.0 : Str = StructAtIndex 1 Test.4; - dec #Derived_gen.0; + let Bool.23 : Str = StructAtIndex 1 Test.4; + dec Bool.23; ret Test.5; else - let #Derived_gen.1 : Str = StructAtIndex 1 Test.4; - dec #Derived_gen.1; + let Bool.24 : Str = StructAtIndex 1 Test.4; + dec Bool.24; let Test.10 : Int1 = CallByName Bool.1; ret Test.10; diff --git a/crates/compiler/test_mono/generated/peano1.txt b/crates/compiler/test_mono/generated/peano1.txt index 7ec0b3c2f5f..794fd931abe 100644 --- a/crates/compiler/test_mono/generated/peano1.txt +++ b/crates/compiler/test_mono/generated/peano1.txt @@ -5,7 +5,7 @@ procedure Test.0 (): let Test.2 : [, C *self] = TagId(0) Test.13; let Test.10 : U8 = 1i64; let Test.11 : U8 = GetTagId Test.2; - joinpoint #Derived_gen.0: + joinpoint Bool.21: let Test.12 : Int1 = lowlevel Eq Test.10 Test.11; if Test.12 then let Test.8 : I64 = 0i64; @@ -14,11 +14,11 @@ procedure Test.0 (): let Test.9 : I64 = 1i64; ret Test.9; in - let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2; - if #Derived_gen.1 then + let Bool.22 : Int1 = lowlevel RefCountIsUnique Test.2; + if Bool.22 then dec Test.13; free Test.2; - jump #Derived_gen.0; + jump Bool.21; else decref Test.2; - jump #Derived_gen.0; + jump Bool.21; diff --git a/crates/compiler/test_mono/generated/peano2.txt b/crates/compiler/test_mono/generated/peano2.txt index f090c272ddc..b51c00b49d2 100644 --- a/crates/compiler/test_mono/generated/peano2.txt +++ b/crates/compiler/test_mono/generated/peano2.txt @@ -8,7 +8,7 @@ procedure Test.0 (): let Test.18 : Int1 = lowlevel Eq Test.16 Test.17; if Test.18 then let Test.12 : [, C *self] = UnionAtIndex (Id 0) (Index 0) Test.2; - joinpoint #Derived_gen.0: + joinpoint Bool.21: let Test.13 : U8 = 0i64; let Test.14 : U8 = GetTagId Test.12; dec Test.12; @@ -20,14 +20,14 @@ procedure Test.0 (): let Test.9 : I64 = 0i64; ret Test.9; in - let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2; - if #Derived_gen.1 then + let Bool.22 : Int1 = lowlevel RefCountIsUnique Test.2; + if Bool.22 then free Test.2; - jump #Derived_gen.0; + jump Bool.21; else inc Test.12; decref Test.2; - jump #Derived_gen.0; + jump Bool.21; else let Test.10 : I64 = 0i64; ret Test.10; diff --git a/crates/compiler/test_mono/generated/pizza_dbg.txt b/crates/compiler/test_mono/generated/pizza_dbg.txt index 3c8c1193143..79812c5fdcb 100644 --- a/crates/compiler/test_mono/generated/pizza_dbg.txt +++ b/crates/compiler/test_mono/generated/pizza_dbg.txt @@ -47,13 +47,13 @@ procedure Str.3 (#Attr.2, #Attr.3): ret Str.246; procedure Test.0 (): - let Test.4 : I64 = 1i64; - let Test.5 : Str = CallByName Inspect.33 Test.4; - dbg Test.5; - dec Test.5; - let Test.9 : I64 = 2i64; - let Test.3 : I64 = CallByName Num.19 Test.4 Test.9; - let Test.6 : Str = CallByName Inspect.33 Test.3; - dbg Test.6; - dec Test.6; - ret Test.3; + let Test.2 : I64 = 1i64; + let Test.3 : Str = CallByName Inspect.33 Test.2; + dbg Test.3; + dec Test.3; + let Test.7 : I64 = 2i64; + let Test.1 : I64 = CallByName Num.19 Test.2 Test.7; + let Test.4 : Str = CallByName Inspect.33 Test.1; + dbg Test.4; + dec Test.4; + ret Test.1; diff --git a/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt b/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt index ad0f58c7d73..36b17debfab 100644 --- a/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt +++ b/crates/compiler/test_mono/generated/polymorphic_expression_unification.txt @@ -30,15 +30,15 @@ procedure Test.0 (): let Test.16 : Str = ""; let Test.15 : [C List *self, C Str] = TagId(1) Test.16; let Test.13 : Int1 = CallByName Bool.9 Test.14 Test.15; - joinpoint #Derived_gen.0: + joinpoint Bool.22: dec Test.14; ret Test.13; in - let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.15; - if #Derived_gen.1 then + let Bool.23 : Int1 = lowlevel RefCountIsUnique Test.15; + if Bool.23 then dec Test.16; free Test.15; - jump #Derived_gen.0; + jump Bool.22; else decref Test.15; - jump #Derived_gen.0; + jump Bool.22; diff --git a/crates/compiler/test_mono/generated/quicksort_help.txt b/crates/compiler/test_mono/generated/quicksort_help.txt index 2b5a06dbda3..430cb3554b1 100644 --- a/crates/compiler/test_mono/generated/quicksort_help.txt +++ b/crates/compiler/test_mono/generated/quicksort_help.txt @@ -10,7 +10,7 @@ procedure Num.22 (#Attr.2, #Attr.3): let Num.285 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; ret Num.285; -procedure Test.1 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): +procedure Test.1 (Bool.21, Bool.22, Bool.23): joinpoint Test.12 Test.2 Test.3 Test.4: let Test.14 : Int1 = CallByName Num.22 Test.3 Test.4; if Test.14 then @@ -29,7 +29,7 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): else ret Test.2; in - jump Test.12 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2; + jump Test.12 Bool.21 Bool.22 Bool.23; procedure Test.0 (): let Test.9 : List I64 = Array []; diff --git a/crates/compiler/test_mono/generated/rb_tree_fbip.txt b/crates/compiler/test_mono/generated/rb_tree_fbip.txt index 19b36ee93b8..9b9742d2c94 100644 --- a/crates/compiler/test_mono/generated/rb_tree_fbip.txt +++ b/crates/compiler/test_mono/generated/rb_tree_fbip.txt @@ -6,10 +6,10 @@ procedure Num.24 (#Attr.2, #Attr.3): let Num.284 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; ret Num.284; -procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): - let #Derived_gen.4 : [C *self I64 *self I32 Int1, ] = NullPointer; - let #Derived_gen.3 : Ptr([C *self I64 *self I32 Int1, ]) = Alloca #Derived_gen.4; - joinpoint #Derived_gen.5 Test.9 Test.10 Test.11 #Derived_gen.6 #Derived_gen.7: +procedure Test.3 (Bool.21, Bool.22, Bool.23): + let Bool.25 : [C *self I64 *self I32 Int1, ] = NullPointer; + let Bool.24 : Ptr([C *self I64 *self I32 Int1, ]) = Alloca Bool.25; + joinpoint Bool.26 Test.9 Test.10 Test.11 Bool.27 Bool.28: let Test.254 : U8 = 0i64; let Test.255 : U8 = GetTagId Test.9; let Test.256 : Int1 = lowlevel Eq Test.254 Test.255; @@ -18,9 +18,9 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.114 : [C *self I64 *self I32 Int1, ] = TagId(0) ; let Test.112 : Int1 = true; let Test.111 : [C *self I64 *self I32 Int1, ] = TagId(1) Test.113 Test.11 Test.114 Test.10 Test.112; - let #Derived_gen.9 : {} = lowlevel PtrStore #Derived_gen.6 Test.111; - let #Derived_gen.8 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.8; + let Bool.30 : {} = lowlevel PtrStore Bool.27 Test.111; + let Bool.29 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.29; else let Test.251 : Int1 = UnionAtIndex (Id 1) (Index 4) Test.9; let Test.252 : Int1 = false; @@ -30,16 +30,16 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.18 : I64 = UnionAtIndex (Id 1) (Index 1) Test.9; let Test.19 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.9; let Test.17 : I32 = UnionAtIndex (Id 1) (Index 3) Test.9; - joinpoint #Derived_gen.114 #Derived_gen.118: + joinpoint Bool.135 Bool.139: let Test.179 : Int1 = CallByName Num.22 Test.10 Test.17; if Test.179 then - joinpoint Test.238 #Derived_gen.166: + joinpoint Test.238 Bool.187: let Test.232 : Int1 = false; - let #Derived_gen.10 : [C *self I64 *self I32 Int1, ] = NullPointer; - let Test.231 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.166 UpdateModeId { id: 56 } TagId(1) #Derived_gen.10 Test.18 Test.19 Test.17 Test.232; - let #Derived_gen.11 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 0]) Test.231; - let #Derived_gen.12 : {} = lowlevel PtrStore #Derived_gen.6 Test.231; - jump #Derived_gen.5 Test.16 Test.10 Test.11 #Derived_gen.11 #Derived_gen.7; + let Bool.31 : [C *self I64 *self I32 Int1, ] = NullPointer; + let Test.231 : [C *self I64 *self I32 Int1, ] = Reuse Bool.187 UpdateModeId { id: 56 } TagId(1) Bool.31 Test.18 Test.19 Test.17 Test.232; + let Bool.32 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 0]) Test.231; + let Bool.33 : {} = lowlevel PtrStore Bool.27 Test.231; + jump Bool.26 Test.16 Test.10 Test.11 Bool.32 Bool.28; in let Test.236 : U8 = 1i64; let Test.237 : U8 = GetTagId Test.16; @@ -50,7 +50,7 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.239 : Int1 = lowlevel Eq Test.235 Test.234; if Test.239 then let Test.180 : [C *self I64 *self I32 Int1, ] = CallByName Test.3 Test.16 Test.10 Test.11; - joinpoint Test.199 #Derived_gen.187: + joinpoint Test.199 Bool.208: let Test.198 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.180; let Test.20 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.198; inc Test.20; @@ -61,55 +61,55 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.25 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180; let Test.26 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.180; let Test.24 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180; - joinpoint #Derived_gen.72 #Derived_gen.189 #Derived_gen.190 #Derived_gen.191: + joinpoint Bool.93 Bool.210 Bool.211 Bool.212: let Test.186 : Int1 = false; - let Test.183 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.191 UpdateModeId { id: 85 } TagId(1) Test.20 Test.22 Test.23 Test.21 Test.186; + let Test.183 : [C *self I64 *self I32 Int1, ] = Reuse Bool.212 UpdateModeId { id: 85 } TagId(1) Test.20 Test.22 Test.23 Test.21 Test.186; let Test.185 : Int1 = false; - let Test.184 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.190 UpdateModeId { id: 84 } TagId(1) Test.26 Test.18 Test.19 Test.17 Test.185; + let Test.184 : [C *self I64 *self I32 Int1, ] = Reuse Bool.211 UpdateModeId { id: 84 } TagId(1) Test.26 Test.18 Test.19 Test.17 Test.185; let Test.182 : Int1 = true; - let Test.181 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.189 UpdateModeId { id: 83 } TagId(1) Test.183 Test.25 Test.184 Test.24 Test.182; - let #Derived_gen.14 : {} = lowlevel PtrStore #Derived_gen.6 Test.181; - let #Derived_gen.13 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.13; + let Test.181 : [C *self I64 *self I32 Int1, ] = Reuse Bool.210 UpdateModeId { id: 83 } TagId(1) Test.183 Test.25 Test.184 Test.24 Test.182; + let Bool.35 : {} = lowlevel PtrStore Bool.27 Test.181; + let Bool.34 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.34; in - let #Derived_gen.73 : Int1 = lowlevel RefCountIsUnique Test.180; - if #Derived_gen.73 then - let #Derived_gen.192 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.198, id: UpdateModeId { id: 86 } }; - jump #Derived_gen.72 #Derived_gen.187 #Derived_gen.192 Test.180; + let Bool.94 : Int1 = lowlevel RefCountIsUnique Test.180; + if Bool.94 then + let Bool.213 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.198, id: UpdateModeId { id: 86 } }; + jump Bool.93 Bool.208 Bool.213 Test.180; else inc Test.26; decref Test.180; - let #Derived_gen.193 : [C *self I64 *self I32 Int1, ] = NullPointer; - jump #Derived_gen.72 #Derived_gen.193 #Derived_gen.193 #Derived_gen.187; + let Bool.214 : [C *self I64 *self I32 Int1, ] = NullPointer; + jump Bool.93 Bool.214 Bool.214 Bool.208; in let Test.228 : U8 = 1i64; let Test.229 : U8 = GetTagId Test.180; let Test.230 : Int1 = lowlevel Eq Test.228 Test.229; if Test.230 then - joinpoint Test.225 #Derived_gen.201: - joinpoint Test.216 #Derived_gen.202: + joinpoint Test.225 Bool.222: + joinpoint Test.216 Bool.223: let Test.46 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.180; let Test.48 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180; let Test.49 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.180; let Test.47 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180; - joinpoint #Derived_gen.66 #Derived_gen.203 #Derived_gen.204: + joinpoint Bool.87 Bool.224 Bool.225: let Test.196 : Int1 = true; - let Test.195 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.204 UpdateModeId { id: 100 } TagId(1) Test.46 Test.48 Test.49 Test.47 Test.196; + let Test.195 : [C *self I64 *self I32 Int1, ] = Reuse Bool.225 UpdateModeId { id: 100 } TagId(1) Test.46 Test.48 Test.49 Test.47 Test.196; let Test.194 : Int1 = false; - let Test.193 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.203 UpdateModeId { id: 99 } TagId(1) Test.195 Test.18 Test.19 Test.17 Test.194; - let #Derived_gen.16 : {} = lowlevel PtrStore #Derived_gen.6 Test.193; - let #Derived_gen.15 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.15; + let Test.193 : [C *self I64 *self I32 Int1, ] = Reuse Bool.224 UpdateModeId { id: 99 } TagId(1) Test.195 Test.18 Test.19 Test.17 Test.194; + let Bool.37 : {} = lowlevel PtrStore Bool.27 Test.193; + let Bool.36 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.36; in - let #Derived_gen.67 : Int1 = lowlevel RefCountIsUnique Test.180; - if #Derived_gen.67 then - jump #Derived_gen.66 #Derived_gen.202 Test.180; + let Bool.88 : Int1 = lowlevel RefCountIsUnique Test.180; + if Bool.88 then + jump Bool.87 Bool.223 Test.180; else inc Test.46; inc Test.49; decref Test.180; - let #Derived_gen.205 : [C *self I64 *self I32 Int1, ] = NullPointer; - jump #Derived_gen.66 #Derived_gen.205 #Derived_gen.202; + let Bool.226 : [C *self I64 *self I32 Int1, ] = NullPointer; + jump Bool.87 Bool.226 Bool.223; in let Test.213 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.180; let Test.214 : U8 = 1i64; @@ -121,11 +121,11 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.212 : Int1 = true; let Test.217 : Int1 = lowlevel Eq Test.212 Test.211; if Test.217 then - jump Test.199 #Derived_gen.201; + jump Test.199 Bool.222; else - jump Test.216 #Derived_gen.201; + jump Test.216 Bool.222; else - jump Test.216 #Derived_gen.201; + jump Test.216 Bool.222; in let Test.222 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.180; let Test.223 : U8 = 1i64; @@ -137,7 +137,7 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.221 : Int1 = true; let Test.226 : Int1 = lowlevel Eq Test.221 Test.220; if Test.226 then - joinpoint Test.207 #Derived_gen.206: + joinpoint Test.207 Bool.227: let Test.33 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.180; let Test.35 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180; let Test.200 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.180; @@ -148,26 +148,26 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): inc Test.39; let Test.37 : I32 = UnionAtIndex (Id 1) (Index 3) Test.200; let Test.34 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180; - joinpoint #Derived_gen.70 #Derived_gen.208 #Derived_gen.209 #Derived_gen.210: + joinpoint Bool.91 Bool.229 Bool.230 Bool.231: let Test.192 : Int1 = false; - let Test.189 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.210 UpdateModeId { id: 107 } TagId(1) Test.33 Test.35 Test.36 Test.34 Test.192; + let Test.189 : [C *self I64 *self I32 Int1, ] = Reuse Bool.231 UpdateModeId { id: 107 } TagId(1) Test.33 Test.35 Test.36 Test.34 Test.192; let Test.191 : Int1 = false; - let Test.190 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.209 UpdateModeId { id: 106 } TagId(1) Test.39 Test.18 Test.19 Test.17 Test.191; + let Test.190 : [C *self I64 *self I32 Int1, ] = Reuse Bool.230 UpdateModeId { id: 106 } TagId(1) Test.39 Test.18 Test.19 Test.17 Test.191; let Test.188 : Int1 = true; - let Test.187 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.208 UpdateModeId { id: 105 } TagId(1) Test.189 Test.38 Test.190 Test.37 Test.188; - let #Derived_gen.18 : {} = lowlevel PtrStore #Derived_gen.6 Test.187; - let #Derived_gen.17 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.17; + let Test.187 : [C *self I64 *self I32 Int1, ] = Reuse Bool.229 UpdateModeId { id: 105 } TagId(1) Test.189 Test.38 Test.190 Test.37 Test.188; + let Bool.39 : {} = lowlevel PtrStore Bool.27 Test.187; + let Bool.38 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.38; in - let #Derived_gen.71 : Int1 = lowlevel RefCountIsUnique Test.180; - if #Derived_gen.71 then - let #Derived_gen.211 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.200, id: UpdateModeId { id: 108 } }; - jump #Derived_gen.70 #Derived_gen.206 #Derived_gen.211 Test.180; + let Bool.92 : Int1 = lowlevel RefCountIsUnique Test.180; + if Bool.92 then + let Bool.232 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.200, id: UpdateModeId { id: 108 } }; + jump Bool.91 Bool.227 Bool.232 Test.180; else inc Test.33; decref Test.180; - let #Derived_gen.212 : [C *self I64 *self I32 Int1, ] = NullPointer; - jump #Derived_gen.70 #Derived_gen.212 #Derived_gen.212 #Derived_gen.206; + let Bool.233 : [C *self I64 *self I32 Int1, ] = NullPointer; + jump Bool.91 Bool.233 Bool.233 Bool.227; in let Test.204 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.180; let Test.205 : U8 = 1i64; @@ -179,36 +179,36 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.203 : Int1 = true; let Test.208 : Int1 = lowlevel Eq Test.203 Test.202; if Test.208 then - jump Test.199 #Derived_gen.118; + jump Test.199 Bool.139; else - jump Test.207 #Derived_gen.118; + jump Test.207 Bool.139; else - jump Test.207 #Derived_gen.118; + jump Test.207 Bool.139; else - jump Test.225 #Derived_gen.118; + jump Test.225 Bool.139; else - jump Test.225 #Derived_gen.118; + jump Test.225 Bool.139; else - decref #Derived_gen.118; + decref Bool.139; dec Test.19; let Test.197 : [C *self I64 *self I32 Int1, ] = TagId(0) ; - let #Derived_gen.20 : {} = lowlevel PtrStore #Derived_gen.6 Test.197; - let #Derived_gen.19 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.19; + let Bool.41 : {} = lowlevel PtrStore Bool.27 Test.197; + let Bool.40 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.40; else - jump Test.238 #Derived_gen.118; + jump Test.238 Bool.139; else - jump Test.238 #Derived_gen.118; + jump Test.238 Bool.139; else let Test.117 : Int1 = CallByName Num.24 Test.10 Test.17; if Test.117 then - joinpoint Test.176 #Derived_gen.288: + joinpoint Test.176 Bool.309: let Test.170 : Int1 = false; - let #Derived_gen.21 : [C *self I64 *self I32 Int1, ] = NullPointer; - let Test.169 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.288 UpdateModeId { id: 196 } TagId(1) Test.16 Test.18 #Derived_gen.21 Test.17 Test.170; - let #Derived_gen.22 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 2]) Test.169; - let #Derived_gen.23 : {} = lowlevel PtrStore #Derived_gen.6 Test.169; - jump #Derived_gen.5 Test.19 Test.10 Test.11 #Derived_gen.22 #Derived_gen.7; + let Bool.42 : [C *self I64 *self I32 Int1, ] = NullPointer; + let Test.169 : [C *self I64 *self I32 Int1, ] = Reuse Bool.309 UpdateModeId { id: 196 } TagId(1) Test.16 Test.18 Bool.42 Test.17 Test.170; + let Bool.43 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 2]) Test.169; + let Bool.44 : {} = lowlevel PtrStore Bool.27 Test.169; + jump Bool.26 Test.19 Test.10 Test.11 Bool.43 Bool.28; in let Test.174 : U8 = 1i64; let Test.175 : U8 = GetTagId Test.19; @@ -219,9 +219,9 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.177 : Int1 = lowlevel Eq Test.173 Test.172; if Test.177 then inc Test.19; - let #Derived_gen.289 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.16, id: UpdateModeId { id: 197 } }; + let Bool.310 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.16, id: UpdateModeId { id: 197 } }; let Test.118 : [C *self I64 *self I32 Int1, ] = CallByName Test.3 Test.19 Test.10 Test.11; - joinpoint Test.137 #Derived_gen.322 #Derived_gen.323: + joinpoint Test.137 Bool.343 Bool.344: let Test.136 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.118; let Test.57 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.136; inc Test.57; @@ -232,56 +232,56 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.62 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118; let Test.63 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.118; let Test.61 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118; - joinpoint #Derived_gen.112 #Derived_gen.326 #Derived_gen.327 #Derived_gen.328: + joinpoint Bool.133 Bool.347 Bool.348 Bool.349: let Test.124 : Int1 = false; - let Test.121 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.328 UpdateModeId { id: 242 } TagId(1) Test.57 Test.59 Test.60 Test.58 Test.124; + let Test.121 : [C *self I64 *self I32 Int1, ] = Reuse Bool.349 UpdateModeId { id: 242 } TagId(1) Test.57 Test.59 Test.60 Test.58 Test.124; let Test.123 : Int1 = false; - let Test.122 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.327 UpdateModeId { id: 241 } TagId(1) Test.63 Test.18 Test.19 Test.17 Test.123; + let Test.122 : [C *self I64 *self I32 Int1, ] = Reuse Bool.348 UpdateModeId { id: 241 } TagId(1) Test.63 Test.18 Test.19 Test.17 Test.123; let Test.120 : Int1 = true; - let Test.119 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.326 UpdateModeId { id: 240 } TagId(1) Test.121 Test.62 Test.122 Test.61 Test.120; - let #Derived_gen.25 : {} = lowlevel PtrStore #Derived_gen.6 Test.119; - let #Derived_gen.24 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.24; + let Test.119 : [C *self I64 *self I32 Int1, ] = Reuse Bool.347 UpdateModeId { id: 240 } TagId(1) Test.121 Test.62 Test.122 Test.61 Test.120; + let Bool.46 : {} = lowlevel PtrStore Bool.27 Test.119; + let Bool.45 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.45; in - let #Derived_gen.113 : Int1 = lowlevel RefCountIsUnique Test.118; - if #Derived_gen.113 then - decref #Derived_gen.322; - let #Derived_gen.329 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.136, id: UpdateModeId { id: 243 } }; - jump #Derived_gen.112 #Derived_gen.323 #Derived_gen.329 Test.118; + let Bool.134 : Int1 = lowlevel RefCountIsUnique Test.118; + if Bool.134 then + decref Bool.343; + let Bool.350 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.136, id: UpdateModeId { id: 243 } }; + jump Bool.133 Bool.344 Bool.350 Test.118; else inc Test.63; decref Test.118; - let #Derived_gen.330 : [C *self I64 *self I32 Int1, ] = NullPointer; - jump #Derived_gen.112 #Derived_gen.330 #Derived_gen.322 #Derived_gen.323; + let Bool.351 : [C *self I64 *self I32 Int1, ] = NullPointer; + jump Bool.133 Bool.351 Bool.343 Bool.344; in let Test.166 : U8 = 1i64; let Test.167 : U8 = GetTagId Test.118; let Test.168 : Int1 = lowlevel Eq Test.166 Test.167; if Test.168 then - joinpoint Test.163 #Derived_gen.340 #Derived_gen.341: - joinpoint Test.154 #Derived_gen.342 #Derived_gen.343: + joinpoint Test.163 Bool.361 Bool.362: + joinpoint Test.154 Bool.363 Bool.364: let Test.83 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.118; let Test.85 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118; let Test.86 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.118; let Test.84 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118; - joinpoint #Derived_gen.102 #Derived_gen.345 #Derived_gen.346: + joinpoint Bool.123 Bool.366 Bool.367: let Test.134 : Int1 = true; - let Test.133 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.346 UpdateModeId { id: 262 } TagId(1) Test.83 Test.85 Test.86 Test.84 Test.134; + let Test.133 : [C *self I64 *self I32 Int1, ] = Reuse Bool.367 UpdateModeId { id: 262 } TagId(1) Test.83 Test.85 Test.86 Test.84 Test.134; let Test.132 : Int1 = false; - let Test.131 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.345 UpdateModeId { id: 261 } TagId(1) Test.133 Test.18 Test.19 Test.17 Test.132; - let #Derived_gen.27 : {} = lowlevel PtrStore #Derived_gen.6 Test.131; - let #Derived_gen.26 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.26; + let Test.131 : [C *self I64 *self I32 Int1, ] = Reuse Bool.366 UpdateModeId { id: 261 } TagId(1) Test.133 Test.18 Test.19 Test.17 Test.132; + let Bool.48 : {} = lowlevel PtrStore Bool.27 Test.131; + let Bool.47 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.47; in - let #Derived_gen.103 : Int1 = lowlevel RefCountIsUnique Test.118; - if #Derived_gen.103 then - decref #Derived_gen.342; - jump #Derived_gen.102 #Derived_gen.343 Test.118; + let Bool.124 : Int1 = lowlevel RefCountIsUnique Test.118; + if Bool.124 then + decref Bool.363; + jump Bool.123 Bool.364 Test.118; else inc Test.83; inc Test.86; decref Test.118; - jump #Derived_gen.102 #Derived_gen.342 #Derived_gen.343; + jump Bool.123 Bool.363 Bool.364; in let Test.151 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.118; let Test.152 : U8 = 1i64; @@ -293,11 +293,11 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.150 : Int1 = true; let Test.155 : Int1 = lowlevel Eq Test.150 Test.149; if Test.155 then - jump Test.137 #Derived_gen.340 #Derived_gen.341; + jump Test.137 Bool.361 Bool.362; else - jump Test.154 #Derived_gen.340 #Derived_gen.341; + jump Test.154 Bool.361 Bool.362; else - jump Test.154 #Derived_gen.340 #Derived_gen.341; + jump Test.154 Bool.361 Bool.362; in let Test.160 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.118; let Test.161 : U8 = 1i64; @@ -309,7 +309,7 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.159 : Int1 = true; let Test.164 : Int1 = lowlevel Eq Test.159 Test.158; if Test.164 then - joinpoint Test.145 #Derived_gen.347 #Derived_gen.348: + joinpoint Test.145 Bool.368 Bool.369: let Test.70 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.118; let Test.72 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118; let Test.138 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.118; @@ -320,27 +320,27 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): inc Test.76; let Test.74 : I32 = UnionAtIndex (Id 1) (Index 3) Test.138; let Test.71 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118; - joinpoint #Derived_gen.106 #Derived_gen.351 #Derived_gen.352 #Derived_gen.353: + joinpoint Bool.127 Bool.372 Bool.373 Bool.374: let Test.130 : Int1 = false; - let Test.127 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.353 UpdateModeId { id: 271 } TagId(1) Test.70 Test.72 Test.73 Test.71 Test.130; + let Test.127 : [C *self I64 *self I32 Int1, ] = Reuse Bool.374 UpdateModeId { id: 271 } TagId(1) Test.70 Test.72 Test.73 Test.71 Test.130; let Test.129 : Int1 = false; - let Test.128 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.352 UpdateModeId { id: 270 } TagId(1) Test.76 Test.18 Test.19 Test.17 Test.129; + let Test.128 : [C *self I64 *self I32 Int1, ] = Reuse Bool.373 UpdateModeId { id: 270 } TagId(1) Test.76 Test.18 Test.19 Test.17 Test.129; let Test.126 : Int1 = true; - let Test.125 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.351 UpdateModeId { id: 269 } TagId(1) Test.127 Test.75 Test.128 Test.74 Test.126; - let #Derived_gen.29 : {} = lowlevel PtrStore #Derived_gen.6 Test.125; - let #Derived_gen.28 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.28; + let Test.125 : [C *self I64 *self I32 Int1, ] = Reuse Bool.372 UpdateModeId { id: 269 } TagId(1) Test.127 Test.75 Test.128 Test.74 Test.126; + let Bool.50 : {} = lowlevel PtrStore Bool.27 Test.125; + let Bool.49 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.49; in - let #Derived_gen.107 : Int1 = lowlevel RefCountIsUnique Test.118; - if #Derived_gen.107 then - decref #Derived_gen.347; - let #Derived_gen.354 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.138, id: UpdateModeId { id: 272 } }; - jump #Derived_gen.106 #Derived_gen.348 #Derived_gen.354 Test.118; + let Bool.128 : Int1 = lowlevel RefCountIsUnique Test.118; + if Bool.128 then + decref Bool.368; + let Bool.375 : [C *self I64 *self I32 Int1, ] = Reset { symbol: Test.138, id: UpdateModeId { id: 272 } }; + jump Bool.127 Bool.369 Bool.375 Test.118; else inc Test.70; decref Test.118; - let #Derived_gen.355 : [C *self I64 *self I32 Int1, ] = NullPointer; - jump #Derived_gen.106 #Derived_gen.355 #Derived_gen.347 #Derived_gen.348; + let Bool.376 : [C *self I64 *self I32 Int1, ] = NullPointer; + jump Bool.127 Bool.376 Bool.368 Bool.369; in let Test.142 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.118; let Test.143 : U8 = 1i64; @@ -352,96 +352,96 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.141 : Int1 = true; let Test.146 : Int1 = lowlevel Eq Test.141 Test.140; if Test.146 then - jump Test.137 #Derived_gen.118 #Derived_gen.289; + jump Test.137 Bool.139 Bool.310; else - jump Test.145 #Derived_gen.118 #Derived_gen.289; + jump Test.145 Bool.139 Bool.310; else - jump Test.145 #Derived_gen.118 #Derived_gen.289; + jump Test.145 Bool.139 Bool.310; else - jump Test.163 #Derived_gen.118 #Derived_gen.289; + jump Test.163 Bool.139 Bool.310; else - jump Test.163 #Derived_gen.118 #Derived_gen.289; + jump Test.163 Bool.139 Bool.310; else - decref #Derived_gen.289; - decref #Derived_gen.118; - joinpoint #Derived_gen.108: + decref Bool.310; + decref Bool.139; + joinpoint Bool.129: let Test.135 : [C *self I64 *self I32 Int1, ] = TagId(0) ; - let #Derived_gen.31 : {} = lowlevel PtrStore #Derived_gen.6 Test.135; - let #Derived_gen.30 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.30; + let Bool.52 : {} = lowlevel PtrStore Bool.27 Test.135; + let Bool.51 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.51; in - let #Derived_gen.111 : Int1 = lowlevel RefCountIsUnique Test.19; - if #Derived_gen.111 then - let #Derived_gen.110 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.19; - dec #Derived_gen.110; - let #Derived_gen.109 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.19; - dec #Derived_gen.109; + let Bool.132 : Int1 = lowlevel RefCountIsUnique Test.19; + if Bool.132 then + let Bool.131 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.19; + dec Bool.131; + let Bool.130 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.19; + dec Bool.130; free Test.19; - jump #Derived_gen.108; + jump Bool.129; else decref Test.19; - jump #Derived_gen.108; + jump Bool.129; else - jump Test.176 #Derived_gen.118; + jump Test.176 Bool.139; else - jump Test.176 #Derived_gen.118; + jump Test.176 Bool.139; else let Test.116 : Int1 = false; - let Test.115 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.118 UpdateModeId { id: 1 } TagId(1) Test.16 Test.11 Test.19 Test.10 Test.116; - let #Derived_gen.33 : {} = lowlevel PtrStore #Derived_gen.6 Test.115; - let #Derived_gen.32 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.32; + let Test.115 : [C *self I64 *self I32 Int1, ] = Reuse Bool.139 UpdateModeId { id: 1 } TagId(1) Test.16 Test.11 Test.19 Test.10 Test.116; + let Bool.54 : {} = lowlevel PtrStore Bool.27 Test.115; + let Bool.53 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.53; in - let #Derived_gen.115 : Int1 = lowlevel RefCountIsUnique Test.9; - if #Derived_gen.115 then - jump #Derived_gen.114 Test.9; + let Bool.136 : Int1 = lowlevel RefCountIsUnique Test.9; + if Bool.136 then + jump Bool.135 Test.9; else inc Test.16; inc Test.19; decref Test.9; - let #Derived_gen.363 : [C *self I64 *self I32 Int1, ] = NullPointer; - jump #Derived_gen.114 #Derived_gen.363; + let Bool.384 : [C *self I64 *self I32 Int1, ] = NullPointer; + jump Bool.135 Bool.384; else let Test.96 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 0) Test.9; let Test.98 : I64 = UnionAtIndex (Id 1) (Index 1) Test.9; let Test.99 : [C *self I64 *self I32 Int1, ] = UnionAtIndex (Id 1) (Index 2) Test.9; let Test.97 : I32 = UnionAtIndex (Id 1) (Index 3) Test.9; - joinpoint #Derived_gen.116 #Derived_gen.364: + joinpoint Bool.137 Bool.385: let Test.247 : Int1 = CallByName Num.22 Test.10 Test.97; if Test.247 then let Test.249 : Int1 = true; - let #Derived_gen.34 : [C *self I64 *self I32 Int1, ] = NullPointer; - let Test.248 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.364 UpdateModeId { id: 284 } TagId(1) #Derived_gen.34 Test.98 Test.99 Test.97 Test.249; - let #Derived_gen.35 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 0]) Test.248; - let #Derived_gen.36 : {} = lowlevel PtrStore #Derived_gen.6 Test.248; - jump #Derived_gen.5 Test.96 Test.10 Test.11 #Derived_gen.35 #Derived_gen.7; + let Bool.55 : [C *self I64 *self I32 Int1, ] = NullPointer; + let Test.248 : [C *self I64 *self I32 Int1, ] = Reuse Bool.385 UpdateModeId { id: 284 } TagId(1) Bool.55 Test.98 Test.99 Test.97 Test.249; + let Bool.56 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 0]) Test.248; + let Bool.57 : {} = lowlevel PtrStore Bool.27 Test.248; + jump Bool.26 Test.96 Test.10 Test.11 Bool.56 Bool.28; else let Test.243 : Int1 = CallByName Num.24 Test.10 Test.97; if Test.243 then let Test.245 : Int1 = true; - let #Derived_gen.37 : [C *self I64 *self I32 Int1, ] = NullPointer; - let Test.244 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.364 UpdateModeId { id: 284 } TagId(1) Test.96 Test.98 #Derived_gen.37 Test.97 Test.245; - let #Derived_gen.38 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 2]) Test.244; - let #Derived_gen.39 : {} = lowlevel PtrStore #Derived_gen.6 Test.244; - jump #Derived_gen.5 Test.99 Test.10 Test.11 #Derived_gen.38 #Derived_gen.7; + let Bool.58 : [C *self I64 *self I32 Int1, ] = NullPointer; + let Test.244 : [C *self I64 *self I32 Int1, ] = Reuse Bool.385 UpdateModeId { id: 284 } TagId(1) Test.96 Test.98 Bool.58 Test.97 Test.245; + let Bool.59 : Ptr([C *self I64 *self I32 Int1, ]) = GetElementPointer (Indices [1, 2]) Test.244; + let Bool.60 : {} = lowlevel PtrStore Bool.27 Test.244; + jump Bool.26 Test.99 Test.10 Test.11 Bool.59 Bool.28; else let Test.242 : Int1 = true; - let Test.241 : [C *self I64 *self I32 Int1, ] = Reuse #Derived_gen.364 UpdateModeId { id: 284 } TagId(1) Test.96 Test.11 Test.99 Test.10 Test.242; - let #Derived_gen.41 : {} = lowlevel PtrStore #Derived_gen.6 Test.241; - let #Derived_gen.40 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad #Derived_gen.7; - ret #Derived_gen.40; + let Test.241 : [C *self I64 *self I32 Int1, ] = Reuse Bool.385 UpdateModeId { id: 284 } TagId(1) Test.96 Test.11 Test.99 Test.10 Test.242; + let Bool.62 : {} = lowlevel PtrStore Bool.27 Test.241; + let Bool.61 : [C *self I64 *self I32 Int1, ] = lowlevel PtrLoad Bool.28; + ret Bool.61; in - let #Derived_gen.117 : Int1 = lowlevel RefCountIsUnique Test.9; - if #Derived_gen.117 then - jump #Derived_gen.116 Test.9; + let Bool.138 : Int1 = lowlevel RefCountIsUnique Test.9; + if Bool.138 then + jump Bool.137 Test.9; else inc Test.96; inc Test.99; decref Test.9; - let #Derived_gen.365 : [C *self I64 *self I32 Int1, ] = NullPointer; - jump #Derived_gen.116 #Derived_gen.365; + let Bool.386 : [C *self I64 *self I32 Int1, ] = NullPointer; + jump Bool.137 Bool.386; in - jump #Derived_gen.5 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.3; + jump Bool.26 Bool.21 Bool.22 Bool.23 Bool.24 Bool.24; procedure Test.0 (): let Test.281 : [C *self I64 *self I32 Int1, ] = TagId(0) ; 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 9a4602f6df9..48374eaaf4b 100644 --- a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt +++ b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt @@ -11,7 +11,7 @@ procedure Test.1 (Test.2): let Test.7 : U32 = CallByName Test.3 Test.8 Test.2; ret Test.7; -procedure Test.3 (#Derived_gen.0, #Derived_gen.1): +procedure Test.3 (Bool.22, Bool.23): joinpoint Test.9 Test.4 Test.2: let Test.13 : Int1 = CallByName Bool.2; if Test.13 then @@ -20,7 +20,7 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1): let Test.11 : U32 = CallByName Num.19 Test.4 Test.2; jump Test.9 Test.11 Test.2; in - jump Test.9 #Derived_gen.0 #Derived_gen.1; + jump Test.9 Bool.22 Bool.23; procedure Test.0 (): let Test.6 : U32 = 6i64; diff --git a/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt b/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt index 71447c05e3a..16d4ea4ee58 100644 --- a/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt +++ b/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt @@ -1,4 +1,4 @@ -procedure List.101 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4, #Derived_gen.5): +procedure List.101 (Bool.22, Bool.23, Bool.24, Bool.25, Bool.26): joinpoint List.681 List.175 List.176 List.177 List.178 List.179: let List.683 : Int1 = CallByName Num.22 List.178 List.179; if List.683 then @@ -12,8 +12,8 @@ procedure List.101 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen dec List.175; ret List.176; in - inc #Derived_gen.1; - jump List.681 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5; + inc Bool.22; + jump List.681 Bool.22 Bool.23 Bool.24 Bool.25 Bool.26; procedure List.18 (List.172, List.173, List.174): let List.679 : U64 = 0i64; @@ -59,11 +59,11 @@ procedure Num.51 (#Attr.2, #Attr.3): procedure Test.2 (Test.5): let Test.6 : List [C List *self] = UnionAtIndex (Id 0) (Index 0) Test.5; inc Test.6; - let #Derived_gen.9 : [C List *self] = Reset { symbol: Test.5, id: UpdateModeId { id: 0 } }; + let Bool.30 : [C List *self] = Reset { symbol: Test.5, id: UpdateModeId { id: 0 } }; let Test.15 : {} = Struct {}; let Test.7 : List [C List *self] = CallByName List.5 Test.6 Test.15; dec Test.6; - let Test.14 : [C List *self] = Reuse #Derived_gen.9 UpdateModeId { id: 0 } TagId(0) Test.7; + let Test.14 : [C List *self] = Reuse Bool.30 UpdateModeId { id: 0 } TagId(0) Test.7; ret Test.14; procedure Test.0 (): diff --git a/crates/compiler/test_mono/generated/recursive_lambda_set_has_nested_non_recursive_lambda_sets_issue_5026.txt b/crates/compiler/test_mono/generated/recursive_lambda_set_has_nested_non_recursive_lambda_sets_issue_5026.txt index a7b9fabce8d..351b4ea3c4c 100644 --- a/crates/compiler/test_mono/generated/recursive_lambda_set_has_nested_non_recursive_lambda_sets_issue_5026.txt +++ b/crates/compiler/test_mono/generated/recursive_lambda_set_has_nested_non_recursive_lambda_sets_issue_5026.txt @@ -25,7 +25,7 @@ procedure Test.3 (Test.7): procedure Test.6 (Test.16, #Attr.12): let Test.23 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12; - joinpoint #Derived_gen.2: + joinpoint Bool.24: let Test.19 : {} = Struct {}; let Test.22 : Str = "foobar"; let Test.20 : [, C {}] = CallByName Test.8 Test.22 Test.23; @@ -42,13 +42,13 @@ procedure Test.6 (Test.16, #Attr.12): ret Test.18; in - let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.3 then + let Bool.25 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.25 then free #Attr.12; - jump #Derived_gen.2; + jump Bool.24; else decref #Attr.12; - jump #Derived_gen.2; + jump Bool.24; procedure Test.8 (Test.9, Test.7): let Test.25 : [, C {}] = CallByName Test.10 Test.9; 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 171dc4d4a0f..93a4073b3da 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 @@ -10,7 +10,7 @@ procedure Num.21 (#Attr.2, #Attr.3): let Num.283 : U8 = lowlevel NumMul #Attr.2 #Attr.3; ret Num.283; -procedure Test.1 (#Derived_gen.0, #Derived_gen.1): +procedure Test.1 (Bool.22, Bool.23): joinpoint Test.11 Test.2 Test.3: let Test.26 : U8 = 0i64; let Test.22 : Int1 = CallByName Bool.9 Test.2 Test.26; @@ -33,13 +33,13 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1): let Test.14 : [, C *self U8] = TagId(0) Test.3 Test.2; jump Test.11 Test.13 Test.14; in - jump Test.11 #Derived_gen.0 #Derived_gen.1; + jump Test.11 Bool.22 Bool.23; -procedure Test.4 (#Derived_gen.2, #Derived_gen.3): +procedure Test.4 (Bool.24, Bool.25): joinpoint Test.15 Test.5 #Attr.12: let Test.20 : U8 = UnionAtIndex (Id 0) (Index 1) #Attr.12; let Test.19 : [, C *self U8] = UnionAtIndex (Id 0) (Index 0) #Attr.12; - joinpoint #Derived_gen.4: + joinpoint Bool.26: let Test.17 : U8 = CallByName Num.21 Test.20 Test.5; let Test.18 : U8 = GetTagId Test.19; switch Test.18: @@ -52,16 +52,16 @@ procedure Test.4 (#Derived_gen.2, #Derived_gen.3): ret Test.16; in - let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.5 then + let Bool.27 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.27 then free #Attr.12; - jump #Derived_gen.4; + jump Bool.26; else inc Test.19; decref #Attr.12; - jump #Derived_gen.4; + jump Bool.26; in - jump Test.15 #Derived_gen.2 #Derived_gen.3; + jump Test.15 Bool.24 Bool.25; procedure Test.6 (Test.7): ret Test.7; diff --git a/crates/compiler/test_mono/generated/recursively_build_effect.txt b/crates/compiler/test_mono/generated/recursively_build_effect.txt index f43506bad37..0efce924608 100644 --- a/crates/compiler/test_mono/generated/recursively_build_effect.txt +++ b/crates/compiler/test_mono/generated/recursively_build_effect.txt @@ -8,8 +8,8 @@ procedure Str.3 (#Attr.2, #Attr.3): procedure Test.11 (Test.29, #Attr.12): let Test.32 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12; - let #Derived_gen.9 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.9 then + let Bool.30 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.30 then free #Attr.12; ret Test.32; else @@ -19,11 +19,11 @@ procedure Test.11 (Test.29, #Attr.12): procedure Test.11 (Test.29, Test.10): ret Test.10; -procedure Test.14 (#Derived_gen.7, #Derived_gen.8): +procedure Test.14 (Bool.28, Bool.29): joinpoint Test.38 Test.37 #Attr.12: let Test.46 : {} = UnionAtIndex (Id 1) (Index 1) #Attr.12; let Test.45 : I64 = UnionAtIndex (Id 1) (Index 0) #Attr.12; - joinpoint #Derived_gen.10: + joinpoint Bool.31: let Test.44 : {} = Struct {}; let Test.43 : {} = CallByName Test.11 Test.44 Test.46; let Test.39 : [C {}, C I64 {}] = CallByName Test.9 Test.43 Test.45; @@ -38,15 +38,15 @@ procedure Test.14 (#Derived_gen.7, #Derived_gen.8): jump Test.38 Test.41 Test.39; in - let #Derived_gen.11 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.11 then + let Bool.32 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if Bool.32 then free #Attr.12; - jump #Derived_gen.10; + jump Bool.31; else decref #Attr.12; - jump #Derived_gen.10; + jump Bool.31; in - jump Test.38 #Derived_gen.7 #Derived_gen.8; + jump Test.38 Bool.28 Bool.29; procedure Test.2 (): let Test.6 : Str = "Hello"; diff --git a/crates/compiler/test_mono/generated/specialize_after_match.txt b/crates/compiler/test_mono/generated/specialize_after_match.txt index 474578aa329..a6f696ca355 100644 --- a/crates/compiler/test_mono/generated/specialize_after_match.txt +++ b/crates/compiler/test_mono/generated/specialize_after_match.txt @@ -23,7 +23,7 @@ procedure Test.2 (Test.9, Test.10): let Test.29 : U64 = CallByName Test.3 Test.9; ret Test.29; else - joinpoint #Derived_gen.4: + joinpoint Bool.25: let Test.13 : Str = UnionAtIndex (Id 0) (Index 0) Test.10; let Test.14 : [, C Str *self] = UnionAtIndex (Id 0) (Index 1) Test.10; let Test.33 : U64 = CallByName Test.3 Test.12; @@ -36,15 +36,15 @@ procedure Test.2 (Test.9, Test.10): else ret Test.16; in - let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.9; - if #Derived_gen.5 then + let Bool.26 : Int1 = lowlevel RefCountIsUnique Test.9; + if Bool.26 then dec Test.11; free Test.9; - jump #Derived_gen.4; + jump Bool.25; else inc Test.12; decref Test.9; - jump #Derived_gen.4; + jump Bool.25; procedure Test.3 (Test.17): let Test.26 : U8 = 1i64; @@ -55,22 +55,22 @@ procedure Test.3 (Test.17): ret Test.22; else let Test.18 : [, C Str *self] = UnionAtIndex (Id 0) (Index 1) Test.17; - joinpoint #Derived_gen.1: + joinpoint Bool.22: let Test.24 : U64 = 1i64; let Test.25 : U64 = CallByName Test.3 Test.18; let Test.23 : U64 = CallByName Num.19 Test.24 Test.25; ret Test.23; in - let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique Test.17; - if #Derived_gen.3 then - let #Derived_gen.2 : Str = UnionAtIndex (Id 0) (Index 0) Test.17; - dec #Derived_gen.2; + let Bool.24 : Int1 = lowlevel RefCountIsUnique Test.17; + if Bool.24 then + let Bool.23 : Str = UnionAtIndex (Id 0) (Index 0) Test.17; + dec Bool.23; free Test.17; - jump #Derived_gen.1; + jump Bool.22; else inc Test.18; decref Test.17; - jump #Derived_gen.1; + jump Bool.22; procedure Test.0 (): let Test.5 : [, C Str *self] = TagId(1) ; diff --git a/crates/compiler/test_mono/generated/tail_call_elimination.txt b/crates/compiler/test_mono/generated/tail_call_elimination.txt index f86a668bc74..7ab2d53bdee 100644 --- a/crates/compiler/test_mono/generated/tail_call_elimination.txt +++ b/crates/compiler/test_mono/generated/tail_call_elimination.txt @@ -6,7 +6,7 @@ procedure Num.20 (#Attr.2, #Attr.3): let Num.284 : I64 = lowlevel NumSub #Attr.2 #Attr.3; ret Num.284; -procedure Test.1 (#Derived_gen.0, #Derived_gen.1): +procedure Test.1 (Bool.21, Bool.22): joinpoint Test.7 Test.2 Test.3: let Test.13 : I64 = 0i64; let Test.14 : Int1 = lowlevel Eq Test.13 Test.2; @@ -18,7 +18,7 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1): let Test.11 : I64 = CallByName Num.19 Test.2 Test.3; jump Test.7 Test.10 Test.11; in - jump Test.7 #Derived_gen.0 #Derived_gen.1; + jump Test.7 Bool.21 Bool.22; procedure Test.0 (): let Test.5 : I64 = 1000000i64; diff --git a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification.txt b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification.txt index b6030ae6710..af84f979691 100644 --- a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification.txt +++ b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification.txt @@ -59,8 +59,8 @@ procedure Test.43 (Test.44, Test.42): jump Test.62 Test.61; else let Test.69 : U8 = StructAtIndex 1 Test.42; - let #Derived_gen.5 : Str = StructAtIndex 0 Test.42; - dec #Derived_gen.5; + let Bool.27 : Str = StructAtIndex 0 Test.42; + dec Bool.27; let Test.63 : Int1 = CallByName Test.15 Test.69; let Test.61 : Int1 = CallByName Test.14 Test.63; jump Test.62 Test.61; diff --git a/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt b/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt index c9a38f87699..cd802d2c8cd 100644 --- a/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt +++ b/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt @@ -51,7 +51,7 @@ procedure List.72 (#Attr.2, #Attr.3, #Attr.4): let List.681 : List U8 = lowlevel ListSublist #Attr.2 #Attr.3 #Attr.4; ret List.681; -procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4): +procedure List.80 (Bool.22, Bool.23, Bool.24, Bool.25, Bool.26): joinpoint List.695 List.566 List.567 List.568 List.569 List.570: let List.697 : Int1 = CallByName Num.22 List.569 List.570; if List.697 then @@ -75,8 +75,8 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen. let List.696 : [C U64, C U64] = TagId(1) List.567; ret List.696; in - inc #Derived_gen.0; - jump List.695 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; + inc Bool.22; + jump List.695 Bool.22 Bool.23 Bool.24 Bool.25 Bool.26; procedure Num.22 (#Attr.2, #Attr.3): let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; diff --git a/crates/compiler/test_syntax/Cargo.toml b/crates/compiler/test_syntax/Cargo.toml index 309c14dfe64..441ce507e15 100644 --- a/crates/compiler/test_syntax/Cargo.toml +++ b/crates/compiler/test_syntax/Cargo.toml @@ -13,6 +13,7 @@ version.workspace = true [dependencies] bumpalo.workspace = true roc_can.workspace = true +roc_can_solo.workspace = true roc_collections.workspace = true roc_error_macros.workspace = true roc_fmt.workspace = true diff --git a/crates/compiler/test_syntax/src/test_helpers.rs b/crates/compiler/test_syntax/src/test_helpers.rs index 4e1d5d55a2b..11e1171d125 100644 --- a/crates/compiler/test_syntax/src/test_helpers.rs +++ b/crates/compiler/test_syntax/src/test_helpers.rs @@ -1,10 +1,11 @@ use std::path::Path; use bumpalo::Bump; -use roc_can::desugar; use roc_can::env::Env; use roc_can::expr::canonicalize_expr; use roc_can::scope::Scope; +use roc_can_solo::env::SoloEnv; +use roc_can_solo::scope::SoloScope; use roc_error_macros::set_panic_not_exit; use roc_fmt::{annotation::Formattable, header::fmt_header, MigrationFlags}; use roc_module::ident::QualifiedModuleName; @@ -217,7 +218,10 @@ impl<'a> Output<'a> { // visited a BinOp node we'd recursively try to apply this to each of its nested // operators, and then again on *their* nested operators, ultimately applying the // rules multiple times unnecessarily. - let loc_expr = desugar::desugar_expr(&mut env, &mut scope, loc_expr); + let mut solo_env = SoloEnv::new(arena, src, Path::new("Test.roc")); + let mut solo_scope = SoloScope::new(); + let loc_expr = + roc_can_solo::desugar::desugar_expr(&mut solo_env, &mut solo_scope, loc_expr); scope.add_alias( Symbol::NUM_INT, diff --git a/crates/compiler/uitest/tests/lambda_set/erased/multi_branch_capturing.txt b/crates/compiler/uitest/tests/lambda_set/erased/multi_branch_capturing.txt index 93ec6845b2e..816122749f3 100644 --- a/crates/compiler/uitest/tests/lambda_set/erased/multi_branch_capturing.txt +++ b/crates/compiler/uitest/tests/lambda_set/erased/multi_branch_capturing.txt @@ -38,18 +38,18 @@ procedure Test.3 (Test.36): procedure Test.4 (Test.27, #Attr.12): let Test.29 : [, C {Str}] = ErasedLoad #Attr.12 .Value; let Test.30 : {Str} = UnionAtIndex (Id 0) (Index 0) Test.29; - joinpoint #Derived_gen.0: + joinpoint Bool.22: let Test.2 : Str = StructAtIndex 0 Test.30; ret Test.2; in - let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.29; - if #Derived_gen.1 then + let Bool.23 : Int1 = lowlevel RefCountIsUnique Test.29; + if Bool.23 then free Test.29; - jump #Derived_gen.0; + jump Bool.22; else inc Test.30; decref Test.29; - jump #Derived_gen.0; + jump Bool.22; procedure Test.0 (): let Test.6 : {} = Struct {}; diff --git a/crates/compiler/uitest/tests/specialize/record_update_between_modules.txt b/crates/compiler/uitest/tests/specialize/record_update_between_modules.txt index f9164a7a8f7..627c7ba911c 100644 --- a/crates/compiler/uitest/tests/specialize/record_update_between_modules.txt +++ b/crates/compiler/uitest/tests/specialize/record_update_between_modules.txt @@ -25,8 +25,8 @@ procedure Dep.0 (): procedure Test.0 (): let Test.6 : {Str, Str} = CallByName Dep.0; let Test.3 : Str = StructAtIndex 0 Test.6; - let #Derived_gen.0 : Str = StructAtIndex 1 Test.6; - dec #Derived_gen.0; + let Bool.21 : Str = StructAtIndex 1 Test.6; + dec Bool.21; let Test.5 : Str = "http://www.example.com"; let Test.2 : {Str, Str} = Struct {Test.3, Test.5}; ret Test.2; diff --git a/crates/compiler/work/src/work.rs b/crates/compiler/work/src/work.rs index 825467dd793..ad1647c4715 100644 --- a/crates/compiler/work/src/work.rs +++ b/crates/compiler/work/src/work.rs @@ -12,6 +12,7 @@ use std::collections::hash_map::Entry; pub enum Phase { LoadHeader, Parse, + SoloCanonicalize, CanonicalizeAndConstrain, SolveTypes, FindSpecializations, @@ -19,9 +20,10 @@ pub enum Phase { } /// NOTE keep up to date manually, from ParseAndGenerateConstraints to the highest phase we support -const PHASES: [Phase; 6] = [ +const PHASES: [Phase; 7] = [ Phase::LoadHeader, Phase::Parse, + Phase::SoloCanonicalize, Phase::CanonicalizeAndConstrain, Phase::SolveTypes, Phase::FindSpecializations, diff --git a/crates/test_compile/Cargo.toml b/crates/test_compile/Cargo.toml index 2fc0a624057..0b47fff78df 100644 --- a/crates/test_compile/Cargo.toml +++ b/crates/test_compile/Cargo.toml @@ -15,6 +15,7 @@ roc_collections.workspace = true roc_load.workspace = true roc_parse.workspace = true roc_can.workspace = true +roc_can_solo.workspace = true roc_module.workspace = true roc_types.workspace = true roc_problem.workspace = true diff --git a/crates/test_compile/src/help_can.rs b/crates/test_compile/src/help_can.rs index a743eee127d..2ed8e000b4a 100644 --- a/crates/test_compile/src/help_can.rs +++ b/crates/test_compile/src/help_can.rs @@ -1,11 +1,12 @@ use crate::help_parse::ParseExpr; use bumpalo::Bump; use roc_can::{ - desugar, env::Env, expr::{canonicalize_expr, Expr, Output}, scope::Scope, }; +use roc_can_solo::env::SoloEnv; +use roc_can_solo::scope::SoloScope; use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, PackageModuleIds, Symbol}; use roc_problem::can::Problem; use roc_region::all::{Loc, Region}; @@ -80,7 +81,10 @@ impl CanExpr { // visited a BinOp node we'd recursively try to apply this to each of its nested // operators, and then again on *their* nested operators, ultimately applying the // rules multiple times unnecessarily. - let loc_expr = desugar::desugar_expr(&mut env, &mut scope, &loc_expr); + let mut solo_env = SoloEnv::new(self.arena(), input, Path::new("Test.roc")); + let mut solo_scope = SoloScope::new(); + let loc_expr = + roc_can_solo::desugar::desugar_expr(&mut solo_env, &mut solo_scope, &loc_expr); scope.add_alias( Symbol::NUM_INT,