diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index fb8e3139e1..e21b4e0121 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -1021,6 +1021,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( // reset, when used on a unique reference, eagerly decrements the components of the // referenced value, and returns the location of the now-invalid cell env.builder.position_at_end(then_block); + match build_reset(env, layout_ids, union_layout) { Some(reset_function) => { let call = @@ -1035,6 +1036,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( panic!("") } } + env.builder.build_unconditional_branch(cont_block); } { @@ -1162,6 +1164,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( lookup_at_index_ptr2( env, tag_id_type, + union_layout, field_layouts, *index as usize, argument.into_pointer_value(), @@ -1174,11 +1177,11 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( lookup_at_index_ptr( env, + union_layout, field_layouts, *index as usize, argument.into_pointer_value(), struct_type.into_struct_type(), - &struct_layout, ) } UnionLayout::NullableWrapped { @@ -1202,6 +1205,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( lookup_at_index_ptr2( env, tag_id_type, + union_layout, field_layouts, *index as usize, argument.into_pointer_value(), @@ -1221,12 +1225,12 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( lookup_at_index_ptr( env, + union_layout, field_layouts, // the tag id is not stored *index as usize, argument.into_pointer_value(), struct_type.into_struct_type(), - &struct_layout, ) } } @@ -1693,11 +1697,15 @@ fn allocate_tag<'a, 'ctx, 'env>( env.builder.build_unconditional_branch(cont_block); raw_ptr }; + let reuse_ptr = { env.builder.position_at_end(else_block); + env.builder.build_unconditional_branch(cont_block); + ptr }; + { env.builder.position_at_end(cont_block); let phi = env.builder.build_phi(raw_ptr.get_type(), "branch"); @@ -1780,11 +1788,11 @@ pub fn get_tag_id<'a, 'ctx, 'env>( fn lookup_at_index_ptr<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, + union_layout: &UnionLayout<'a>, field_layouts: &[Layout<'_>], index: usize, value: PointerValue<'ctx>, struct_type: StructType<'ctx>, - structure_layout: &Layout<'_>, ) -> BasicValueEnum<'ctx> { let builder = env.builder; @@ -1806,11 +1814,13 @@ fn lookup_at_index_ptr<'a, 'ctx, 'env>( if let Some(Layout::RecursivePointer) = field_layouts.get(index as usize) { // a recursive field is stored as a `i64*`, to use it we must cast it to // a pointer to the block of memory representation + let actual_type = basic_type_from_layout(env, &Layout::Union(*union_layout)); + debug_assert!(actual_type.is_pointer_type()); + builder.build_bitcast( result, - block_of_memory(env.context, structure_layout, env.ptr_bytes) - .ptr_type(AddressSpace::Generic), - "cast_rec_pointer_lookup_at_index_ptr", + actual_type, + "cast_rec_pointer_lookup_at_index_ptr_old", ) } else { result @@ -1820,6 +1830,7 @@ fn lookup_at_index_ptr<'a, 'ctx, 'env>( fn lookup_at_index_ptr2<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, tag_id_type: IntType<'ctx>, + union_layout: &UnionLayout<'a>, field_layouts: &[Layout<'_>], index: usize, value: PointerValue<'ctx>, @@ -1856,16 +1867,12 @@ fn lookup_at_index_ptr2<'a, 'ctx, 'env>( // a recursive field is stored as a `i64*`, to use it we must cast it to // a pointer to the block of memory representation - let tags = &[field_layouts]; - let struct_type = block_of_memory_slices(env.context, tags, env.ptr_bytes); - - let opaque_wrapper_type = env - .context - .struct_type(&[struct_type, tag_id_type.into()], false); + let actual_type = basic_type_from_layout(env, &Layout::Union(*union_layout)); + debug_assert!(actual_type.is_pointer_type()); builder.build_bitcast( result, - opaque_wrapper_type.ptr_type(AddressSpace::Generic), + actual_type, "cast_rec_pointer_lookup_at_index_ptr_new", ) } else {