diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index 2f964bfce4..92da76a01a 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -1660,8 +1660,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( builder.build_load(tag_id_pointer.into_pointer_value(), "load_tag_id") } UnionLayout::Recursive(_) => { - let pointer = builder.build_alloca(argument.get_type(), "get_type"); - builder.build_store(pointer, argument); + let pointer = argument.into_pointer_value(); let tag_id_pointer = builder.build_bitcast( pointer, env.context.i64_type().ptr_type(AddressSpace::Generic), diff --git a/compiler/mono/src/decision_tree.rs b/compiler/mono/src/decision_tree.rs index 055281f7dc..c8be7b874f 100644 --- a/compiler/mono/src/decision_tree.rs +++ b/compiler/mono/src/decision_tree.rs @@ -1161,58 +1161,45 @@ fn test_to_equality<'a>( Layout<'a>, Option>, ) { - let (rhs_symbol, mut stores, _layout) = + let (rhs_symbol, mut stores, test_layout) = path_to_expr_help(env, cond_symbol, &path, *cond_layout); match test { - Test::IsCtor { - tag_id, - union, - arguments, - .. - } => { + Test::IsCtor { tag_id, union, .. } => { let path_symbol = rhs_symbol; // the IsCtor check should never be generated for tag unions of size 1 // (e.g. record pattern guard matches) debug_assert!(union.alternatives.len() > 1); - let lhs = Expr::Literal(Literal::Int(tag_id as i128)); + match test_layout { + Layout::Union(union_layout) => { + let lhs = Expr::Literal(Literal::Int(tag_id as i128)); - let mut field_layouts = - bumpalo::collections::Vec::with_capacity_in(arguments.len(), env.arena); + let rhs = Expr::GetTagId { + structure: path_symbol, + union_layout, + }; - // add the tag discriminant - field_layouts.push(Layout::Builtin(Builtin::Int64)); + let lhs_symbol = env.unique_symbol(); + let rhs_symbol = env.unique_symbol(); - for (_, layout) in arguments { - field_layouts.push(layout); + stores.push((lhs_symbol, Layout::Builtin(Builtin::Int64), lhs)); + stores.push((rhs_symbol, Layout::Builtin(Builtin::Int64), rhs)); + + ( + stores, + lhs_symbol, + rhs_symbol, + Layout::Builtin(Builtin::Int64), + Some(ConstructorKnown::OnlyPass { + scrutinee: path_symbol, + layout: *cond_layout, + tag_id, + }), + ) + } + _ => unreachable!("{:?}", (cond_layout, union)), } - let field_layouts = field_layouts.into_bump_slice(); - - let rhs = Expr::AccessAtIndex { - index: 0, - field_layouts, - structure: path_symbol, - wrapped: Wrapped::MultiTagUnion, - }; - - let lhs_symbol = env.unique_symbol(); - let rhs_symbol = env.unique_symbol(); - - stores.push((lhs_symbol, Layout::Builtin(Builtin::Int64), lhs)); - stores.push((rhs_symbol, Layout::Builtin(Builtin::Int64), rhs)); - - ( - stores, - lhs_symbol, - rhs_symbol, - Layout::Builtin(Builtin::Int64), - Some(ConstructorKnown::OnlyPass { - scrutinee: path_symbol, - layout: *cond_layout, - tag_id, - }), - ) } Test::IsInt(test_int) => { // TODO don't downcast i128 here