From d63405d82483fa87bc7c0b1187c7a19c798599b1 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Fri, 12 Nov 2021 08:35:38 -0800 Subject: [PATCH] Make Expr::List use a Collection --- ast/src/lang/core/expr/expr_to_expr2.rs | 2 +- cli/src/repl/eval.rs | 15 ++-------- compiler/can/src/expr.rs | 4 +-- compiler/can/src/operator.rs | 11 +++----- compiler/fmt/src/expr.rs | 18 ++++-------- compiler/parse/src/ast.rs | 5 +--- compiler/parse/src/expr.rs | 4 +-- compiler/parse/tests/test_parse.rs | 37 ++++++++----------------- 8 files changed, 29 insertions(+), 67 deletions(-) diff --git a/ast/src/lang/core/expr/expr_to_expr2.rs b/ast/src/lang/core/expr/expr_to_expr2.rs index 00fa759f65..d1589a83b6 100644 --- a/ast/src/lang/core/expr/expr_to_expr2.rs +++ b/ast/src/lang/core/expr/expr_to_expr2.rs @@ -132,7 +132,7 @@ pub fn expr_to_expr2<'a>( Str(literal) => flatten_str_literal(env, scope, literal), - List { items, .. } => { + List(items) => { let mut output = Output::default(); let output_ref = &mut output; diff --git a/cli/src/repl/eval.rs b/cli/src/repl/eval.rs index b56200dc6f..1abb0f2f07 100644 --- a/cli/src/repl/eval.rs +++ b/cli/src/repl/eval.rs @@ -133,10 +133,7 @@ fn jit_to_ast_help<'a>( ), Layout::Builtin(Builtin::EmptyList) => { Ok(run_jit_function!(lib, main_fn_name, &'static str, |_| { - Expr::List { - items: &[], - final_comments: &[], - } + Expr::List(Collection::empty()) })) } Layout::Builtin(Builtin::List(elem_layout)) => Ok(run_jit_function!( @@ -431,10 +428,7 @@ fn ptr_to_ast<'a>( num_to_ast(env, number_literal_to_ast(env.arena, num), content) } - Layout::Builtin(Builtin::EmptyList) => Expr::List { - items: &[], - final_comments: &[], - }, + Layout::Builtin(Builtin::EmptyList) => Expr::List(Collection::empty()), Layout::Builtin(Builtin::List(elem_layout)) => { // Turn the (ptr, len) wrapper struct into actual ptr and len values. let len = unsafe { *(ptr.offset(env.ptr_bytes as isize) as *const usize) }; @@ -522,10 +516,7 @@ fn list_to_ast<'a>( let output = output.into_bump_slice(); - Expr::List { - items: output, - final_comments: &[], - } + Expr::List(Collection::with_items(output)) } fn single_tag_union_to_ast<'a>( diff --git a/compiler/can/src/expr.rs b/compiler/can/src/expr.rs index 768bba827e..098ad7926b 100644 --- a/compiler/can/src/expr.rs +++ b/compiler/can/src/expr.rs @@ -303,9 +303,7 @@ pub fn canonicalize_expr<'a>( } } ast::Expr::Str(literal) => flatten_str_literal(env, var_store, scope, literal), - ast::Expr::List { - items: loc_elems, .. - } => { + ast::Expr::List(loc_elems) => { if loc_elems.is_empty() { ( List { diff --git a/compiler/can/src/operator.rs b/compiler/can/src/operator.rs index 4faecdf9bf..98e8a1cba1 100644 --- a/compiler/can/src/operator.rs +++ b/compiler/can/src/operator.rs @@ -144,20 +144,17 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a arena.alloc(Located { region, value }) } - List { - items, - final_comments, - } => { + List(items) => { let mut new_items = Vec::with_capacity_in(items.len(), arena); for item in items.iter() { new_items.push(desugar_expr(arena, item)); } let new_items = new_items.into_bump_slice(); - let value: Expr<'a> = List { + let value: Expr<'a> = List(Collection { items: new_items, - final_comments, - }; + final_comments: items.final_comments, + }); arena.alloc(Located { region: loc_expr.region, diff --git a/compiler/fmt/src/expr.rs b/compiler/fmt/src/expr.rs index fd4d43e821..5e028c10ac 100644 --- a/compiler/fmt/src/expr.rs +++ b/compiler/fmt/src/expr.rs @@ -41,7 +41,7 @@ impl<'a> Formattable<'a> for Expr<'a> { // These expressions always have newlines Defs(_, _) | When(_, _) => true, - List { items, .. } => items.iter().any(|loc_expr| loc_expr.is_multiline()), + List(items) => items.iter().any(|loc_expr| loc_expr.is_multiline()), Str(literal) => { use roc_parse::ast::StrLiteral::*; @@ -290,11 +290,8 @@ impl<'a> Formattable<'a> for Expr<'a> { fmt_if(buf, branches, final_else, self.is_multiline(), indent); } When(loc_condition, branches) => fmt_when(buf, loc_condition, branches, indent), - List { - items, - final_comments, - } => { - fmt_list(buf, items, final_comments, indent); + List(items) => { + fmt_list(buf, *items, indent); } BinOps(lefts, right) => fmt_bin_ops(buf, lefts, right, false, parens, indent), UnaryOp(sub_expr, unary_op) => { @@ -411,12 +408,9 @@ fn fmt_bin_ops<'a>( loc_right_side.format_with_options(buf, apply_needs_parens, Newlines::Yes, indent); } -fn fmt_list<'a>( - buf: &mut String<'a>, - loc_items: &[&Located>], - final_comments: &'a [CommentOrNewline<'a>], - indent: u16, -) { +fn fmt_list<'a>(buf: &mut String<'a>, items: Collection<'a, &Located>>, indent: u16) { + let loc_items = items.items; + let final_comments = items.final_comments; if loc_items.is_empty() && final_comments.iter().all(|c| c.is_newline()) { buf.push_str("[]"); } else { diff --git a/compiler/parse/src/ast.rs b/compiler/parse/src/ast.rs index 02fd3acb03..d9661f2f37 100644 --- a/compiler/parse/src/ast.rs +++ b/compiler/parse/src/ast.rs @@ -127,10 +127,7 @@ pub enum Expr<'a> { AccessorFunction(&'a str), // Collection Literals - List { - items: &'a [&'a Loc>], - final_comments: &'a [CommentOrNewline<'a>], - }, + List(Collection<'a, &'a Loc>>), RecordUpdate { update: &'a Loc>, diff --git a/compiler/parse/src/expr.rs b/compiler/parse/src/expr.rs index d2f7b24487..ad14d0dfe4 100644 --- a/compiler/parse/src/expr.rs +++ b/compiler/parse/src/expr.rs @@ -2173,10 +2173,10 @@ fn list_literal_help<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, EList<'a> allocated.push(parsed_elem); } - let expr = Expr::List { + let expr = Expr::List(Collection { items: allocated.into_bump_slice(), final_comments: elements.final_comments, - }; + }); Ok((MadeProgress, expr, state)) } diff --git a/compiler/parse/tests/test_parse.rs b/compiler/parse/tests/test_parse.rs index 4e35c1b007..25d10eb092 100644 --- a/compiler/parse/tests/test_parse.rs +++ b/compiler/parse/tests/test_parse.rs @@ -1166,10 +1166,7 @@ mod test_parse { #[test] fn empty_list() { let arena = Bump::new(); - let expected = List { - items: &[], - final_comments: &[], - }; + let expected = List(Collection::empty()); let actual = parse_expr_with(&arena, "[]"); assert_eq!(Ok(expected), actual); @@ -1179,10 +1176,7 @@ mod test_parse { fn spaces_inside_empty_list() { // This is a regression test! let arena = Bump::new(); - let expected = List { - items: &[], - final_comments: &[], - }; + let expected = List(Collection::empty()); let actual = parse_expr_with(&arena, "[ ]"); assert_eq!(Ok(expected), actual); @@ -1191,10 +1185,10 @@ mod test_parse { #[test] fn newline_inside_empty_list() { let arena = Bump::new(); - let expected = List { + let expected = List(Collection { items: &[], final_comments: &[Newline], - }; + }); let actual = parse_expr_with(&arena, "[\n]"); assert_eq!(Ok(expected), actual); @@ -1203,10 +1197,10 @@ mod test_parse { #[test] fn comment_inside_empty_list() { let arena = Bump::new(); - let expected = List { + let expected = List(Collection { items: &[], final_comments: &[LineComment("comment")], - }; + }); let actual = parse_expr_with(&arena, "[#comment\n]"); assert_eq!(Ok(expected), actual); @@ -1216,10 +1210,7 @@ mod test_parse { fn packed_singleton_list() { let arena = Bump::new(); let items = &[&*arena.alloc(Located::new(0, 0, 1, 2, Num("1")))]; - let expected = List { - items, - final_comments: &[], - }; + let expected = List(Collection::with_items(items)); let actual = parse_expr_with(&arena, "[1]"); assert_eq!(Ok(expected), actual); @@ -1229,10 +1220,7 @@ mod test_parse { fn spaced_singleton_list() { let arena = Bump::new(); let items = &[&*arena.alloc(Located::new(0, 0, 2, 3, Num("1")))]; - let expected = List { - items, - final_comments: &[], - }; + let expected = List(Collection::with_items(items)); let actual = parse_expr_with(&arena, "[ 1 ]"); assert_eq!(Ok(expected), actual); @@ -1247,10 +1235,7 @@ mod test_parse { )); let item = Expr::SpaceBefore(item, arena.alloc([Newline])); let items = [&*arena.alloc(Located::new(1, 1, 0, 1, item))]; - let expected = List { - items: &items, - final_comments: &[], - }; + let expected = List(Collection::with_items(&items)); let actual = parse_expr_with(&arena, "[\n1\n]"); assert_eq!(Ok(expected), actual); @@ -2111,8 +2096,8 @@ mod test_parse { let apply = Expr::Apply( arena.alloc(Located::new(0, 0, 8, 17, var_list_map2)), bumpalo::vec![ in &arena; - &*arena.alloc(Located::new(0, 0, 18, 20, Expr::List{ items: &[], final_comments: &[] })), - &*arena.alloc(Located::new(0, 0, 21, 23, Expr::List{ items: &[], final_comments: &[] })), + &*arena.alloc(Located::new(0, 0, 18, 20, Expr::List(Collection::empty()))), + &*arena.alloc(Located::new(0, 0, 21, 23, Expr::List(Collection::empty()))), ] .into_bump_slice(), CalledVia::Space,