05-implicit-casts.ha (3182B)
1 use rt::{compile, exited, EXIT_SUCCESS}; 2 3 type subtype = struct { 4 foo: int, 5 }; 6 7 type super1 = struct { 8 foo: subtype, 9 bar: int, 10 }; 11 12 type super2 = struct { 13 subtype, 14 bar: int, 15 }; 16 17 type super3 = struct { 18 struct { foo: int }, 19 bar: int, 20 }; 21 22 fn rules() void = { 23 // Fixed precision ints 24 let _i64: i64 = 0i64; 25 _i64 = 42i8; 26 _i64 = 42i16; 27 _i64 = 42i32; 28 _i64 = 42i; 29 let _i32: i32 = 0i32; 30 _i32 = 42i8; 31 _i32 = 42i16; 32 let _i16: i16 = 0i16; 33 _i16 = 42i8; 34 let _u64: u64 = 0u64; 35 _u64 = 42u8; 36 _u64 = 42u16; 37 _u64 = 42u32; 38 _u64 = 42u; 39 let _u32: u32 = 0u32; 40 _u32 = 42u8; 41 _u32 = 42u16; 42 let _u16: u16 = 0u16; 43 _u16 = 42u8; 44 45 // Implementation-defined precision 46 if (size(int) == 8) { 47 assert(compile("fn test() void = { let i: int = 42i64; };") as exited == EXIT_SUCCESS); 48 }; 49 let i: int = 42i; 50 i = 42i32; 51 i = 42i16; 52 i = 42i8; 53 54 if (size(uint) == 8) { 55 assert(compile("fn test() void = { let u: uint = 42u64; };") as exited == EXIT_SUCCESS); 56 }; 57 let u: uint = 42u; 58 u = 42u32; 59 u = 42u16; 60 u = 42u8; 61 62 // Precision loss (should fail) 63 assert(compile("fn test() void = { let _i8: i8 = 42i16; };") as exited != EXIT_SUCCESS); 64 assert(compile("fn test() void = { let _i8: i8 = 42i32; };") as exited != EXIT_SUCCESS); 65 assert(compile("fn test() void = { let _i8: i8 = 42i64; };") as exited != EXIT_SUCCESS); 66 assert(compile("fn test() void = { let _i8: i8 = 42i; };") as exited != EXIT_SUCCESS); 67 assert(compile("fn test() void = { let _i16: i16 = 42i32; };") as exited != EXIT_SUCCESS); 68 assert(compile("fn test() void = { let _i16: i16 = 42i64; };") as exited != EXIT_SUCCESS); 69 assert(compile("fn test() void = { let _i32: i32 = 42i64; };") as exited != EXIT_SUCCESS); 70 assert(compile("fn test() void = { let _u8: u8 = 42u16; };") as exited != EXIT_SUCCESS); 71 assert(compile("fn test() void = { let _u8: u8 = 42u32; };") as exited != EXIT_SUCCESS); 72 assert(compile("fn test() void = { let _u8: u8 = 42u64; };") as exited != EXIT_SUCCESS); 73 assert(compile("fn test() void = { let _u8: u8 = 42u; };") as exited != EXIT_SUCCESS); 74 assert(compile("fn test() void = { let _u16: u16 = 42u32; };") as exited != EXIT_SUCCESS); 75 assert(compile("fn test() void = { let _u16: u16 = 42u64; };") as exited != EXIT_SUCCESS); 76 assert(compile("fn test() void = { let _u32: u32 = 42u64; };") as exited != EXIT_SUCCESS); 77 78 // Pointer conversions 79 let nptr: nullable *int = null; 80 nptr = &i; 81 let vptr: nullable *void = nptr; 82 83 // Struct subtyping 84 let sptr: *subtype = &super1 { ... }; 85 let sptr: *subtype = &super2 { ... }; 86 let sptr: *struct { foo: int } = &super3 { ... }; 87 88 // Invalid pointer conversions 89 assert(compile( 90 "fn test() void = { let x: nullable *int = null; let y: *int = x; };" 91 ) as exited != EXIT_SUCCESS); 92 assert(compile( 93 "fn test() void = { let x: int = 10; let y: *int = &x; let y: *uint = x; };" 94 ) as exited != EXIT_SUCCESS); 95 96 // Non-const from const (copy) 97 const j = 10; 98 let k = j; 99 }; 100 101 fn rvalue() i64 = { 102 return 1234; 103 }; 104 105 fn callme(in: i64) void = { 106 assert(in == 1234i64); 107 }; 108 109 fn calls() void = { 110 callme(1234); 111 }; 112 113 export fn main() void = { 114 rules(); 115 assert(rvalue() == 1234i64); 116 calls(); 117 // TODO: Expand this: 118 // - Floats 119 // - Arrays <-> slices 120 };