From 1bee16decdaee10bb8c12419a0e87cd8ce37ee55 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 26 Apr 2020 09:24:45 -0400 Subject: [PATCH] Temporarily disable List.get in favor of getUnsafe --- compiler/builtins/src/std.rs | 15 +- compiler/builtins/src/unique.rs | 26 +++- compiler/can/src/builtins.rs | 178 ++++++++++++------------ compiler/gen/tests/gen_builtins.rs | 58 ++------ compiler/module/src/symbol.rs | 2 +- compiler/solve/tests/test_uniq_solve.rs | 4 +- 6 files changed, 141 insertions(+), 142 deletions(-) diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index 271f0e0085..f66975d2ac 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -371,7 +371,20 @@ pub fn types() -> MutMap { // List module - // get : List elem, Int -> Result elem [ IndexOutOfBounds ]* + // get : List elem, Int -> Result elem [ OutOfBounds ]* + let index_out_of_bounds = SolvedType::TagUnion( + vec![(TagName::Global("OutOfBounds".into()), vec![])], + Box::new(SolvedType::Wildcard), + ); + + add_type( + Symbol::LIST_GET, + SolvedType::Func( + vec![list_type(flex(TVAR1)), int_type()], + Box::new(result_type(flex(TVAR1), index_out_of_bounds)), + ), + ); + add_type( Symbol::LIST_GET_UNSAFE, SolvedType::Func( diff --git a/compiler/builtins/src/unique.rs b/compiler/builtins/src/unique.rs index 8ab3661136..0a0671b0cf 100644 --- a/compiler/builtins/src/unique.rs +++ b/compiler/builtins/src/unique.rs @@ -450,7 +450,20 @@ pub fn types() -> MutMap { unique_function(vec![list_type(UVAR1, TVAR1)], int_type(UVAR2)), ); - // #getUnsafe : List elem, Int -> elem + // get : List a, Int -> Result a [ OutOfBounds ]* + let index_out_of_bounds = SolvedType::TagUnion( + vec![(TagName::Global("OutOfBounds".into()), vec![])], + Box::new(SolvedType::Wildcard), + ); + + add_type( + Symbol::LIST_GET, + unique_function( + vec![list_type(UVAR1, TVAR1), int_type(UVAR2)], + result_type(UVAR3, flex(TVAR1), lift(UVAR4, index_out_of_bounds)), + ), + ); + add_type( Symbol::LIST_GET_UNSAFE, unique_function(vec![list_type(UVAR1, TVAR1), int_type(UVAR2)], flex(TVAR1)), @@ -934,6 +947,17 @@ fn num_type(u: VarId, a: VarId) -> SolvedType { ) } +#[inline(always)] +fn result_type(u: VarId, a: SolvedType, e: SolvedType) -> SolvedType { + SolvedType::Apply( + Symbol::ATTR_ATTR, + vec![ + flex(u), + SolvedType::Apply(Symbol::RESULT_RESULT, vec![a, e]), + ], + ) +} + #[inline(always)] fn list_type(u: VarId, a: VarId) -> SolvedType { SolvedType::Apply( diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index aa23379b8b..dc4051ae00 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -26,102 +26,102 @@ use roc_types::subs::{VarStore, Variable}; /// lookup (if the bounds check passed). That internal function is hardcoded in code gen, /// which works fine because it doesn't involve any open tag unions. pub fn builtin_defs(var_store: &VarStore) -> Vec { - vec![list_get(var_store), list_first(var_store)] + vec![/*list_get(var_store),*/ list_first(var_store)] } /// List.get : List elem, Int -> Result elem [ OutOfBounds ]* -fn list_get(var_store: &VarStore) -> Def { - use crate::expr::Expr::*; - use crate::pattern::Pattern::*; +// fn list_get(var_store: &VarStore) -> Def { +// use crate::expr::Expr::*; +// use crate::pattern::Pattern::*; - let args = vec![ - ( - var_store.fresh(), - no_region(Identifier(Symbol::LIST_GET_ARG_LIST)), - ), - ( - var_store.fresh(), - no_region(Identifier(Symbol::LIST_GET_ARG_INDEX)), - ), - ]; +// let args = vec![ +// ( +// var_store.fresh(), +// no_region(Identifier(Symbol::LIST_GET_ARG_LIST)), +// ), +// ( +// var_store.fresh(), +// no_region(Identifier(Symbol::LIST_GET_ARG_INDEX)), +// ), +// ]; - // Perform a bounds check. If it passes, delegate to List.#getUnsafe - let body = If { - cond_var: var_store.fresh(), - branch_var: var_store.fresh(), - branches: vec![( - // if-condition - no_region( - // index < List.len list - call( - Symbol::NUM_LT, - vec![ - Var(Symbol::LIST_GET_ARG_INDEX), - call( - Symbol::LIST_LEN, - vec![Var(Symbol::LIST_GET_ARG_LIST)], - var_store, - ), - ], - var_store, - ), - ), - // then-branch - no_region( - // Ok - tag( - "Ok", - vec![ - // List.getUnsafe list index - Call( - Box::new(( - var_store.fresh(), - no_region(Var(Symbol::LIST_GET_UNSAFE)), - var_store.fresh(), - )), - vec![ - (var_store.fresh(), no_region(Var(Symbol::LIST_GET_ARG_LIST))), - ( - var_store.fresh(), - no_region(Var(Symbol::LIST_GET_ARG_INDEX)), - ), - ], - CalledVia::Space, - ), - ], - var_store, - ), - ), - )], - final_else: Box::new( - // else-branch - no_region( - // Err - tag( - "Err", - vec![tag("OutOfBounds", Vec::new(), var_store)], - var_store, - ), - ), - ), - }; +// // Perform a bounds check. If it passes, delegate to List.#getUnsafe +// let body = If { +// cond_var: var_store.fresh(), +// branch_var: var_store.fresh(), +// branches: vec![( +// // if-condition +// no_region( +// // index < List.len list +// call( +// Symbol::NUM_LT, +// vec![ +// Var(Symbol::LIST_GET_ARG_INDEX), +// call( +// Symbol::LIST_LEN, +// vec![Var(Symbol::LIST_GET_ARG_LIST)], +// var_store, +// ), +// ], +// var_store, +// ), +// ), +// // then-branch +// no_region( +// // Ok +// tag( +// "Ok", +// vec![ +// // List.getUnsafe list index +// Call( +// Box::new(( +// var_store.fresh(), +// no_region(Var(Symbol::LIST_GET_UNSAFE)), +// var_store.fresh(), +// )), +// vec![ +// (var_store.fresh(), no_region(Var(Symbol::LIST_GET_ARG_LIST))), +// ( +// var_store.fresh(), +// no_region(Var(Symbol::LIST_GET_ARG_INDEX)), +// ), +// ], +// CalledVia::Space, +// ), +// ], +// var_store, +// ), +// ), +// )], +// final_else: Box::new( +// // else-branch +// no_region( +// // Err +// tag( +// "Err", +// vec![tag("OutOfBounds", Vec::new(), var_store)], +// var_store, +// ), +// ), +// ), +// }; - let expr = Closure( - var_store.fresh(), - Symbol::LIST_GET, - Recursive::NotRecursive, - args, - Box::new((no_region(body), var_store.fresh())), - ); +// let expr = Closure( +// var_store.fresh(), +// Symbol::LIST_GET, +// Recursive::NotRecursive, +// args, +// Box::new((no_region(body), var_store.fresh())), +// ); - Def { - loc_pattern: no_region(Identifier(Symbol::LIST_GET)), - loc_expr: no_region(expr), - expr_var: var_store.fresh(), - pattern_vars: SendMap::default(), - annotation: None, - } -} +// Def { +// loc_pattern: no_region(Identifier(Symbol::LIST_GET)), +// loc_expr: no_region(expr), +// expr_var: var_store.fresh(), +// pattern_vars: SendMap::default(), +// annotation: None, +// } +// } /// List.first : List elem -> Result elem [ ListWasEmpty ]* fn list_first(var_store: &VarStore) -> Def { diff --git a/compiler/gen/tests/gen_builtins.rs b/compiler/gen/tests/gen_builtins.rs index 5c4cda2b0a..13611cde02 100644 --- a/compiler/gen/tests/gen_builtins.rs +++ b/compiler/gen/tests/gen_builtins.rs @@ -306,12 +306,12 @@ mod gen_builtins { assert_evals_to!( indoc!( r#" - when List.first [ 42, 7, 19, 21 ] is + when List.first [ 12, 9, 6, 3 ] is Ok val -> val Err _ -> -1 "# ), - 42, + 12, i64 ); } @@ -334,32 +334,12 @@ mod gen_builtins { #[test] fn get_int_list() { - assert_evals_to!( - indoc!( - r#" - when List.get [ 42, 7, 19, 21 ] 1 is - Ok val -> val - Err _ -> -1 - "# - ), - 7, - i64 - ); + assert_evals_to!("List.getUnsafe [ 12, 9, 6 ] 1", 9, i64); } #[test] fn get_set_unique_int_list() { - assert_evals_to!( - indoc!( - r#" - when List.get (List.set [ 12, 9, 7, 3 ] 1 42) 1 is - Ok val -> val - Err _ -> -1 - "# - ), - 42, - i64 - ); + assert_evals_to!("List.getUnsafe (List.set [ 12, 9, 7, 3 ] 1 42) 1", 42, i64); } #[test] @@ -388,17 +368,9 @@ mod gen_builtins { shared = [ 2.1, 4.3 ] # This should not mutate the original - x = - when List.get (List.set shared 1 7.7) 1 is - Ok val -> val - Err _ -> -1 + x = List.getUnsafe (List.set shared 1 7.7) 1 - y = - when List.get shared 1 is - Ok val -> val - Err _ -> -1 - - { x, y } + { x, y: List.getUnsafe shared 1 } "# ), (7.7, 4.3), @@ -414,17 +386,9 @@ mod gen_builtins { shared = [ 2, 4 ] # This List.set is out of bounds, and should have no effect - x = - when List.get (List.set shared 422 0) 1 is - Ok val -> val - Err _ -> -1 + x = List.getUnsafe (List.set shared 422 0) 1 - y = - when List.get shared 1 is - Ok val -> val - Err _ -> -1 - - { x, y } + { x, y: List.getUnsafe shared 1 } "# ), (4, 4), @@ -437,11 +401,9 @@ mod gen_builtins { assert_evals_to!( indoc!( r#" - unshared = [ 2, 4 ] + shared = [ 2, 4 ] - when List.get unshared 1 is - Ok val -> val - Err _ -> -1 + List.getUnsafe shared 1 "# ), 4, diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index 2d6b01fa2a..34abb0569e 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -642,7 +642,7 @@ define_builtins! { 10 LIST_LEN: "len" 11 LIST_FOLDL: "foldl" 12 LIST_FOLDR: "foldr" - 13 LIST_GET_UNSAFE: "#getUnsafe" + 13 LIST_GET_UNSAFE: "getUnsafe" 14 LIST_CONCAT: "concat" 15 LIST_FIRST: "first" 16 LIST_FIRST_ARG: "first#list" diff --git a/compiler/solve/tests/test_uniq_solve.rs b/compiler/solve/tests/test_uniq_solve.rs index 34f562ee69..5eff143efe 100644 --- a/compiler/solve/tests/test_uniq_solve.rs +++ b/compiler/solve/tests/test_uniq_solve.rs @@ -2097,8 +2097,8 @@ mod test_uniq_solve { reverse "# ), - "Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr b c)))", - //"Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr a c)))", + // "Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr b c)))", + "Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr a c)))", ); }