diff --git a/compiler/gen/tests/gen_list.rs b/compiler/gen/tests/gen_list.rs index 724b7d7545..e0da60f308 100644 --- a/compiler/gen/tests/gen_list.rs +++ b/compiler/gen/tests/gen_list.rs @@ -32,6 +32,11 @@ mod gen_list { assert_evals_to_ir!("[]", &[], &'static [i64]); } + #[test] + fn int_singleton_list_literal() { + assert_evals_to_ir!("[1]", &[1], &'static [i64]); + } + #[test] fn int_list_literal() { assert_evals_to_ir!("[ 12, 9, 6, 3 ]", &[12, 9, 6, 3], &'static [i64]); diff --git a/compiler/mono/src/experiment.rs b/compiler/mono/src/experiment.rs index fd58eec99b..3ea8329fd4 100644 --- a/compiler/mono/src/experiment.rs +++ b/compiler/mono/src/experiment.rs @@ -1,5 +1,7 @@ use self::InProgressProc::*; -use crate::layout::{list_layout_from_elem, Builtin, Layout, LayoutCache, LayoutProblem}; +use crate::layout::{ + list_layout_from_elem, Builtin, Layout, LayoutCache, LayoutProblem, Ownership, +}; use crate::pattern2::{Ctor, Guard, RenderAs, TagId}; use bumpalo::collections::Vec; use bumpalo::Bump; @@ -1281,6 +1283,12 @@ pub fn with_hole<'a>( When { .. } | If { .. } => todo!("when or if in expression requires join points"), + List { loc_elems, .. } if loc_elems.is_empty() => { + // because an empty list has an unknown element type, it is handled differently + let expr = Expr::EmptyArray; + Stmt::Let(assigned, expr, Layout::Builtin(Builtin::EmptyList), hole) + } + List { elem_var, loc_elems, @@ -1303,7 +1311,15 @@ pub fn with_hole<'a>( elem_layout: elem_layout.clone(), elems: arg_symbols, }; - let mut stmt = Stmt::Let(assigned, expr, elem_layout, hole); + let mut stmt = Stmt::Let( + assigned, + expr, + Layout::Builtin(Builtin::List( + Ownership::Owned, + env.arena.alloc(elem_layout), + )), + hole, + ); for (arg_expr, symbol) in loc_elems.into_iter().rev().zip(arg_symbols.iter().rev()) { // if this argument is already a symbol, we don't need to re-define it diff --git a/compiler/mono/tests/test_mono.rs b/compiler/mono/tests/test_mono.rs index 7f4dc26d4e..7c94a501a9 100644 --- a/compiler/mono/tests/test_mono.rs +++ b/compiler/mono/tests/test_mono.rs @@ -1533,4 +1533,26 @@ mod test_mono { ), ) } + + #[test] + fn list_push() { + compiles_to_ir( + r#" + List.push [1] 2 + "#, + indoc!( + r#" + procedure List.5 (#Attr.2, #Attr.3): + let Test.3 = lowlevel ListPush #Attr.2 #Attr.3; + ret Test.3; + + let Test.4 = 1i64; + let Test.1 = Array [Test.4]; + let Test.2 = 2i64; + let Test.0 = CallByName List.5 Test.1 Test.2; + ret Test.0; + "# + ), + ) + } }