diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index fe5d2afdd1..a7f06c406e 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -126,21 +126,17 @@ pub fn types() -> MutMap { } // addChecked : Num a, Num a -> Result (Num a) [ Overflow ]* - add_type!( + add_top_level_function_type!( Symbol::NUM_ADD_CHECKED, - top_level_function( - vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], - Box::new(result_type(num_type(flex(TVAR1)), overflow())), - ), + vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], + Box::new(result_type(num_type(flex(TVAR1)), overflow())), ); // addWrap : Int range, Int range -> Int range - add_type!( + add_top_level_function_type!( Symbol::NUM_ADD_WRAP, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // sub or (-) : Num a, Num a -> Num a @@ -151,21 +147,17 @@ pub fn types() -> MutMap { ); // subWrap : Int range, Int range -> Int range - add_type!( + add_top_level_function_type!( Symbol::NUM_SUB_WRAP, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // subChecked : Num a, Num a -> Result (Num a) [ Overflow ]* - add_type!( + add_top_level_function_type!( Symbol::NUM_SUB_CHECKED, - top_level_function( - vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], - Box::new(result_type(num_type(flex(TVAR1)), overflow())), - ), + vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], + Box::new(result_type(num_type(flex(TVAR1)), overflow())), ); // mul or (*) : Num a, Num a -> Num a @@ -176,81 +168,73 @@ pub fn types() -> MutMap { ); // mulWrap : Int range, Int range -> Int range - add_type!( + add_top_level_function_type!( Symbol::NUM_MUL_WRAP, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // mulChecked : Num a, Num a -> Result (Num a) [ Overflow ]* - add_type!( + add_top_level_function_type!( Symbol::NUM_MUL_CHECKED, - top_level_function( - vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], - Box::new(result_type(num_type(flex(TVAR1)), overflow())), - ), + vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], + Box::new(result_type(num_type(flex(TVAR1)), overflow())), ); // abs : Num a -> Num a - add_type!( + add_top_level_function_type!( Symbol::NUM_ABS, - top_level_function(vec![num_type(flex(TVAR1))], Box::new(num_type(flex(TVAR1)))), + vec![num_type(flex(TVAR1))], + Box::new(num_type(flex(TVAR1))) ); // neg : Num a -> Num a - add_type!( + add_top_level_function_type!( Symbol::NUM_NEG, - top_level_function(vec![num_type(flex(TVAR1))], Box::new(num_type(flex(TVAR1)))), + vec![num_type(flex(TVAR1))], + Box::new(num_type(flex(TVAR1))) ); // isEq or (==) : a, a -> Bool - add_type!( + add_top_level_function_type!( Symbol::BOOL_EQ, - top_level_function(vec![flex(TVAR1), flex(TVAR1)], Box::new(bool_type())), + vec![flex(TVAR1), flex(TVAR1)], + Box::new(bool_type()) ); // isNeq or (!=) : a, a -> Bool - add_type!( + add_top_level_function_type!( Symbol::BOOL_NEQ, - top_level_function(vec![flex(TVAR1), flex(TVAR1)], Box::new(bool_type())), + vec![flex(TVAR1), flex(TVAR1)], + Box::new(bool_type()) ); // isLt or (<) : Num a, Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_LT, - top_level_function( - vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], - Box::new(bool_type()), - ), + vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], + Box::new(bool_type()), ); // isLte or (<=) : Num a, Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_LTE, - top_level_function( - vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], - Box::new(bool_type()), - ), + vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], + Box::new(bool_type()), ); // isGt or (>) : Num a, Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_GT, - top_level_function( - vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], - Box::new(bool_type()), - ), + vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], + Box::new(bool_type()), ); // isGte or (>=) : Num a, Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_GTE, - top_level_function( - vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], - Box::new(bool_type()), - ), + vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))], + Box::new(bool_type()), ); // compare : Num a, Num a -> [ LT, EQ, GT ] @@ -261,42 +245,45 @@ pub fn types() -> MutMap { ); // toFloat : Num * -> Float * - add_type!( + add_top_level_function_type!( Symbol::NUM_TO_FLOAT, - top_level_function( - vec![num_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR2))), - ), + vec![num_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR2))), ); // isNegative : Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_IS_NEGATIVE, - top_level_function(vec![num_type(flex(TVAR1))], Box::new(bool_type())), + vec![num_type(flex(TVAR1))], + Box::new(bool_type()) ); // isPositive : Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_IS_POSITIVE, - top_level_function(vec![num_type(flex(TVAR1))], Box::new(bool_type())), + vec![num_type(flex(TVAR1))], + Box::new(bool_type()) ); // isZero : Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_IS_ZERO, - top_level_function(vec![num_type(flex(TVAR1))], Box::new(bool_type())), + vec![num_type(flex(TVAR1))], + Box::new(bool_type()) ); // isEven : Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_IS_EVEN, - top_level_function(vec![num_type(flex(TVAR1))], Box::new(bool_type())), + vec![num_type(flex(TVAR1))], + Box::new(bool_type()) ); // isOdd : Num a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_IS_ODD, - top_level_function(vec![num_type(flex(TVAR1))], Box::new(bool_type())), + vec![num_type(flex(TVAR1))], + Box::new(bool_type()) ); // maxInt : Int range @@ -311,81 +298,66 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - add_type!( + add_top_level_function_type!( Symbol::NUM_DIV_INT, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())), ); // bitwiseAnd : Int a, Int a -> Int a - add_type!( + add_top_level_function_type!( Symbol::NUM_BITWISE_AND, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // bitwiseXor : Int a, Int a -> Int a - add_type!( + add_top_level_function_type!( Symbol::NUM_BITWISE_XOR, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // bitwiseOr : Int a, Int a -> Int a - add_type!( + add_top_level_function_type!( Symbol::NUM_BITWISE_OR, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // shiftLeftBy : Int a, Int a -> Int a - add_type!( + add_top_level_function_type!( Symbol::NUM_SHIFT_LEFT, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // shiftRightBy : Int a, Int a -> Int a - add_type!( + add_top_level_function_type!( Symbol::NUM_SHIFT_RIGHT, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // shiftRightZfBy : Int a, Int a -> Int a - add_type!( + add_top_level_function_type!( Symbol::NUM_SHIFT_RIGHT_ZERO_FILL, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // intCast : Int a -> Int b - add_type!( + add_top_level_function_type!( Symbol::NUM_INT_CAST, - top_level_function(vec![int_type(flex(TVAR1))], Box::new(int_type(flex(TVAR2)))), + vec![int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR2))) ); // rem : Int a, Int a -> Result (Int a) [ DivByZero ]* - add_type!( + add_top_level_function_type!( Symbol::NUM_REM, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())), ); // mod : Int a, Int a -> Result (Int a) [ DivByZero ]* @@ -396,12 +368,10 @@ pub fn types() -> MutMap { ); // isMultipleOf : Int a, Int a -> Bool - add_type!( + add_top_level_function_type!( Symbol::NUM_IS_MULTIPLE_OF, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(bool_type()), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(bool_type()), ); // maxI128 : I128 @@ -410,21 +380,17 @@ pub fn types() -> MutMap { // Float module // div : Float a, Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_DIV_FLOAT, - top_level_function( - vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], - Box::new(result_type(float_type(flex(TVAR1)), div_by_zero.clone())), - ), + vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], + Box::new(result_type(float_type(flex(TVAR1)), div_by_zero.clone())), ); // mod : Float a, Float a -> Result (Float a) [ DivByZero ]* - add_type!( + add_top_level_function_type!( Symbol::NUM_MOD_FLOAT, - top_level_function( - vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], - Box::new(result_type(float_type(flex(TVAR1)), div_by_zero)), - ), + vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], + Box::new(result_type(float_type(flex(TVAR1)), div_by_zero)), ); // sqrt : Float a -> Float a @@ -433,12 +399,10 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - add_type!( + add_top_level_function_type!( Symbol::NUM_SQRT, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(result_type(float_type(flex(TVAR1)), sqrt_of_negative)), - ), + vec![float_type(flex(TVAR1))], + Box::new(result_type(float_type(flex(TVAR1)), sqrt_of_negative)), ); // log : Float a -> Float a @@ -447,48 +411,38 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - add_type!( + add_top_level_function_type!( Symbol::NUM_LOG, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(result_type(float_type(flex(TVAR1)), log_needs_positive)), - ), + vec![float_type(flex(TVAR1))], + Box::new(result_type(float_type(flex(TVAR1)), log_needs_positive)), ); // round : Float a -> Int b - add_type!( + add_top_level_function_type!( Symbol::NUM_ROUND, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR2))), - ), + vec![float_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR2))), ); // sin : Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_SIN, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR1))), - ), + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), ); // cos : Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_COS, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR1))), - ), + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), ); // tan : Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_TAN, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR1))), - ), + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), ); // maxFloat : Float a @@ -498,103 +452,87 @@ pub fn types() -> MutMap { add_type!(Symbol::NUM_MIN_FLOAT, float_type(flex(TVAR1))); // pow : Float a, Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_POW, - top_level_function( - vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR1))), - ), + vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), ); // ceiling : Float a -> Int b - add_type!( + add_top_level_function_type!( Symbol::NUM_CEILING, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR2))), - ), + vec![float_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR2))), ); // powInt : Int a, Int a -> Int a - add_type!( + add_top_level_function_type!( Symbol::NUM_POW_INT, - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR1))), - ), + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), ); // floor : Float a -> Int b - add_type!( + add_top_level_function_type!( Symbol::NUM_FLOOR, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(int_type(flex(TVAR2))), - ), + vec![float_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR2))), ); // atan : Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_ATAN, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR1))), - ), + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), ); // acos : Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_ACOS, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR1))), - ), + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), ); // asin : Float a -> Float a - add_type!( + add_top_level_function_type!( Symbol::NUM_ASIN, - top_level_function( - vec![float_type(flex(TVAR1))], - Box::new(float_type(flex(TVAR1))), - ), + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), ); // Bool module // and : Bool, Bool -> Bool - add_type!( + add_top_level_function_type!( Symbol::BOOL_AND, - top_level_function(vec![bool_type(), bool_type()], Box::new(bool_type())), + vec![bool_type(), bool_type()], + Box::new(bool_type()) ); // or : Bool, Bool -> Bool - add_type!( + add_top_level_function_type!( Symbol::BOOL_OR, - top_level_function(vec![bool_type(), bool_type()], Box::new(bool_type())), + vec![bool_type(), bool_type()], + Box::new(bool_type()) ); // xor : Bool, Bool -> Bool - add_type!( + add_top_level_function_type!( Symbol::BOOL_XOR, - top_level_function(vec![bool_type(), bool_type()], Box::new(bool_type())), + vec![bool_type(), bool_type()], + Box::new(bool_type()) ); // not : Bool -> Bool - add_type!( - Symbol::BOOL_NOT, - top_level_function(vec![bool_type()], Box::new(bool_type())), - ); + add_top_level_function_type!(Symbol::BOOL_NOT, vec![bool_type()], Box::new(bool_type())); // Str module // Str.split : Str, Str -> List Str - add_type!( + add_top_level_function_type!( Symbol::STR_SPLIT, - top_level_function( - vec![str_type(), str_type()], - Box::new(list_type(str_type())), - ), + vec![str_type(), str_type()], + Box::new(list_type(str_type())), ); // Str.concat : Str, Str -> Str @@ -605,48 +543,52 @@ pub fn types() -> MutMap { ); // Str.joinWith : List Str, Str -> Str - add_type!( + add_top_level_function_type!( Symbol::STR_JOIN_WITH, - top_level_function( - vec![list_type(str_type()), str_type()], - Box::new(str_type()), - ), + vec![list_type(str_type()), str_type()], + Box::new(str_type()), ); // isEmpty : Str -> Bool - add_type!( + add_top_level_function_type!( Symbol::STR_IS_EMPTY, - top_level_function(vec![str_type()], Box::new(bool_type())), + vec![str_type()], + Box::new(bool_type()) ); // startsWith : Str, Str -> Bool - add_type!( + add_top_level_function_type!( Symbol::STR_STARTS_WITH, - top_level_function(vec![str_type(), str_type()], Box::new(bool_type())), + vec![str_type(), str_type()], + Box::new(bool_type()) ); // startsWithCodePoint : Str, U32 -> Bool - add_type!( + add_top_level_function_type!( Symbol::STR_STARTS_WITH_CODE_POINT, - top_level_function(vec![str_type(), u32_type()], Box::new(bool_type())), + vec![str_type(), u32_type()], + Box::new(bool_type()) ); // endsWith : Str, Str -> Bool - add_type!( + add_top_level_function_type!( Symbol::STR_ENDS_WITH, - top_level_function(vec![str_type(), str_type()], Box::new(bool_type())), + vec![str_type(), str_type()], + Box::new(bool_type()) ); // countGraphemes : Str -> Nat - add_type!( + add_top_level_function_type!( Symbol::STR_COUNT_GRAPHEMES, - top_level_function(vec![str_type()], Box::new(nat_type())), + vec![str_type()], + Box::new(nat_type()) ); // fromInt : Int a -> Str - add_type!( + add_top_level_function_type!( Symbol::STR_FROM_INT, - top_level_function(vec![int_type(flex(TVAR1))], Box::new(str_type())), + vec![int_type(flex(TVAR1))], + Box::new(str_type()) ); // fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]* @@ -659,24 +601,24 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - add_type!( + add_top_level_function_type!( Symbol::STR_FROM_UTF8, - top_level_function( - vec![list_type(u8_type())], - Box::new(result_type(str_type(), bad_utf8)), - ), + vec![list_type(u8_type())], + Box::new(result_type(str_type(), bad_utf8)), ); // toBytes : Str -> List U8 - add_type!( + add_top_level_function_type!( Symbol::STR_TO_BYTES, - top_level_function(vec![str_type()], Box::new(list_type(u8_type()))), + vec![str_type()], + Box::new(list_type(u8_type())) ); // fromFloat : Float a -> Str - add_type!( + add_top_level_function_type!( Symbol::STR_FROM_FLOAT, - top_level_function(vec![float_type(flex(TVAR1))], Box::new(str_type())), + vec![float_type(flex(TVAR1))], + Box::new(str_type()) ); // List module @@ -687,12 +629,10 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - add_type!( + add_top_level_function_type!( Symbol::LIST_GET, - top_level_function( - vec![list_type(flex(TVAR1)), nat_type()], - Box::new(result_type(flex(TVAR1), index_out_of_bounds)), - ), + vec![list_type(flex(TVAR1)), nat_type()], + Box::new(result_type(flex(TVAR1), index_out_of_bounds)), ); // first : List elem -> Result elem [ ListWasEmpty ]* @@ -701,92 +641,74 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - add_type!( + add_top_level_function_type!( Symbol::LIST_FIRST, - top_level_function( - vec![list_type(flex(TVAR1))], - Box::new(result_type(flex(TVAR1), list_was_empty.clone())), - ), + vec![list_type(flex(TVAR1))], + Box::new(result_type(flex(TVAR1), list_was_empty.clone())), ); // last : List elem -> Result elem [ ListWasEmpty ]* - add_type!( + add_top_level_function_type!( Symbol::LIST_LAST, - top_level_function( - vec![list_type(flex(TVAR1))], - Box::new(result_type(flex(TVAR1), list_was_empty)), - ), + vec![list_type(flex(TVAR1))], + Box::new(result_type(flex(TVAR1), list_was_empty)), ); // set : List elem, Nat, elem -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_SET, - top_level_function( - vec![list_type(flex(TVAR1)), nat_type(), flex(TVAR1)], - Box::new(list_type(flex(TVAR1))), - ), + vec![list_type(flex(TVAR1)), nat_type(), flex(TVAR1)], + Box::new(list_type(flex(TVAR1))), ); // concat : List elem, List elem -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_CONCAT, - top_level_function( - vec![list_type(flex(TVAR1)), list_type(flex(TVAR1))], - Box::new(list_type(flex(TVAR1))), - ), + vec![list_type(flex(TVAR1)), list_type(flex(TVAR1))], + Box::new(list_type(flex(TVAR1))), ); // contains : List elem, elem -> Bool - add_type!( + add_top_level_function_type!( Symbol::LIST_CONTAINS, - top_level_function( - vec![list_type(flex(TVAR1)), flex(TVAR1)], - Box::new(bool_type()), - ), + vec![list_type(flex(TVAR1)), flex(TVAR1)], + Box::new(bool_type()), ); // sum : List (Num a) -> Num a - add_type!( + add_top_level_function_type!( Symbol::LIST_SUM, - top_level_function( - vec![list_type(num_type(flex(TVAR1)))], - Box::new(num_type(flex(TVAR1))), - ), + vec![list_type(num_type(flex(TVAR1)))], + Box::new(num_type(flex(TVAR1))), ); // product : List (Num a) -> Num a - add_type!( + add_top_level_function_type!( Symbol::LIST_PRODUCT, - top_level_function( - vec![list_type(num_type(flex(TVAR1)))], - Box::new(num_type(flex(TVAR1))), - ), + vec![list_type(num_type(flex(TVAR1)))], + Box::new(num_type(flex(TVAR1))), ); // walk : List elem, (elem -> accum -> accum), accum -> accum - add_type!( + add_top_level_function_type!( Symbol::LIST_WALK, - top_level_function( - vec![ - list_type(flex(TVAR1)), - closure(vec![flex(TVAR1), flex(TVAR2)], TVAR3, Box::new(flex(TVAR2))), - flex(TVAR2), - ], - Box::new(flex(TVAR2)), - ), + vec![ + list_type(flex(TVAR1)), + closure(vec![flex(TVAR1), flex(TVAR2)], TVAR3, Box::new(flex(TVAR2))), + flex(TVAR2), + ], + Box::new(flex(TVAR2)), ); // walkBackwards : List elem, (elem -> accum -> accum), accum -> accum - add_type!( + add_top_level_function_type!( Symbol::LIST_WALK_BACKWARDS, - top_level_function( - vec![ - list_type(flex(TVAR1)), - closure(vec![flex(TVAR1), flex(TVAR2)], TVAR3, Box::new(flex(TVAR2))), - flex(TVAR2), - ], - Box::new(flex(TVAR2)), - ), + vec![ + list_type(flex(TVAR1)), + closure(vec![flex(TVAR1), flex(TVAR2)], TVAR3, Box::new(flex(TVAR2))), + flex(TVAR2), + ], + Box::new(flex(TVAR2)), ); fn until_type(content: SolvedType) -> SolvedType { @@ -801,38 +723,35 @@ pub fn types() -> MutMap { } // walkUntil : List elem, (elem -> accum -> [ Continue accum, Stop accum ]), accum -> accum - add_type!( + add_top_level_function_type!( Symbol::LIST_WALK_UNTIL, - top_level_function( - vec![ - list_type(flex(TVAR1)), - closure( - vec![flex(TVAR1), flex(TVAR2)], - TVAR3, - Box::new(until_type(flex(TVAR2))), - ), - flex(TVAR2), - ], - Box::new(flex(TVAR2)), - ), + vec![ + list_type(flex(TVAR1)), + closure( + vec![flex(TVAR1), flex(TVAR2)], + TVAR3, + Box::new(until_type(flex(TVAR2))), + ), + flex(TVAR2), + ], + Box::new(flex(TVAR2)), ); // keepIf : List elem, (elem -> Bool) -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_KEEP_IF, - top_level_function( - vec![ - list_type(flex(TVAR1)), - closure(vec![flex(TVAR1)], TVAR2, Box::new(bool_type())), - ], - Box::new(list_type(flex(TVAR1))), - ), + vec![ + list_type(flex(TVAR1)), + closure(vec![flex(TVAR1)], TVAR2, Box::new(bool_type())), + ], + Box::new(list_type(flex(TVAR1))), ); // keepOks : List before, (before -> Result after *) -> List after - add_type!(Symbol::LIST_KEEP_OKS, { + { let_tvars! { star, cvar, before, after}; - top_level_function( + add_top_level_function_type!( + Symbol::LIST_KEEP_OKS, vec![ list_type(flex(before)), closure( @@ -843,7 +762,7 @@ pub fn types() -> MutMap { ], Box::new(list_type(flex(after))), ) - }); + }; // keepErrs: List before, (before -> Result * after) -> List after { @@ -864,41 +783,40 @@ pub fn types() -> MutMap { }; // range : Int a, Int a -> List (Int a) - add_type!(Symbol::LIST_RANGE, { - top_level_function( - vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], - Box::new(list_type(int_type(flex(TVAR1)))), - ) - }); + add_top_level_function_type!( + Symbol::LIST_RANGE, + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(list_type(int_type(flex(TVAR1)))), + ); // map : List before, (before -> after) -> List after - add_type!( + add_top_level_function_type!( Symbol::LIST_MAP, - top_level_function( - vec![ - list_type(flex(TVAR1)), - closure(vec![flex(TVAR1)], TVAR3, Box::new(flex(TVAR2))), - ], - Box::new(list_type(flex(TVAR2))), - ), + vec![ + list_type(flex(TVAR1)), + closure(vec![flex(TVAR1)], TVAR3, Box::new(flex(TVAR2))), + ], + Box::new(list_type(flex(TVAR2))), ); // mapWithIndex : List before, (Nat, before -> after) -> List after - add_type!(Symbol::LIST_MAP_WITH_INDEX, { + { let_tvars! { cvar, before, after}; - top_level_function( + add_top_level_function_type!( + Symbol::LIST_MAP_WITH_INDEX, vec![ list_type(flex(before)), closure(vec![nat_type(), flex(before)], cvar, Box::new(flex(after))), ], Box::new(list_type(flex(after))), ) - }); + }; // map2 : List a, List b, (a, b -> c) -> List c - add_type!(Symbol::LIST_MAP2, { + { let_tvars! {a, b, c, cvar}; - top_level_function( + add_top_level_function_type!( + Symbol::LIST_MAP2, vec![ list_type(flex(a)), list_type(flex(b)), @@ -906,7 +824,7 @@ pub fn types() -> MutMap { ], Box::new(list_type(flex(c))), ) - }); + }; { let_tvars! {a, b, c, d, cvar}; @@ -925,111 +843,99 @@ pub fn types() -> MutMap { }; // append : List elem, elem -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_APPEND, - top_level_function( - vec![list_type(flex(TVAR1)), flex(TVAR1)], - Box::new(list_type(flex(TVAR1))), - ), + vec![list_type(flex(TVAR1)), flex(TVAR1)], + Box::new(list_type(flex(TVAR1))), ); // prepend : List elem, elem -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_PREPEND, - top_level_function( - vec![list_type(flex(TVAR1)), flex(TVAR1)], - Box::new(list_type(flex(TVAR1))), - ), + vec![list_type(flex(TVAR1)), flex(TVAR1)], + Box::new(list_type(flex(TVAR1))), ); // join : List (List elem) -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_JOIN, - top_level_function( - vec![list_type(list_type(flex(TVAR1)))], - Box::new(list_type(flex(TVAR1))), - ), + vec![list_type(list_type(flex(TVAR1)))], + Box::new(list_type(flex(TVAR1))), ); // single : a -> List a - add_type!( + add_top_level_function_type!( Symbol::LIST_SINGLE, - top_level_function(vec![flex(TVAR1)], Box::new(list_type(flex(TVAR1)))), + vec![flex(TVAR1)], + Box::new(list_type(flex(TVAR1))) ); // repeat : Nat, elem -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_REPEAT, - top_level_function( - vec![nat_type(), flex(TVAR1)], - Box::new(list_type(flex(TVAR1))), - ), + vec![nat_type(), flex(TVAR1)], + Box::new(list_type(flex(TVAR1))), ); // reverse : List elem -> List elem - add_type!( + add_top_level_function_type!( Symbol::LIST_REVERSE, - top_level_function( - vec![list_type(flex(TVAR1))], - Box::new(list_type(flex(TVAR1))), - ), + vec![list_type(flex(TVAR1))], + Box::new(list_type(flex(TVAR1))), ); // len : List * -> Nat - add_type!( + add_top_level_function_type!( Symbol::LIST_LEN, - top_level_function(vec![list_type(flex(TVAR1))], Box::new(nat_type())), + vec![list_type(flex(TVAR1))], + Box::new(nat_type()) ); // isEmpty : List * -> Bool - add_type!( + add_top_level_function_type!( Symbol::LIST_IS_EMPTY, - top_level_function(vec![list_type(flex(TVAR1))], Box::new(bool_type())), + vec![list_type(flex(TVAR1))], + Box::new(bool_type()) ); // sortWith : List a, (a, a -> Ordering) -> List a - add_type!( + add_top_level_function_type!( Symbol::LIST_SORT_WITH, - top_level_function( - vec![ - list_type(flex(TVAR1)), - closure( - vec![flex(TVAR1), flex(TVAR1)], - TVAR2, - Box::new(ordering_type()), - ), - ], - Box::new(list_type(flex(TVAR1))), - ), + vec![ + list_type(flex(TVAR1)), + closure( + vec![flex(TVAR1), flex(TVAR1)], + TVAR2, + Box::new(ordering_type()), + ), + ], + Box::new(list_type(flex(TVAR1))), ); // Dict module // Dict.hashTestOnly : Nat, v -> Nat - add_type!( + add_top_level_function_type!( Symbol::DICT_TEST_HASH, - top_level_function(vec![u64_type(), flex(TVAR2)], Box::new(nat_type())), + vec![u64_type(), flex(TVAR2)], + Box::new(nat_type()) ); // len : Dict * * -> Nat - add_type!( + add_top_level_function_type!( Symbol::DICT_LEN, - top_level_function( - vec![dict_type(flex(TVAR1), flex(TVAR2))], - Box::new(nat_type()), - ), + vec![dict_type(flex(TVAR1), flex(TVAR2))], + Box::new(nat_type()), ); // empty : Dict * * add_type!(Symbol::DICT_EMPTY, dict_type(flex(TVAR1), flex(TVAR2))); // single : k, v -> Dict k v - add_type!( + add_top_level_function_type!( Symbol::DICT_SINGLE, - top_level_function( - vec![flex(TVAR1), flex(TVAR2)], - Box::new(dict_type(flex(TVAR1), flex(TVAR2))), - ), + vec![flex(TVAR1), flex(TVAR2)], + Box::new(dict_type(flex(TVAR1), flex(TVAR2))), ); // get : Dict k v, k -> Result v [ KeyNotFound ]* @@ -1038,114 +944,94 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - add_type!( + add_top_level_function_type!( Symbol::DICT_GET, - top_level_function( - vec![dict_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)], - Box::new(result_type(flex(TVAR2), key_not_found)), - ), + vec![dict_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)], + Box::new(result_type(flex(TVAR2), key_not_found)), ); // Dict.insert : Dict k v, k, v -> Dict k v - add_type!( + add_top_level_function_type!( Symbol::DICT_INSERT, - top_level_function( - vec![ - dict_type(flex(TVAR1), flex(TVAR2)), - flex(TVAR1), - flex(TVAR2), - ], - Box::new(dict_type(flex(TVAR1), flex(TVAR2))), - ), + vec![ + dict_type(flex(TVAR1), flex(TVAR2)), + flex(TVAR1), + flex(TVAR2), + ], + Box::new(dict_type(flex(TVAR1), flex(TVAR2))), ); // Dict.remove : Dict k v, k -> Dict k v - add_type!( + add_top_level_function_type!( Symbol::DICT_REMOVE, - top_level_function( - vec![dict_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)], - Box::new(dict_type(flex(TVAR1), flex(TVAR2))), - ), + vec![dict_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)], + Box::new(dict_type(flex(TVAR1), flex(TVAR2))), ); // Dict.contains : Dict k v, k -> Bool - add_type!( + add_top_level_function_type!( Symbol::DICT_CONTAINS, - top_level_function( - vec![dict_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)], - Box::new(bool_type()), - ), + vec![dict_type(flex(TVAR1), flex(TVAR2)), flex(TVAR1)], + Box::new(bool_type()), ); // Dict.keys : Dict k v -> List k - add_type!( + add_top_level_function_type!( Symbol::DICT_KEYS, - top_level_function( - vec![dict_type(flex(TVAR1), flex(TVAR2))], - Box::new(list_type(flex(TVAR1))), - ), + vec![dict_type(flex(TVAR1), flex(TVAR2))], + Box::new(list_type(flex(TVAR1))), ); // Dict.values : Dict k v -> List v - add_type!( + add_top_level_function_type!( Symbol::DICT_VALUES, - top_level_function( - vec![dict_type(flex(TVAR1), flex(TVAR2))], - Box::new(list_type(flex(TVAR2))), - ), + vec![dict_type(flex(TVAR1), flex(TVAR2))], + Box::new(list_type(flex(TVAR2))), ); // Dict.union : Dict k v, Dict k v -> Dict k v - add_type!( + add_top_level_function_type!( Symbol::DICT_UNION, - top_level_function( - vec![ - dict_type(flex(TVAR1), flex(TVAR2)), - dict_type(flex(TVAR1), flex(TVAR2)), - ], - Box::new(dict_type(flex(TVAR1), flex(TVAR2))), - ), + vec![ + dict_type(flex(TVAR1), flex(TVAR2)), + dict_type(flex(TVAR1), flex(TVAR2)), + ], + Box::new(dict_type(flex(TVAR1), flex(TVAR2))), ); // Dict.intersection : Dict k v, Dict k v -> Dict k v - add_type!( + add_top_level_function_type!( Symbol::DICT_INTERSECTION, - top_level_function( - vec![ - dict_type(flex(TVAR1), flex(TVAR2)), - dict_type(flex(TVAR1), flex(TVAR2)), - ], - Box::new(dict_type(flex(TVAR1), flex(TVAR2))), - ), + vec![ + dict_type(flex(TVAR1), flex(TVAR2)), + dict_type(flex(TVAR1), flex(TVAR2)), + ], + Box::new(dict_type(flex(TVAR1), flex(TVAR2))), ); // Dict.difference : Dict k v, Dict k v -> Dict k v - add_type!( + add_top_level_function_type!( Symbol::DICT_DIFFERENCE, - top_level_function( - vec![ - dict_type(flex(TVAR1), flex(TVAR2)), - dict_type(flex(TVAR1), flex(TVAR2)), - ], - Box::new(dict_type(flex(TVAR1), flex(TVAR2))), - ), + vec![ + dict_type(flex(TVAR1), flex(TVAR2)), + dict_type(flex(TVAR1), flex(TVAR2)), + ], + Box::new(dict_type(flex(TVAR1), flex(TVAR2))), ); // Dict.walk : Dict k v, (k, v, accum -> accum), accum -> accum - add_type!( + add_top_level_function_type!( Symbol::DICT_WALK, - top_level_function( - vec![ - dict_type(flex(TVAR1), flex(TVAR2)), - closure( - vec![flex(TVAR1), flex(TVAR2), flex(TVAR3)], - TVAR4, - Box::new(flex(TVAR3)), - ), - flex(TVAR3), - ], - Box::new(flex(TVAR3)), - ), + vec![ + dict_type(flex(TVAR1), flex(TVAR2)), + closure( + vec![flex(TVAR1), flex(TVAR2), flex(TVAR3)], + TVAR4, + Box::new(flex(TVAR3)), + ), + flex(TVAR3), + ], + Box::new(flex(TVAR3)), ); // Set module @@ -1154,111 +1040,93 @@ pub fn types() -> MutMap { add_type!(Symbol::SET_EMPTY, set_type(flex(TVAR1))); // single : a -> Set a - add_type!( + add_top_level_function_type!( Symbol::SET_SINGLE, - top_level_function(vec![flex(TVAR1)], Box::new(set_type(flex(TVAR1)))), + vec![flex(TVAR1)], + Box::new(set_type(flex(TVAR1))) ); // len : Set * -> Nat - add_type!( + add_top_level_function_type!( Symbol::SET_LEN, - top_level_function(vec![set_type(flex(TVAR1))], Box::new(nat_type())), + vec![set_type(flex(TVAR1))], + Box::new(nat_type()) ); // toList : Set a -> List a - add_type!( + add_top_level_function_type!( Symbol::SET_TO_LIST, - top_level_function( - vec![set_type(flex(TVAR1))], - Box::new(list_type(flex(TVAR1))), - ), + vec![set_type(flex(TVAR1))], + Box::new(list_type(flex(TVAR1))), ); - // fromList : Set a -> List a - add_type!( + // fromList : List a -> Set a + add_top_level_function_type!( Symbol::SET_FROM_LIST, - top_level_function( - vec![list_type(flex(TVAR1))], - Box::new(set_type(flex(TVAR1))), - ), + vec![list_type(flex(TVAR1))], + Box::new(set_type(flex(TVAR1))), ); // union : Set a, Set a -> Set a - add_type!( + add_top_level_function_type!( Symbol::SET_UNION, - top_level_function( - vec![set_type(flex(TVAR1)), set_type(flex(TVAR1))], - Box::new(set_type(flex(TVAR1))), - ), + vec![set_type(flex(TVAR1)), set_type(flex(TVAR1))], + Box::new(set_type(flex(TVAR1))), ); // difference : Set a, Set a -> Set a - add_type!( + add_top_level_function_type!( Symbol::SET_DIFFERENCE, - top_level_function( - vec![set_type(flex(TVAR1)), set_type(flex(TVAR1))], - Box::new(set_type(flex(TVAR1))), - ), + vec![set_type(flex(TVAR1)), set_type(flex(TVAR1))], + Box::new(set_type(flex(TVAR1))), ); // intersection : Set a, Set a -> Set a - add_type!( + add_top_level_function_type!( Symbol::SET_INTERSECTION, - top_level_function( - vec![set_type(flex(TVAR1)), set_type(flex(TVAR1))], - Box::new(set_type(flex(TVAR1))), - ), + vec![set_type(flex(TVAR1)), set_type(flex(TVAR1))], + Box::new(set_type(flex(TVAR1))), ); // Set.walk : Set a, (a, b -> b), b -> b - add_type!( + add_top_level_function_type!( Symbol::SET_WALK, - top_level_function( - vec![ - set_type(flex(TVAR1)), - closure(vec![flex(TVAR1), flex(TVAR2)], TVAR3, Box::new(flex(TVAR2))), - flex(TVAR2), - ], - Box::new(flex(TVAR2)), - ), + vec![ + set_type(flex(TVAR1)), + closure(vec![flex(TVAR1), flex(TVAR2)], TVAR3, Box::new(flex(TVAR2))), + flex(TVAR2), + ], + Box::new(flex(TVAR2)), ); - add_type!( + add_top_level_function_type!( Symbol::SET_INSERT, - top_level_function( - vec![set_type(flex(TVAR1)), flex(TVAR1)], - Box::new(set_type(flex(TVAR1))), - ), + vec![set_type(flex(TVAR1)), flex(TVAR1)], + Box::new(set_type(flex(TVAR1))), ); - add_type!( + add_top_level_function_type!( Symbol::SET_REMOVE, - top_level_function( - vec![set_type(flex(TVAR1)), flex(TVAR1)], - Box::new(set_type(flex(TVAR1))), - ), + vec![set_type(flex(TVAR1)), flex(TVAR1)], + Box::new(set_type(flex(TVAR1))), ); - add_type!( + add_top_level_function_type!( Symbol::SET_CONTAINS, - top_level_function( - vec![set_type(flex(TVAR1)), flex(TVAR1)], - Box::new(bool_type()), - ), + vec![set_type(flex(TVAR1)), flex(TVAR1)], + Box::new(bool_type()), ); // Result module // map : Result a err, (a -> b) -> Result b err - add_type!( + add_top_level_function_type!( Symbol::RESULT_MAP, - top_level_function( - vec![ - result_type(flex(TVAR1), flex(TVAR3)), - closure(vec![flex(TVAR1)], TVAR4, Box::new(flex(TVAR2))), - ], - Box::new(result_type(flex(TVAR2), flex(TVAR3))), - ), + vec![ + result_type(flex(TVAR1), flex(TVAR3)), + closure(vec![flex(TVAR1)], TVAR4, Box::new(flex(TVAR2))), + ], + Box::new(result_type(flex(TVAR2), flex(TVAR3))), ); // mapErr : Result a x, (x -> y) -> Result a x @@ -1272,28 +1140,24 @@ pub fn types() -> MutMap { ); // after : Result a err, (a -> Result b err) -> Result b err - add_type!( + add_top_level_function_type!( Symbol::RESULT_AFTER, - top_level_function( - vec![ - result_type(flex(TVAR1), flex(TVAR3)), - closure( - vec![flex(TVAR1)], - TVAR4, - Box::new(result_type(flex(TVAR2), flex(TVAR3))), - ), - ], - Box::new(result_type(flex(TVAR2), flex(TVAR3))), - ), + vec![ + result_type(flex(TVAR1), flex(TVAR3)), + closure( + vec![flex(TVAR1)], + TVAR4, + Box::new(result_type(flex(TVAR2), flex(TVAR3))), + ), + ], + Box::new(result_type(flex(TVAR2), flex(TVAR3))), ); // withDefault : Result a x, a -> a - add_type!( + add_top_level_function_type!( Symbol::RESULT_WITH_DEFAULT, - top_level_function( - vec![result_type(flex(TVAR1), flex(TVAR3)), flex(TVAR1)], - Box::new(flex(TVAR1)), - ), + vec![result_type(flex(TVAR1), flex(TVAR3)), flex(TVAR1)], + Box::new(flex(TVAR1)), ); types diff --git a/compiler/gen/src/llvm/bitcode.rs b/compiler/gen/src/llvm/bitcode.rs index b30b670fa8..b4da4e4060 100644 --- a/compiler/gen/src/llvm/bitcode.rs +++ b/compiler/gen/src/llvm/bitcode.rs @@ -145,6 +145,7 @@ fn build_transform_caller_help_new<'a, 'ctx, 'env>( arguments_cast.push(argument); } + dbg!(closure_data_layout); match closure_data_layout { Layout::FunctionPointer(_, _) => { // do nothing @@ -167,9 +168,31 @@ fn build_transform_caller_help_new<'a, 'ctx, 'env>( arguments_cast.push(closure_data); } } + Layout::Struct([Layout::Closure(_, lambda_set, _)]) => { + // a case required for Set.walk; may be able to remove when we can define builtins in + // terms of other builtins in the right way (using their function symbols instead of + // hacking with lowlevel ops). + let closure_type = basic_type_from_layout( + env, + &Layout::Struct(&[lambda_set.runtime_representation()]), + ) + .ptr_type(AddressSpace::Generic); + + let closure_cast = env + .builder + .build_bitcast(closure_ptr, closure_type, "load_opaque") + .into_pointer_value(); + + let closure_data = env.builder.build_load(closure_cast, "load_opaque"); + + arguments_cast.push(closure_data); + } Layout::Struct([]) => { // do nothing, should try to remove this case later } + Layout::Struct(_) => { + // do nothing, should try to remove this case later + } other => unreachable!("layout is not valid for a closure: {:?}", other), } diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 455bb7c87e..e7c3cb28c3 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -3069,8 +3069,6 @@ pub fn build_proc_header_new<'a, 'ctx, 'env>( ) -> FunctionValue<'ctx> { let layout = env.arena.alloc(layout).full(); - dbg!(symbol, layout); - build_proc_header(env, layout_ids, symbol, &layout, proc) } @@ -4448,11 +4446,12 @@ fn run_low_level<'a, 'ctx, 'env>( } } DictWalk => { - debug_assert_eq!(args.len(), 3); + debug_assert_eq!(args.len(), 4); let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]); - let (stepper, stepper_layout) = load_symbol_and_layout(scope, &args[1]); - let (accum, accum_layout) = load_symbol_and_layout(scope, &args[2]); + let (default, default_layout) = load_symbol_and_layout(scope, &args[1]); + let (function_layout, function) = scope.function_pointers[&args[2]]; + let (closure, closure_layout) = load_symbol_and_layout(scope, &args[3]); match dict_layout { Layout::Builtin(Builtin::EmptyDict) => { @@ -4463,12 +4462,14 @@ fn run_low_level<'a, 'ctx, 'env>( env, layout_ids, dict, - stepper, - accum, - stepper_layout, + function, + function_layout, + closure, + *closure_layout, + default, key_layout, value_layout, - accum_layout, + default_layout, ), _ => unreachable!("invalid dict layout"), } diff --git a/compiler/gen/src/llvm/build_dict.rs b/compiler/gen/src/llvm/build_dict.rs index 7ef54fd055..08a7b81e58 100644 --- a/compiler/gen/src/llvm/build_dict.rs +++ b/compiler/gen/src/llvm/build_dict.rs @@ -1,6 +1,6 @@ use crate::debug_info_init; use crate::llvm::bitcode::{ - build_dec_wrapper, build_eq_wrapper, build_inc_wrapper, build_transform_caller, + build_dec_wrapper, build_eq_wrapper, build_inc_wrapper, build_transform_caller_new, call_bitcode_fn, call_void_bitcode_fn, }; use crate::llvm::build::{ @@ -633,9 +633,11 @@ pub fn dict_walk<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, layout_ids: &mut LayoutIds<'a>, dict: BasicValueEnum<'ctx>, - stepper: BasicValueEnum<'ctx>, + transform: FunctionValue<'ctx>, + transform_layout: Layout<'a>, + closure_data: BasicValueEnum<'ctx>, + closure_data_layout: Layout<'a>, accum: BasicValueEnum<'ctx>, - stepper_layout: &Layout<'a>, key_layout: &Layout<'a>, value_layout: &Layout<'a>, accum_layout: &Layout<'a>, @@ -648,13 +650,13 @@ pub fn dict_walk<'a, 'ctx, 'env>( let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr"); env.builder.build_store(dict_ptr, dict); - let stepper_ptr = builder.build_alloca(stepper.get_type(), "stepper_ptr"); - env.builder.build_store(stepper_ptr, stepper); + let closure_data_ptr = builder.build_alloca(closure_data.get_type(), "closure_data_ptr"); + env.builder.build_store(closure_data_ptr, closure_data); - let stepper_caller = build_transform_caller( + let stepper_caller = build_transform_caller_new( env, - layout_ids, - stepper_layout, + transform, + closure_data_layout, &[*key_layout, *value_layout, *accum_layout], ) .as_global_value() @@ -688,7 +690,8 @@ pub fn dict_walk<'a, 'ctx, 'env>( env, &[ dict_ptr.into(), - env.builder.build_bitcast(stepper_ptr, u8_ptr, "to_opaque"), + env.builder + .build_bitcast(closure_data_ptr, u8_ptr, "to_opaque"), stepper_caller.into(), env.builder.build_bitcast(accum_ptr, u8_ptr, "to_opaque"), alignment_iv.into(), diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index 89ba64c855..c03960006a 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -980,6 +980,7 @@ define_builtins! { 12 SET_WALK: "walk" 13 SET_WALK_USER_FUNCTION: "#walk_user_function" 14 SET_CONTAINS: "contains" + 15 SET_WALK_VAR: "#set_walk_var" } num_modules: 8 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro) diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index c636f46c4e..804dbaab14 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -19,7 +19,7 @@ use roc_types::subs::{Content, FlatType, Subs, Variable}; use std::collections::HashMap; use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder}; -pub const PRETTY_PRINT_IR_SYMBOLS: bool = true; +pub const PRETTY_PRINT_IR_SYMBOLS: bool = false; macro_rules! return_on_layout_error { ($env:expr, $layout_result:expr) => { @@ -2449,8 +2449,8 @@ impl<'a> TopLevelFunctionLayout<'a> { Layout::FunctionPointer(old_arguments, result) => { Self::new(arena, old_arguments, *result) } - Layout::Closure(arguments, closure_layout, result) => { - let full = closure_layout.extend_function_layout(arena, arguments, result); + Layout::Closure(arguments, lambda_set, result) => { + let full = lambda_set.extend_function_layout(arena, arguments, result); TopLevelFunctionLayout::from_layout(arena, full) } _ => TopLevelFunctionLayout { @@ -3901,7 +3901,7 @@ pub fn with_hole<'a>( } Call(boxed, loc_args, _) => { - let (fn_var, loc_expr, lambda_set_var, ret_var) = *boxed; + let (fn_var, loc_expr, _lambda_set_var, ret_var) = *boxed; // even if a call looks like it's by name, it may in fact be by-pointer. // E.g. in `(\f, x -> f x)` the call is in fact by pointer. @@ -3910,7 +3910,7 @@ pub fn with_hole<'a>( // if it's in there, it's a call by name, otherwise it's a call by pointer let is_known = |key| { // a proc in this module, or an imported symbol - procs.partial_procs.contains_key(key) || key.module_id() != assigned.module_id() + procs.partial_procs.contains_key(key) || env.is_imported_symbol(*key) }; match loc_expr.value { @@ -4181,6 +4181,16 @@ pub fn with_hole<'a>( // actual closure, and the default is either the number 1 or 0 // this can be removed when we define builtin modules as proper modules + let stmt = assign_to_symbol( + env, + procs, + layout_cache, + args[0].0, + Located::at_zero(args[0].1.clone()), + arg_symbols[0], + stmt, + ); + let stmt = assign_to_symbol( env, procs, @@ -7524,8 +7534,7 @@ fn lowlevel_match_on_lambda_set<'a, F>( where F: Fn(Symbol, Symbol) -> Call<'a> + Copy, { - dbg!(lambda_set); - match dbg!(lambda_set.runtime_representation()) { + match lambda_set.runtime_representation() { Layout::Union(_) => { let closure_tag_id_symbol = env.unique_symbol(); @@ -7562,8 +7571,6 @@ where let bound = env.unique_symbol(); - dbg!(hole); - // build the call let stmt = Stmt::Let( assigned, diff --git a/compiler/mono/src/layout.rs b/compiler/mono/src/layout.rs index 21acf8663e..def448a6c3 100644 --- a/compiler/mono/src/layout.rs +++ b/compiler/mono/src/layout.rs @@ -168,6 +168,7 @@ impl<'a> LambdaSet<'a> { ) -> Layout<'a> { if let [] = self.set { // TERRIBLE HACK for builting functions + panic!(); Layout::FunctionPointer(argument_layouts, ret_layout) } else { match self.representation { diff --git a/compiler/test_gen/src/gen_list.rs b/compiler/test_gen/src/gen_list.rs index 4ec2a79c99..bb8a7483fb 100644 --- a/compiler/test_gen/src/gen_list.rs +++ b/compiler/test_gen/src/gen_list.rs @@ -1809,12 +1809,7 @@ fn list_keep_errs() { assert_evals_to!( indoc!( r#" - mapErr = \result, f -> - when result is - Err e -> Err ( f e ) - Ok v -> Ok v - - List.keepErrs [0,1,2] (\x -> x % 0 |> mapErr (\_ -> 32)) + List.keepErrs [0,1,2] (\x -> x % 0 |> Result.mapErr (\_ -> 32)) "# ), &[32, 32, 32],