23-errors.ha (2278B)
1 use rt::{compile, exited, EXIT_SUCCESS}; 2 3 type err_int = !int; 4 5 fn assignability() void = { 6 // Error and non-error types are interchangable: 7 let a: !int = 10; 8 let b: int = a; 9 assert(a == b); 10 }; 11 12 type error = !void; 13 14 fn err_if_false(in: bool) (error | int) = { 15 if (in) { 16 return 1337; 17 }; 18 return error; 19 }; 20 21 fn indirect(in: bool) (error | int) = { 22 let x = err_if_false(in)?; 23 return x; 24 }; 25 26 fn propagate() void = { 27 assert(indirect(true) as int == 1337); 28 assert(indirect(false) is error); 29 }; 30 31 fn cannotignore() void = { 32 assert(compile(" 33 type error = !void; 34 35 export fn main() int = { 36 error; 37 return 42; 38 }; 39 ") as exited != EXIT_SUCCESS); 40 err_if_false(true)!; 41 }; 42 43 fn void_assignability() void = { 44 assert(compile(` 45 type err = !void; 46 47 fn reterr() (int | err) = { 48 return err; 49 }; 50 51 fn properr() void = { 52 reterr()?; 53 }; 54 55 export fn main() void = void; 56 `) as exited != EXIT_SUCCESS); // error types cannot be assigned to void 57 58 assert(compile(` 59 fn disallow_1() void = { 60 return "I am illegal"; 61 }; 62 63 fn disallow_2() void = { 64 return 12; 65 }; 66 67 export fn main() void = void; 68 `) as exited != EXIT_SUCCESS); // non-void types cannot be assigned to void 69 }; 70 71 fn measurements() void = { 72 assert(size(!int) == size(int)); 73 assert(size(!f64) == size(f64)); 74 assert(size(!(int | void)) == size((int | void))); 75 assert(size(!(i8, rune)) == size((i8, rune))); 76 assert(size(!struct { x: int, y: str }) == size(struct { x: int, y: str })); 77 assert(size(!union { x: int, y: str }) == size(union { x: int, y: str })); 78 assert(size(![2]int) == size([2]int)); 79 assert(size(![]int) == size([]int)); 80 assert(size(!*size) == size(*size)); 81 82 assert(align(!int) == align(int)); 83 assert(align(!f64) == align(f64)); 84 assert(align(!(int | void)) == align((int | void))); 85 assert(align(!(i8, rune)) == align((i8, rune))); 86 assert(align(!struct { x: int, y: str }) == align(struct { x: int, y: str })); 87 assert(align(!union { x: int, y: str }) == align(union { x: int, y: str })); 88 assert(align(![2]int) == align([2]int)); 89 assert(align(![*]int) == align([*]int)); 90 assert(align(![]int) == align([]int)); 91 assert(align(!*size) == align(*size)); 92 }; 93 94 export fn main() void = { 95 assignability(); 96 propagate(); 97 cannotignore(); 98 void_assignability(); 99 measurements(); 100 };