harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

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 };