diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index f9bfb9bafc..ec8d61c468 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -11,7 +11,7 @@ use inkwell::{AddressSpace, FloatPredicate, IntPredicate}; use crate::llvm::convert::{ basic_type_from_layout, collection_wrapper, get_array_type, get_fn_type, }; -use roc_collections::all::{ImMap, MutMap}; +use roc_collections::all::ImMap; use roc_module::symbol::{Interns, Symbol}; use roc_mono::expr::{Expr, Proc, Procs}; use roc_mono::layout::{Builtin, Layout}; @@ -316,11 +316,10 @@ pub fn build_expr<'a, 'ctx, 'env>( BasicValueEnum::StructValue(struct_val.into_struct_value()) } Tag { - tag_id, + union_size, arguments, - tag_layout, .. - } => { + } if *union_size == 1 => { /* // put the discriminant in the first slot let discriminant = ( @@ -393,6 +392,16 @@ pub fn build_expr<'a, 'ctx, 'env>( .build_extract_value(struct_val, index, "field_access") .unwrap() } + AccessAtIndex { index, expr, .. } => { + let builder = env.builder; + + // Get Struct val + let struct_val = build_expr(env, &scope, parent, expr, procs).into_struct_value(); + + builder + .build_extract_value(struct_val, *index as u32, "tag_field_access") + .unwrap() + } _ => { panic!("I don't yet know how to LLVM build {:?}", expr); } diff --git a/compiler/gen/src/llvm/convert.rs b/compiler/gen/src/llvm/convert.rs index ecd14decd8..e5cc39c4f0 100644 --- a/compiler/gen/src/llvm/convert.rs +++ b/compiler/gen/src/llvm/convert.rs @@ -69,7 +69,7 @@ pub fn basic_type_from_layout<'ctx>( .as_basic_type_enum() } Union(tags) if tags.len() == 1 => { - let (_, layouts) = tags.into_iter().next().unwrap(); + let (_, layouts) = tags.iter().next().unwrap(); // Determine types let mut field_types = Vec::with_capacity_in(layouts.len(), arena); @@ -82,7 +82,7 @@ pub fn basic_type_from_layout<'ctx>( .struct_type(field_types.into_bump_slice(), false) .as_basic_type_enum() } - Union(tags) => { + Union(_) => { // TODO make this dynamic let ptr_size = std::mem::size_of::(); let union_size = layout.stack_size(ptr_size as u32); diff --git a/compiler/gen/tests/test_gen.rs b/compiler/gen/tests/test_gen.rs index a42712c710..464d2cc76c 100644 --- a/compiler/gen/tests/test_gen.rs +++ b/compiler/gen/tests/test_gen.rs @@ -708,6 +708,38 @@ mod test_gen { ); } + #[test] + fn when_one_element_tag() { + assert_evals_to!( + indoc!( + r#" + x : [ Pair Int Int ] + x = Pair 0x2 0x3 + + when x is + Pair l r -> l + r + "# + ), + 5, + i64 + ); + } + + #[test] + fn twice_record_access() { + assert_evals_to!( + indoc!( + r#" + x = {a: 0x2, b: 0x3 } + + x.a + x.b + "# + ), + 5, + i64 + ); + } + #[test] fn gen_when_one_branch() { assert_evals_to!( @@ -1312,5 +1344,17 @@ mod test_gen { 19, i64 ); + + assert_evals_to!( + indoc!( + r#" + rec = { x: 15, y: 17, z: 19 } + + rec.z + rec.x + "# + ), + 34, + i64 + ); } } diff --git a/compiler/mono/src/expr.rs b/compiler/mono/src/expr.rs index 4658a6dedc..4755142cad 100644 --- a/compiler/mono/src/expr.rs +++ b/compiler/mono/src/expr.rs @@ -910,7 +910,7 @@ fn store_pattern2<'a>( match argument { Identifier(symbol) => { // store immediately in the given symbol - stored.push((*symbol, layout.clone(), load)); + stored.push((*symbol, arg_layout.clone(), load)); } Underscore => { // ignore