╭ bitcast.zig ──────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
.. conflicting_externs/ hasdecl/ import/ namespace_depends_on_compile_var/ pub_enum/ x86_64/ zon/ abs.zig addrspace_and_linksection.zig align.zig alignof.zig array.zig asm.zig atomics.zig backing_int.zig basic.zig bit_shifting.zig ╭─────────────────────────────────╮ │bitcast.zig │ ╰─────────────────────────────────╯ bitreverse.zig bool.zig builtin_functions_returning_void_ byteswap.zig byval_arg_var.zig call.zig cast.zig cast_int.zig comptime_memory.zig const_slice_child.zig decl_literals.zig decltest.zig defer.zig destructure.zig duplicated_test_names.zig enum.zig error.zig eval.zig export_builtin.zig export_c_keywords.zig export_keyword.zig export_self_referential_type_info extern.zig extern_struct_zero_size_fields.zi field_parent_ptr.zig file_to_embed.txt floatop.zig fn.zig fn_delegation.zig fn_in_struct_in_comptime.zig for.zig generics.zig globals.zig hasdecl.zig hasfield.zig if.zig import.zig import_c_keywords.zig incomplete_struct_param_tld.zig inline_switch.zig int128.zig int_comparison_elision.zig ir_block_deps.zig lower_strlit_to_vector.zig math.zig maximum_minimum.zig member_func.zig memcpy.zig memmove.zig memset.zig merge_error_sets.zig muladd.zig multiple_externs_with_conflicting namespace_depends_on_compile_var. nan.zig null.zig optional.zig overlapping_assign.zig packed-struct.zig packed-union.zig packed_struct_explicit_backing_in pointers.zig popcount.zig prefetch.zig ptrcast.zig ptrfromint.zig pub_enum.zig ref_var_in_if_after_if_2nd_switch reflection.zig return_address.zig saturating_arithmetic.zig select.zig shuffle.zig sizeof_and_typeof.zig slice.zig slice_sentinel_comptime.zig spirv.zig splat.zig src.zig string_literals.zig struct.zig struct_contains_null_ptr_itself.z struct_contains_slice_of_itself.z switch.zig switch_loop.zig switch_on_captured_error.zig switch_prong_err_enum.zig switch_prong_implicit_cast.zig this.zig threadlocal.zig truncate.zig try.zig tuple.zig tuple_declarations.zig type.zig type_info.zig typename.zig undefined.zig underscore.zig union.zig var_args.zig vector.zig void.zig wasm.zig while.zig widening.zig wrapping_arithmetic.zig x86_64.zig zero.bin zon.zig
1 const std = @import("std"); 2 const builtin = @import("builtin"); 3 const assert = std.debug.assert; 4 const expect = std.testing.expect; 5 const expectEqual = std.testing.expectEqual; 6 const math = std.math; 7 const maxInt = std.math.maxInt; 8 const minInt = std.math.minInt; 9 const native_endian = builtin.target.cpu.arch.endian(); 10 11 test "@bitCast iX -> uX (32, 64)" { 12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 13 14 const bit_values = [_]usize{ 32, 64 }; 15 16 inline for (bit_values) |bits| { 17 try testBitCast(bits); 18 try comptime testBitCast(bits); 19 } 20 } 21 22 test "@bitCast iX -> uX (8, 16, 128)" { 23 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 24 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 25 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 26 const bit_values = [_]usize{ 8, 16, 128 }; 27 28 inline for (bit_values) |bits| { 29 try testBitCast(bits); 30 try comptime testBitCast(bits); 31 } 32 } 33 34 test "@bitCast iX -> uX exotic integers" { 35 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 36 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 37 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 38 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 39 40 const bit_values = [_]usize{ 1, 48, 27, 512, 493, 293, 125, 204, 112 }; 41 42 inline for (bit_values) |bits| { 43 try testBitCast(bits); 44 try comptime testBitCast(bits); 45 } 46 } 47 48 fn testBitCast(comptime N: usize) !void { 49 const iN = @Int(.signed, N); 50 const uN = @Int(.unsigned, N); 51 52 try expect(conv_iN(N, -1) == maxInt(uN)); 53 try expect(conv_uN(N, maxInt(uN)) == -1); 54 55 try expect(conv_iN(N, maxInt(iN)) == maxInt(iN)); 56 try expect(conv_uN(N, maxInt(iN)) == maxInt(iN)); 57 58 try expect(conv_uN(N, 1 << (N - 1)) == minInt(iN)); 59 try expect(conv_iN(N, minInt(iN)) == (1 << (N - 1))); 60 61 try expect(conv_uN(N, 0) == 0); 62 try expect(conv_iN(N, 0) == 0); 63 64 if (N > 24) { 65 try expect(conv_uN(N, 0xf23456) == 0xf23456); 66 } 67 } 68 69 fn conv_iN(comptime N: usize, x: @Int(.signed, N)) @Int(.unsigned, N) { 70 return @as(@Int(.unsigned, N), @bitCast(x)); 71 } 72 73 fn conv_uN(comptime N: usize, x: @Int(.unsigned, N)) @Int(.signed, N) { 74 return @as(@Int(.signed, N), @bitCast(x)); 75 } 76 77 test "nested bitcast" { 78 const S = struct { 79 fn moo(x: isize) !void { 80 try expect(@as(isize, @intCast(42)) == x); 81 } 82 83 fn foo(x: isize) !void { 84 try @This().moo( 85 @as(isize, @bitCast(if (x != 0) @as(usize, @bitCast(x)) else @as(usize, @bitCast(x)))), 86 ); 87 } 88 }; 89 90 try S.foo(42); 91 try comptime S.foo(42); 92 } 93 94 // issue #3010: compiler segfault 95 test "bitcast literal [4]u8 param to u32" { 96 const ip = @as(u32, @bitCast([_]u8{ 255, 255, 255, 255 })); 97 try expect(ip == maxInt(u32)); 98 } 99 100 test "bitcast generates a temporary value" { 101 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 102 103 var y: u16 = 0x55AA; 104 _ = &y; 105 const x: u16 = @bitCast(@as([2]u8, @bitCast(y))); 106 try expect(y == x); 107 } 108 109 test "@bitCast packed structs at runtime and comptime" { 110 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 111 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 112 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 113 114 const Full = packed struct { 115 number: u16, 116 }; 117 const Divided = packed struct { 118 half1: u8, 119 quarter3: u4, 120 quarter4: u4, 121 }; 122 const S = struct { 123 fn doTheTest() !void { 124 var full = Full{ .number = 0x1234 }; 125 _ = &full; 126 const two_halves: Divided = @bitCast(full); 127 try expect(two_halves.half1 == 0x34); 128 try expect(two_halves.quarter3 == 0x2); 129 try expect(two_halves.quarter4 == 0x1); 130 } 131 }; 132 try S.doTheTest(); 133 try comptime S.doTheTest(); 134 } 135 136 test "bitcast packed struct to integer and back" { 137 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 138 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 140 141 const LevelUpMove = packed struct { 142 move_id: u9, 143 level: u7, 144 }; 145 const S = struct { 146 fn doTheTest() !void { 147 var move = LevelUpMove{ .move_id = 1, .level = 2 }; 148 _ = &move; 149 const v: u16 = @bitCast(move); 150 const back_to_a_move: LevelUpMove = @bitCast(v); 151 try expect(back_to_a_move.move_id == 1); 152 try expect(back_to_a_move.level == 2); 153 } 154 }; 155 try S.doTheTest(); 156 try comptime S.doTheTest(); 157 } 158 159 test "implicit cast to error union by returning" { 160 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 161 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 162 163 const S = struct { 164 fn entry() !void { 165 try expect((func(-1) catch unreachable) == maxInt(u64)); 166 } 167 pub fn func(sz: i64) anyerror!u64 { 168 return @as(u64, @bitCast(sz)); 169 } 170 }; 171 try S.entry(); 172 try comptime S.entry(); 173 } 174 175 test "bitcast packed struct literal to byte" { 176 const Foo = packed struct { 177 value: u8, 178 }; 179 const casted = @as(u8, @bitCast(Foo{ .value = 0xF })); 180 try expect(casted == 0xf); 181 } 182 183 test "comptime bitcast used in expression has the correct type" { 184 const Foo = packed struct { 185 value: u8, 186 }; 187 try expect(@as(u8, @bitCast(Foo{ .value = 0xF })) == 0xf); 188 } 189 190 test "bitcast passed as tuple element" { 191 const S = struct { 192 fn foo(args: anytype) !void { 193 comptime assert(@TypeOf(args[0]) == f32); 194 try expect(args[0] == 12.34); 195 } 196 }; 197 try S.foo(.{@as(f32, @bitCast(@as(u32, 0x414570A4)))}); 198 } 199 200 test "triple level result location with bitcast sandwich passed as tuple element" { 201 const S = struct { 202 fn foo(args: anytype) !void { 203 comptime assert(@TypeOf(args[0]) == f64); 204 try expect(args[0] > 12.33 and args[0] < 12.35); 205 } 206 }; 207 try S.foo(.{@as(f64, @as(f32, @bitCast(@as(u32, 0x414570A4))))}); 208 } 209 210 test "@bitCast packed struct of floats" { 211 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 212 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 213 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 214 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 215 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 216 217 const Foo = packed struct { 218 a: f16 = 0, 219 b: f32 = 1, 220 c: f64 = 2, 221 d: f128 = 3, 222 }; 223 224 const Foo2 = packed struct { 225 a: f16 = 0, 226 b: f32 = 1, 227 c: f64 = 2, 228 d: f128 = 3, 229 }; 230 231 const S = struct { 232 fn doTheTest() !void { 233 var foo = Foo{}; 234 _ = &foo; 235 const v: Foo2 = @bitCast(foo); 236 try expect(v.a == foo.a); 237 try expect(v.b == foo.b); 238 try expect(v.c == foo.c); 239 try expect(v.d == foo.d); 240 } 241 }; 242 try S.doTheTest(); 243 try comptime S.doTheTest(); 244 } 245 246 test "comptime @bitCast packed struct to int and back" { 247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 248 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 249 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 250 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 251 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 252 253 const S = packed struct { 254 void: void = {}, 255 uint: u8 = 13, 256 uint_bit_aligned: u3 = 2, 257 iint_pos: i4 = 1, 258 iint_neg4: i3 = -4, 259 iint_neg2: i3 = -2, 260 float: f32 = 3.14, 261 @"enum": enum(u2) { A, B = 1, C, D } = .B, 262 }; 263 const Int = @typeInfo(S).@"struct".backing_integer.?; 264 265 // S -> Int 266 var s: S = .{}; 267 _ = &s; 268 try expectEqual(@as(Int, @bitCast(s)), comptime @as(Int, @bitCast(S{}))); 269 270 // Int -> S 271 var i: Int = 0; 272 _ = &i; 273 const rt_cast = @as(S, @bitCast(i)); 274 const ct_cast = comptime @as(S, @bitCast(@as(Int, 0))); 275 inline for (@typeInfo(S).@"struct".field_names) |field_name| { 276 try expectEqual(@field(rt_cast, field_name), @field(ct_cast, field_name)); 277 } 278 } 279 280 test "bitcast vector to integer and back" { 281 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 282 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 283 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 284 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 285 286 var vec: @Vector(16, bool) = @splat(true); 287 vec[1] = false; 288 289 const int: u16 = @bitCast(vec); 290 try expect(int == 0b1111_1111_1111_1101); 291 292 const vec_again: @Vector(16, bool) = @bitCast(int); 293 try expect(vec_again[0]); 294 try expect(!vec_again[1]); 295 try expect(vec_again[2]); 296 try expect(vec_again[3]); 297 try expect(vec_again[4]); 298 try expect(vec_again[5]); 299 try expect(vec_again[6]); 300 try expect(vec_again[7]); 301 try expect(vec_again[8]); 302 try expect(vec_again[9]); 303 try expect(vec_again[10]); 304 try expect(vec_again[11]); 305 try expect(vec_again[12]); 306 try expect(vec_again[13]); 307 try expect(vec_again[14]); 308 try expect(vec_again[15]); 309 310 const int_again: u16 = @bitCast(vec_again); 311 try expect(int_again == 0b1111_1111_1111_1101); 312 } 313 314 fn bitCastWrapper16(x: f16) u16 { 315 return @as(u16, @bitCast(x)); 316 } 317 fn bitCastWrapper32(x: f32) u32 { 318 return @as(u32, @bitCast(x)); 319 } 320 fn bitCastWrapper64(x: f64) u64 { 321 return @as(u64, @bitCast(x)); 322 } 323 fn bitCastWrapper128(x: f128) u128 { 324 return @as(u128, @bitCast(x)); 325 } 326 test "bitcast nan float does not modify signaling bit" { 327 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 328 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 329 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 330 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; 331 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; 332 333 const snan_u16: u16 = 0x7D00; 334 const snan_u32: u32 = 0x7FA00000; 335 const snan_u64: u64 = 0x7FF4000000000000; 336 const snan_u128: u128 = 0x7FFF4000000000000000000000000000; 337 338 // 16 bit 339 const snan_f16_const = math.snan(f16); 340 try expectEqual(snan_u16, @as(u16, @bitCast(snan_f16_const))); 341 try expectEqual(snan_u16, bitCastWrapper16(snan_f16_const)); 342 343 var snan_f16_var = math.snan(f16); 344 _ = &snan_f16_var; 345 try expectEqual(snan_u16, @as(u16, @bitCast(snan_f16_var))); 346 try expectEqual(snan_u16, bitCastWrapper16(snan_f16_var)); 347 348 // 32 bit 349 const snan_f32_const = math.snan(f32); 350 try expectEqual(snan_u32, @as(u32, @bitCast(snan_f32_const))); 351 try expectEqual(snan_u32, bitCastWrapper32(snan_f32_const)); 352 353 var snan_f32_var = math.snan(f32); 354 _ = &snan_f32_var; 355 try expectEqual(snan_u32, @as(u32, @bitCast(snan_f32_var))); 356 try expectEqual(snan_u32, bitCastWrapper32(snan_f32_var)); 357 358 // 64 bit 359 const snan_f64_const = math.snan(f64); 360 try expectEqual(snan_u64, @as(u64, @bitCast(snan_f64_const))); 361 try expectEqual(snan_u64, bitCastWrapper64(snan_f64_const)); 362 363 var snan_f64_var = math.snan(f64); 364 _ = &snan_f64_var; 365 try expectEqual(snan_u64, @as(u64, @bitCast(snan_f64_var))); 366 try expectEqual(snan_u64, bitCastWrapper64(snan_f64_var)); 367 368 // 128 bit 369 const snan_f128_const = math.snan(f128); 370 try expectEqual(snan_u128, @as(u128, @bitCast(snan_f128_const))); 371 try expectEqual(snan_u128, bitCastWrapper128(snan_f128_const)); 372 373 var snan_f128_var = math.snan(f128); 374 _ = &snan_f128_var; 375 try expectEqual(snan_u128, @as(u128, @bitCast(snan_f128_var))); 376 try expectEqual(snan_u128, bitCastWrapper128(snan_f128_var)); 377 } 378 379 test "@bitCast of packed struct of bools all true" { 380 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 381 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 382 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO 383 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO 384 385 const P = packed struct { 386 b0: bool, 387 b1: bool, 388 b2: bool, 389 b3: bool, 390 }; 391 var p = std.mem.zeroes(P); 392 p.b0 = true; 393 p.b1 = true; 394 p.b2 = true; 395 p.b3 = true; 396 try expect(@as(u8, @as(u4, @bitCast(p))) == 15); 397 } 398 399 test "@bitCast of packed struct of bools all false" { 400 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 401 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 402 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO 403 404 const P = packed struct { 405 b0: bool, 406 b1: bool, 407 b2: bool, 408 b3: bool, 409 }; 410 var p = std.mem.zeroes(P); 411 p.b0 = false; 412 p.b1 = false; 413 p.b2 = false; 414 p.b3 = false; 415 try expect(@as(u8, @as(u4, @bitCast(p))) == 0); 416 } 417 418 test "@bitCast of packed struct with void field to integer" { 419 const S = packed struct(u8) { 420 v: void, 421 x: u8, 422 423 fn doTheTest(x: u8) !void { 424 // Intentionally using `@as` to avoid RLS which masks the bug 425 const foo = @as(@This(), .{ .v = {}, .x = x }); 426 const as_int: u8 = @bitCast(foo); 427 try expect(as_int == x); 428 } 429 }; 430 try S.doTheTest(123); 431 try comptime S.doTheTest(123); 432 } 433 434 test "@bitCast of packed struct with void field and multiple integers" { 435 const S = packed struct { 436 x: u8, 437 v: void, 438 y: u8, 439 440 fn doTheTest(x: u8, y: u8) !void { 441 const foo = @as(@This(), .{ .x = x, .v = {}, .y = y }); 442 const as_int: u16 = @bitCast(foo); 443 try expect(as_int == @as(u16, y) << 8 | x); 444 } 445 }; 446 try S.doTheTest(123, 45); 447 try comptime S.doTheTest(123, 45); 448 } 449 450 test "@bitCast vector to array with different element size" { 451 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 452 453 const static = struct { 454 fn doTheTest(v: @Vector(4, u5)) !void { 455 const result: [5]u4 = @bitCast(v); 456 // See the definition of `v` in the test proper for these values. 457 try expect(result[0] == 0b0010); 458 try expect(result[1] == 0b1110); 459 try expect(result[2] == 0b0101); 460 try expect(result[3] == 0b0110); 461 try expect(result[4] == 0b0000); 462 } 463 }; 464 // The strange digit groupings here are to indicate how this maps to `expected` above. 465 const v: @Vector(4, u5) = .{ 466 0b0_0010, 467 0b01_111, 468 0b110_01, 469 0b0000_0, 470 }; 471 try static.doTheTest(v); 472 try comptime static.doTheTest(v); 473 } 474 475 test "@bitCast packed struct to array of bits" { 476 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 477 478 const S = packed struct(u16) { 479 foo: u5, 480 bar: i7, 481 baz: u3, 482 qux: bool, 483 fn doTheTest(val: @This(), comptime Bits: type) !void { 484 const bits: Bits = @bitCast(val); 485 486 // foo 487 try expect(bits[0] == 1); 488 try expect(bits[1] == 0); 489 try expect(bits[2] == 0); 490 try expect(bits[3] == 1); 491 try expect(bits[4] == 0); 492 // bar 493 try expect(bits[5] == 0); 494 try expect(bits[6] == 1); 495 try expect(bits[7] == 1); 496 try expect(bits[8] == 1); 497 try expect(bits[9] == 1); 498 try expect(bits[10] == 1); 499 try expect(bits[11] == 1); 500 // baz 501 try expect(bits[12] == 0); 502 try expect(bits[13] == 1); 503 try expect(bits[14] == 0); 504 // qux 505 try expect(bits[15] == 1); 506 } 507 }; 508 509 const val: S = .{ 510 .foo = 0b01001, 511 .bar = -2, 512 .baz = 0b010, 513 .qux = true, 514 }; 515 516 try val.doTheTest(@Vector(16, u1)); 517 try val.doTheTest([16]u1); 518 519 try comptime val.doTheTest(@Vector(16, u1)); 520 try comptime val.doTheTest([16]u1); 521 } 522 523 test "@bitCast nested arrays of vectors" { 524 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 525 526 const Src = [2][2]@Vector(4, u5); 527 const Dest = [5]@Vector(2, u8); 528 529 // The strange digit groupings here are to indicate how this maps to the output. 530 const src: Src = .{ .{ 531 .{ 0b00011, 0b00_100, 0b11100, 0b0010_1 }, 532 .{ 0b1_0110, 0b11011, 0b101_10, 0b10101 }, 533 }, .{ 534 .{ 0b10101, 0b00_001, 0b01011, 0b0001_0 }, 535 .{ 0b0_0001, 0b01111, 0b111_10, 0b00001 }, 536 } }; 537 538 const expected: Dest = .{ 539 .{ 0b10000011, 0b11110000 }, 540 .{ 0b01100010, 0b10110111 }, 541 .{ 0b10101101, 0b00110101 }, 542 .{ 0b00101100, 0b00010001 }, 543 .{ 0b10011110, 0b00001111 }, 544 }; 545 546 const static = struct { 547 fn doTheTest(src_arg: Src) !void { 548 const actual: Dest = @bitCast(src_arg); 549 for (actual, expected) |actual_vec, expected_vec| { 550 try expect(actual_vec[0] == expected_vec[0]); 551 try expect(actual_vec[1] == expected_vec[1]); 552 } 553 } 554 }; 555 556 try static.doTheTest(src); 557 try comptime static.doTheTest(src); 558 } 559 560 test "@bitCast nested arrays of bool to scalar" { 561 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 562 563 const static = struct { 564 fn doTheTest(src: [4][4]bool) !void { 565 const result: u16 = @bitCast(src); 566 try expect(result == 0b1100_0101_1010_0011); 567 } 568 }; 569 const src: [4][4]bool = .{ 570 .{ true, true, false, false }, // 0b0011 571 .{ false, true, false, true }, // 0b1010 572 .{ true, false, true, false }, // 0b0101 573 .{ false, false, true, true }, // 0b1100 574 }; 575 try static.doTheTest(src); 576 try comptime static.doTheTest(src); 577 } 578 579 test "@bitCast deeply nested arrays to scalar" { 580 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 581 582 const static = struct { 583 fn doTheTest(src: [2][1][3][5]u4) !void { 584 const signed: i120 = @bitCast(src); 585 try expect(signed < 0); // top nibble is 0x8 so sign bit is 1 586 const unsigned: u120 = @bitCast(src); 587 try expect(unsigned == 0x8873B_5BF6F_F4020_0E7AC_1EFED_40F51); 588 try expect(@as(i120, @bitCast(unsigned)) == signed); 589 try expect(@as(u120, @bitCast(signed)) == unsigned); 590 } 591 }; 592 const src: [2][1][3][5]u4 = .{ .{.{ 593 .{ 0x1, 0x5, 0xF, 0x0, 0x4 }, 594 .{ 0xD, 0xE, 0xF, 0xE, 0x1 }, 595 .{ 0xC, 0xA, 0x7, 0xE, 0x0 }, 596 }}, .{.{ 597 .{ 0x0, 0x2, 0x0, 0x4, 0xF }, 598 .{ 0xF, 0x6, 0xF, 0xB, 0x5 }, 599 .{ 0xB, 0x3, 0x7, 0x8, 0x8 }, 600 }} }; 601 try static.doTheTest(src); 602 try comptime static.doTheTest(src); 603 } 604