From 25ec2dbc1e2302d1138749262b588d3e438fcd55 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Sat, 17 Oct 2020 18:04:53 -0600 Subject: [PATCH] Add builtin.Signedness, use it instead of is_signed --- lib/std/builtin.zig | 9 ++++- lib/std/fmt.zig | 2 +- lib/std/io/serialization.zig | 2 +- lib/std/json/write_stream.zig | 2 +- lib/std/leb128.zig | 4 +-- lib/std/math.zig | 44 ++++++++++++------------ lib/std/math/big.zig | 2 +- lib/std/math/big/int.zig | 18 +++++----- lib/std/math/powi.zig | 2 +- lib/std/meta.zig | 9 ++--- lib/std/meta/trait.zig | 4 +-- lib/std/os.zig | 7 +--- lib/std/os/linux.zig | 4 +-- lib/std/packed_int_array.zig | 4 +-- lib/std/rand.zig | 18 +++++----- lib/std/start.zig | 4 +-- src/Module.zig | 8 ++--- src/codegen.zig | 24 +++++-------- src/link/Elf.zig | 5 ++- src/stage1/ir.cpp | 14 ++++---- src/type.zig | 54 +++++++++++++++--------------- src/value.zig | 17 +++++----- src/zir.zig | 5 ++- test/compile_errors.zig | 23 +++++++------ test/stage1/behavior/type.zig | 12 +++---- test/stage1/behavior/type_info.zig | 2 +- 26 files changed, 149 insertions(+), 150 deletions(-) diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 19d333713..20195bf5a 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -209,7 +209,7 @@ pub const TypeInfo = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const Int = struct { - is_signed: bool, + signedness: Signedness, bits: comptime_int, }; @@ -438,6 +438,13 @@ pub const Endian = enum { Little, }; +/// This data structure is used by the Zig language code generation and +/// therefore must be kept in sync with the compiler implementation. +pub const Signedness = enum { + signed, + unsigned, +}; + /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const OutputMode = enum { diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 81d7ce588..0cb5137b2 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -1028,7 +1028,7 @@ pub fn formatInt( if (a == 0) break; } - if (value_info.is_signed) { + if (value_info.signedness == .signed) { if (value < 0) { // Negative integer index -= 1; diff --git a/lib/std/io/serialization.zig b/lib/std/io/serialization.zig index 59a6de358..3fbc20324 100644 --- a/lib/std/io/serialization.zig +++ b/lib/std/io/serialization.zig @@ -73,7 +73,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, if (int_size == 1) { if (t_bit_count == 8) return @bitCast(T, buffer[0]); - const PossiblySignedByte = std.meta.Int(if (@typeInfo(T).Int.is_signed) .signed else .unsigned, 8); + const PossiblySignedByte = std.meta.Int(@typeInfo(T).Int.signedness, 8); return @truncate(T, @bitCast(PossiblySignedByte, buffer[0])); } diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig index 59bebd69d..ee2c12154 100644 --- a/lib/std/json/write_stream.zig +++ b/lib/std/json/write_stream.zig @@ -167,7 +167,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { self.popState(); return; } - if (value < 4503599627370496 and (!info.is_signed or value > -4503599627370496)) { + if (value < 4503599627370496 and (info.signedness == .unsigned or value > -4503599627370496)) { try self.stream.print("{}", .{value}); self.popState(); return; diff --git a/lib/std/leb128.zig b/lib/std/leb128.zig index 2fa5776e1..2a8a6fc2f 100644 --- a/lib/std/leb128.zig +++ b/lib/std/leb128.zig @@ -297,8 +297,8 @@ test "deserialize unsigned LEB128" { fn test_write_leb128(value: anytype) !void { const T = @TypeOf(value); - const t_signed = @typeInfo(T).Int.is_signed; - const signedness = if (t_signed) .signed else .unsigned; + const signedness = @typeInfo(T).Int.signedness; + const t_signed = signedness == .signed; const writeStream = if (t_signed) writeILEB128 else writeULEB128; const readStream = if (t_signed) readILEB128 else readULEB128; diff --git a/lib/std/math.zig b/lib/std/math.zig index 39b1471e7..4fc9eb40e 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -313,7 +313,7 @@ pub fn floatExponentBits(comptime T: type) comptime_int { pub fn Min(comptime A: type, comptime B: type) type { switch (@typeInfo(A)) { .Int => |a_info| switch (@typeInfo(B)) { - .Int => |b_info| if (!a_info.is_signed and !b_info.is_signed) { + .Int => |b_info| if (a_info.signedness == .unsigned and b_info.signedness == .unsigned) { if (a_info.bits < b_info.bits) { return A; } else { @@ -450,7 +450,7 @@ pub fn shl(comptime T: type, a: T, shift_amt: anytype) T { } }; - if (@TypeOf(shift_amt) == comptime_int or @typeInfo(@TypeOf(shift_amt)).Int.is_signed) { + if (@TypeOf(shift_amt) == comptime_int or @typeInfo(@TypeOf(shift_amt)).Int.signedness == .signed) { if (shift_amt < 0) { return a >> casted_shift_amt; } @@ -490,7 +490,7 @@ pub fn shr(comptime T: type, a: T, shift_amt: anytype) T { } }; - if (@TypeOf(shift_amt) == comptime_int or @typeInfo(@TypeOf(shift_amt)).Int.is_signed) { + if (@TypeOf(shift_amt) == comptime_int or @typeInfo(@TypeOf(shift_amt)).Int.signedness == .signed) { if (shift_amt < 0) { return a << casted_shift_amt; } @@ -518,12 +518,12 @@ test "math.shr" { pub fn rotr(comptime T: type, x: T, r: anytype) T { if (@typeInfo(T) == .Vector) { const C = @typeInfo(T).Vector.child; - if (@typeInfo(C).Int.is_signed) { + if (@typeInfo(C).Int.signedness == .signed) { @compileError("cannot rotate signed integers"); } const ar = @intCast(Log2Int(C), @mod(r, @typeInfo(C).Int.bits)); return (x >> @splat(@typeInfo(T).Vector.len, ar)) | (x << @splat(@typeInfo(T).Vector.len, 1 + ~ar)); - } else if (@typeInfo(T).Int.is_signed) { + } else if (@typeInfo(T).Int.signedness == .signed) { @compileError("cannot rotate signed integer"); } else { const ar = @mod(r, @typeInfo(T).Int.bits); @@ -546,12 +546,12 @@ test "math.rotr" { pub fn rotl(comptime T: type, x: T, r: anytype) T { if (@typeInfo(T) == .Vector) { const C = @typeInfo(T).Vector.child; - if (@typeInfo(C).Int.is_signed) { + if (@typeInfo(C).Int.signedness == .signed) { @compileError("cannot rotate signed integers"); } const ar = @intCast(Log2Int(C), @mod(r, @typeInfo(C).Int.bits)); return (x << @splat(@typeInfo(T).Vector.len, ar)) | (x >> @splat(@typeInfo(T).Vector.len, 1 +% ~ar)); - } else if (@typeInfo(T).Int.is_signed) { + } else if (@typeInfo(T).Int.signedness == .signed) { @compileError("cannot rotate signed integer"); } else { const ar = @mod(r, @typeInfo(T).Int.bits); @@ -585,7 +585,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t if (from == 0 and to == 0) { return u0; } - const sign: std.meta.Signedness = if (from < 0) .signed else .unsigned; + const sign: std.builtin.Signedness = if (from < 0) .signed else .unsigned; const largest_positive_integer = max(if (from < 0) (-from) - 1 else from, to); // two's complement const base = log2(largest_positive_integer); const upper = (1 << base) - 1; @@ -658,7 +658,7 @@ fn testOverflow() void { pub fn absInt(x: anytype) !@TypeOf(x) { const T = @TypeOf(x); comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt - comptime assert(@typeInfo(T).Int.is_signed); // must pass a signed integer to absInt + comptime assert(@typeInfo(T).Int.signedness == .signed); // must pass a signed integer to absInt if (x == minInt(@TypeOf(x))) { return error.Overflow; @@ -691,7 +691,7 @@ fn testAbsFloat() void { pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T { @setRuntimeSafety(false); if (denominator == 0) return error.DivisionByZero; - if (@typeInfo(T) == .Int and @typeInfo(T).Int.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow; + if (@typeInfo(T) == .Int and @typeInfo(T).Int.signedness == .signed and numerator == minInt(T) and denominator == -1) return error.Overflow; return @divTrunc(numerator, denominator); } @@ -712,7 +712,7 @@ fn testDivTrunc() void { pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T { @setRuntimeSafety(false); if (denominator == 0) return error.DivisionByZero; - if (@typeInfo(T) == .Int and @typeInfo(T).Int.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow; + if (@typeInfo(T) == .Int and @typeInfo(T).Int.signedness == .signed and numerator == minInt(T) and denominator == -1) return error.Overflow; return @divFloor(numerator, denominator); } @@ -786,7 +786,7 @@ fn testDivCeil() void { pub fn divExact(comptime T: type, numerator: T, denominator: T) !T { @setRuntimeSafety(false); if (denominator == 0) return error.DivisionByZero; - if (@typeInfo(T) == .Int and @typeInfo(T).Int.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow; + if (@typeInfo(T) == .Int and @typeInfo(T).Int.signedness == .signed and numerator == minInt(T) and denominator == -1) return error.Overflow; const result = @divTrunc(numerator, denominator); if (result * denominator != numerator) return error.UnexpectedRemainder; return result; @@ -892,7 +892,7 @@ test "math.absCast" { /// Returns the negation of the integer parameter. /// Result is a signed integer. pub fn negateCast(x: anytype) !std.meta.Int(.signed, std.meta.bitCount(@TypeOf(x))) { - if (@typeInfo(@TypeOf(x)).Int.is_signed) return negate(x); + if (@typeInfo(@TypeOf(x)).Int.signedness == .signed) return negate(x); const int = std.meta.Int(.signed, std.meta.bitCount(@TypeOf(x))); if (x > -minInt(int)) return error.Overflow; @@ -981,11 +981,11 @@ fn testFloorPowerOfTwo() void { /// Returns the next power of two (if the value is not already a power of two). /// Only unsigned integers can be used. Zero is not an allowed input. /// Result is a type with 1 more bit than the input type. -pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) std.meta.Int(if (@typeInfo(T).Int.is_signed) .signed else .unsigned, @typeInfo(T).Int.bits + 1) { +pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) std.meta.Int(@typeInfo(T).Int.signedness, @typeInfo(T).Int.bits + 1) { comptime assert(@typeInfo(T) == .Int); - comptime assert(!@typeInfo(T).Int.is_signed); + comptime assert(@typeInfo(T).Int.signedness == .unsigned); assert(value != 0); - comptime const PromotedType = std.meta.Int(if (@typeInfo(T).Int.is_signed) .signed else .unsigned, @typeInfo(T).Int.bits + 1); + comptime const PromotedType = std.meta.Int(@typeInfo(T).Int.signedness, @typeInfo(T).Int.bits + 1); comptime const shiftType = std.math.Log2Int(PromotedType); return @as(PromotedType, 1) << @intCast(shiftType, @typeInfo(T).Int.bits - @clz(T, value - 1)); } @@ -996,8 +996,8 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) std.meta.Int(if (@typeI pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) { comptime assert(@typeInfo(T) == .Int); const info = @typeInfo(T).Int; - comptime assert(!info.is_signed); - comptime const PromotedType = std.meta.Int(if (info.is_signed) .signed else .unsigned, info.bits + 1); + comptime assert(info.signedness == .unsigned); + comptime const PromotedType = std.meta.Int(info.signedness, info.bits + 1); comptime const overflowBit = @as(PromotedType, 1) << info.bits; var x = ceilPowerOfTwoPromote(T, value); if (overflowBit & x != 0) { @@ -1090,13 +1090,13 @@ pub fn maxInt(comptime T: type) comptime_int { const info = @typeInfo(T); const bit_count = info.Int.bits; if (bit_count == 0) return 0; - return (1 << (bit_count - @boolToInt(info.Int.is_signed))) - 1; + return (1 << (bit_count - @boolToInt(info.Int.signedness == .signed))) - 1; } pub fn minInt(comptime T: type) comptime_int { const info = @typeInfo(T); const bit_count = info.Int.bits; - if (!info.Int.is_signed) return 0; + if (info.Int.signedness == .unsigned) return 0; if (bit_count == 0) return 0; return -(1 << (bit_count - 1)); } @@ -1143,8 +1143,8 @@ test "max value type" { testing.expect(x == 2147483647); } -pub fn mulWide(comptime T: type, a: T, b: T) std.meta.Int(if (@typeInfo(T).Int.is_signed) .signed else .unsigned, @typeInfo(T).Int.bits * 2) { - const ResultInt = std.meta.Int(if (@typeInfo(T).Int.is_signed) .signed else .unsigned, @typeInfo(T).Int.bits * 2); +pub fn mulWide(comptime T: type, a: T, b: T) std.meta.Int(@typeInfo(T).Int.signedness, @typeInfo(T).Int.bits * 2) { + const ResultInt = std.meta.Int(@typeInfo(T).Int.signedness, @typeInfo(T).Int.bits * 2); return @as(ResultInt, a) * @as(ResultInt, b); } diff --git a/lib/std/math/big.zig b/lib/std/math/big.zig index 1f58af54d..5e2073954 100644 --- a/lib/std/math/big.zig +++ b/lib/std/math/big.zig @@ -17,7 +17,7 @@ pub const Log2Limb = std.math.Log2Int(Limb); comptime { assert(std.math.floorPowerOfTwo(usize, limb_info.bits) == limb_info.bits); assert(limb_info.bits <= 64); // u128 set is unsupported - assert(limb_info.is_signed == false); + assert(limb_info.signedness == .unsigned); } test "" { diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index a810334eb..dd0b92569 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -24,7 +24,7 @@ pub fn calcLimbLen(scalar: anytype) usize { const T = @TypeOf(scalar); switch (@typeInfo(T)) { .Int => |info| { - const UT = if (info.is_signed) std.meta.Int(.unsigned, info.bits - 1) else T; + const UT = if (info.signedness == .signed) std.meta.Int(.unsigned, info.bits - 1) else T; return @sizeOf(UT) / @sizeOf(Limb); }, .ComptimeInt => { @@ -187,7 +187,7 @@ pub const Mutable = struct { switch (@typeInfo(T)) { .Int => |info| { - const UT = if (info.is_signed) std.meta.Int(.unsigned, info.bits - 1) else T; + const UT = if (info.signedness == .signed) std.meta.Int(.unsigned, info.bits - 1) else T; const needed_limbs = @sizeOf(UT) / @sizeOf(Limb); assert(needed_limbs <= self.limbs.len); // value too big @@ -1054,22 +1054,22 @@ pub const Const = struct { return bits; } - pub fn fitsInTwosComp(self: Const, is_signed: bool, bit_count: usize) bool { + pub fn fitsInTwosComp(self: Const, signedness: std.builtin.Signedness, bit_count: usize) bool { if (self.eqZero()) { return true; } - if (!is_signed and !self.positive) { + if (signedness == .unsigned and !self.positive) { return false; } - const req_bits = self.bitCountTwosComp() + @boolToInt(self.positive and is_signed); + const req_bits = self.bitCountTwosComp() + @boolToInt(self.positive and signedness == .signed); return bit_count >= req_bits; } /// Returns whether self can fit into an integer of the requested type. pub fn fits(self: Const, comptime T: type) bool { const info = @typeInfo(T).Int; - return self.fitsInTwosComp(info.is_signed, info.bits); + return self.fitsInTwosComp(info.signedness, info.bits); } /// Returns the approximate size of the integer in the given base. Negative values accommodate for @@ -1110,7 +1110,7 @@ pub const Const = struct { } } - if (!info.is_signed) { + if (info.signedness == .unsigned) { return if (self.positive) @intCast(T, r) else error.NegativeIntoUnsigned; } else { if (self.positive) { @@ -1558,8 +1558,8 @@ pub const Managed = struct { return self.toConst().bitCountTwosComp(); } - pub fn fitsInTwosComp(self: Managed, is_signed: bool, bit_count: usize) bool { - return self.toConst().fitsInTwosComp(is_signed, bit_count); + pub fn fitsInTwosComp(self: Managed, signedness: std.builtin.Signedness, bit_count: usize) bool { + return self.toConst().fitsInTwosComp(signedness, bit_count); } /// Returns whether self can fit into an integer of the requested type. diff --git a/lib/std/math/powi.zig b/lib/std/math/powi.zig index 660aeddc0..8846ee883 100644 --- a/lib/std/math/powi.zig +++ b/lib/std/math/powi.zig @@ -48,7 +48,7 @@ pub fn powi(comptime T: type, x: T, y: T) (error{ // powi(x, y) = Overflow for for y >= @sizeOf(x) - 1 y > 0 // powi(x, y) = Underflow for for y > @sizeOf(x) - 1 y < 0 const bit_size = @sizeOf(T) * 8; - if (info.Int.is_signed) { + if (info.Int.signedness == .signed) { if (x == -1) { // powi(-1, y) = -1 for for y an odd integer // powi(-1, y) = 1 for for y an even integer diff --git a/lib/std/meta.zig b/lib/std/meta.zig index f1e9711b3..8919c2679 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -718,15 +718,10 @@ pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const De pub const IntType = @compileError("replaced by std.meta.Int"); -pub const Signedness = enum { - unsigned, - signed, -}; - -pub fn Int(comptime signedness: Signedness, comptime bit_count: u16) type { +pub fn Int(comptime signedness: builtin.Signedness, comptime bit_count: u16) type { return @Type(TypeInfo{ .Int = .{ - .is_signed = signedness == .signed, + .signedness = signedness, .bits = bit_count, }, }); diff --git a/lib/std/meta/trait.zig b/lib/std/meta/trait.zig index 2455542e4..a288b2adf 100644 --- a/lib/std/meta/trait.zig +++ b/lib/std/meta/trait.zig @@ -195,7 +195,7 @@ test "std.meta.trait.isPacked" { pub fn isUnsignedInt(comptime T: type) bool { return switch (@typeInfo(T)) { - .Int => |i| !i.is_signed, + .Int => |i| i.signedness == .unsigned, else => false, }; } @@ -210,7 +210,7 @@ test "isUnsignedInt" { pub fn isSignedInt(comptime T: type) bool { return switch (@typeInfo(T)) { .ComptimeInt => true, - .Int => |i| i.is_signed, + .Int => |i| i.signedness == .signed, else => false, }; } diff --git a/lib/std/os.zig b/lib/std/os.zig index 6e57c59c1..d8385e977 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -4868,12 +4868,7 @@ pub fn sendfile( var total_written: usize = 0; // Prevents EOVERFLOW. - const size_t = @Type(std.builtin.TypeInfo{ - .Int = .{ - .is_signed = false, - .bits = @typeInfo(usize).Int.bits - 1, - }, - }); + const size_t = std.meta.Int(.unsigned, @typeInfo(usize).Int.bits - 1); const max_count = switch (std.Target.current.os.tag) { .linux => 0x7ffff000, .macos, .ios, .watchos, .tvos => math.maxInt(i32), diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 02d87c606..d0bc80c64 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -777,7 +777,7 @@ pub fn seteuid(euid: uid_t) usize { // The setresuid(2) man page says that if -1 is passed the corresponding // id will not be changed. Since uid_t is unsigned, this wraps around to the // max value in C. - comptime assert(@typeInfo(uid_t) == .Int and !@typeInfo(uid_t).Int.is_signed); + comptime assert(@typeInfo(uid_t) == .Int and @typeInfo(uid_t).Int.signedness == .unsigned); return setresuid(std.math.maxInt(uid_t), euid, std.math.maxInt(uid_t)); } @@ -788,7 +788,7 @@ pub fn setegid(egid: gid_t) usize { // The setresgid(2) man page says that if -1 is passed the corresponding // id will not be changed. Since gid_t is unsigned, this wraps around to the // max value in C. - comptime assert(@typeInfo(uid_t) == .Int and !@typeInfo(uid_t).Int.is_signed); + comptime assert(@typeInfo(uid_t) == .Int and @typeInfo(uid_t).Int.signedness == .unsigned); return setresgid(std.math.maxInt(gid_t), egid, std.math.maxInt(gid_t)); } diff --git a/lib/std/packed_int_array.zig b/lib/std/packed_int_array.zig index ed22931cb..c3222c483 100644 --- a/lib/std/packed_int_array.zig +++ b/lib/std/packed_int_array.zig @@ -332,7 +332,7 @@ test "PackedIntArray" { comptime var bits = 0; inline while (bits <= max_bits) : (bits += 1) { //alternate unsigned and signed - const sign: std.meta.Signedness = if (bits % 2 == 0) .signed else .unsigned; + const sign: builtin.Signedness = if (bits % 2 == 0) .signed else .unsigned; const I = std.meta.Int(sign, bits); const PackedArray = PackedIntArray(I, int_count); @@ -384,7 +384,7 @@ test "PackedIntSlice" { comptime var bits = 0; inline while (bits <= max_bits) : (bits += 1) { //alternate unsigned and signed - const sign: std.meta.Signedness = if (bits % 2 == 0) .signed else .unsigned; + const sign: builtin.Signedness = if (bits % 2 == 0) .signed else .unsigned; const I = std.meta.Int(sign, bits); const P = PackedIntSlice(I); diff --git a/lib/std/rand.zig b/lib/std/rand.zig index 61aa2dac3..a201968a5 100644 --- a/lib/std/rand.zig +++ b/lib/std/rand.zig @@ -69,7 +69,7 @@ pub const Random = struct { /// Constant-time implementation off `uintLessThan`. /// The results of this function may be biased. pub fn uintLessThanBiased(r: *Random, comptime T: type, less_than: T) T { - comptime assert(@typeInfo(T).Int.is_signed == false); + comptime assert(@typeInfo(T).Int.signedness == .unsigned); const bits = @typeInfo(T).Int.bits; comptime assert(bits <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation! assert(0 < less_than); @@ -89,7 +89,7 @@ pub const Random = struct { /// this function is guaranteed to return. /// If you need deterministic runtime bounds, use `uintLessThanBiased`. pub fn uintLessThan(r: *Random, comptime T: type, less_than: T) T { - comptime assert(@typeInfo(T).Int.is_signed == false); + comptime assert(@typeInfo(T).Int.signedness == .unsigned); const bits = @typeInfo(T).Int.bits; comptime assert(bits <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation! assert(0 < less_than); @@ -129,7 +129,7 @@ pub const Random = struct { /// Constant-time implementation off `uintAtMost`. /// The results of this function may be biased. pub fn uintAtMostBiased(r: *Random, comptime T: type, at_most: T) T { - assert(@typeInfo(T).Int.is_signed == false); + assert(@typeInfo(T).Int.signedness == .unsigned); if (at_most == maxInt(T)) { // have the full range return r.int(T); @@ -141,7 +141,7 @@ pub const Random = struct { /// See `uintLessThan`, which this function uses in most cases, /// for commentary on the runtime of this function. pub fn uintAtMost(r: *Random, comptime T: type, at_most: T) T { - assert(@typeInfo(T).Int.is_signed == false); + assert(@typeInfo(T).Int.signedness == .unsigned); if (at_most == maxInt(T)) { // have the full range return r.int(T); @@ -154,7 +154,7 @@ pub const Random = struct { pub fn intRangeLessThanBiased(r: *Random, comptime T: type, at_least: T, less_than: T) T { assert(at_least < less_than); const info = @typeInfo(T).Int; - if (info.is_signed) { + if (info.signedness == .signed) { // Two's complement makes this math pretty easy. const UnsignedT = std.meta.Int(.unsigned, info.bits); const lo = @bitCast(UnsignedT, at_least); @@ -173,7 +173,7 @@ pub const Random = struct { pub fn intRangeLessThan(r: *Random, comptime T: type, at_least: T, less_than: T) T { assert(at_least < less_than); const info = @typeInfo(T).Int; - if (info.is_signed) { + if (info.signedness == .signed) { // Two's complement makes this math pretty easy. const UnsignedT = std.meta.Int(.unsigned, info.bits); const lo = @bitCast(UnsignedT, at_least); @@ -191,7 +191,7 @@ pub const Random = struct { pub fn intRangeAtMostBiased(r: *Random, comptime T: type, at_least: T, at_most: T) T { assert(at_least <= at_most); const info = @typeInfo(T).Int; - if (info.is_signed) { + if (info.signedness == .signed) { // Two's complement makes this math pretty easy. const UnsignedT = std.meta.Int(.unsigned, info.bits); const lo = @bitCast(UnsignedT, at_least); @@ -210,7 +210,7 @@ pub const Random = struct { pub fn intRangeAtMost(r: *Random, comptime T: type, at_least: T, at_most: T) T { assert(at_least <= at_most); const info = @typeInfo(T).Int; - if (info.is_signed) { + if (info.signedness == .signed) { // Two's complement makes this math pretty easy. const UnsignedT = std.meta.Int(.unsigned, info.bits); const lo = @bitCast(UnsignedT, at_least); @@ -288,7 +288,7 @@ pub const Random = struct { /// into an integer 0 <= result < less_than. /// This function introduces a minor bias. pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T { - comptime assert(@typeInfo(T).Int.is_signed == false); + comptime assert(@typeInfo(T).Int.signedness == .unsigned); const bits = @typeInfo(T).Int.bits; const T2 = std.meta.Int(.unsigned, bits * 2); diff --git a/lib/std/start.zig b/lib/std/start.zig index aa03b3713..a3f9de14b 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -325,7 +325,7 @@ pub fn callMain() u8 { return 0; }, .Int => |info| { - if (info.bits != 8 or info.is_signed) { + if (info.bits != 8 or info.signedness == .signed) { @compileError(bad_main_ret); } return root.main(); @@ -341,7 +341,7 @@ pub fn callMain() u8 { switch (@typeInfo(@TypeOf(result))) { .Void => return 0, .Int => |info| { - if (info.bits != 8 or info.is_signed) { + if (info.bits != 8 or info.signedness == .signed) { @compileError(bad_main_ret); } return result; diff --git a/src/Module.zig b/src/Module.zig index 81dc72e60..7ef32abcc 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -2633,7 +2633,7 @@ pub fn cmpNumeric( dest_float_type = lhs.ty; } else { const int_info = lhs.ty.intInfo(self.getTarget()); - lhs_bits = int_info.bits + @boolToInt(!int_info.signed and dest_int_is_signed); + lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed); } var rhs_bits: usize = undefined; @@ -2668,7 +2668,7 @@ pub fn cmpNumeric( dest_float_type = rhs.ty; } else { const int_info = rhs.ty.intInfo(self.getTarget()); - rhs_bits = int_info.bits + @boolToInt(!int_info.signed and dest_int_is_signed); + rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed); } const dest_type = if (dest_float_type) |ft| ft else blk: { @@ -2817,9 +2817,9 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst const src_info = inst.ty.intInfo(self.getTarget()); const dst_info = dest_type.intInfo(self.getTarget()); - if ((src_info.signed == dst_info.signed and dst_info.bits >= src_info.bits) or + if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or // small enough unsigned ints can get casted to large enough signed ints - (src_info.signed and !dst_info.signed and dst_info.bits > src_info.bits)) + (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits)) { const b = try self.requireRuntimeBlock(scope, inst.src); return self.addUnOp(b, inst.src, dest_type, .intcast, inst); diff --git a/src/codegen.zig b/src/codegen.zig index 804a9b202..48fda6f0d 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -203,7 +203,7 @@ pub fn generateSymbol( .Int => { // TODO populate .debug_info for the integer const info = typed_value.ty.intInfo(bin_file.options.target); - if (info.bits == 8 and !info.signed) { + if (info.bits == 8 and info.signedness == .unsigned) { const x = typed_value.val.toUnsignedInt(); try code.append(@intCast(u8, x)); return Result{ .appended = {} }; @@ -920,7 +920,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { const operand = try self.resolveInst(inst.operand); const info_a = inst.operand.ty.intInfo(self.target.*); const info_b = inst.base.ty.intInfo(self.target.*); - if (info_a.signed != info_b.signed) + if (info_a.signedness != info_b.signedness) return self.fail(inst.base.src, "TODO gen intcast sign safety in semantic analysis", .{}); if (info_a.bits == info_b.bits) @@ -1780,7 +1780,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { fn genCmp(self: *Self, inst: *ir.Inst.BinOp, op: math.CompareOperator) !MCValue { // No side effects, so if it's unreferenced, do nothing. if (inst.base.isUnused()) - return MCValue.dead; + return MCValue{ .dead = {} }; switch (arch) { .x86_64 => { try self.code.ensureCapacity(self.code.items.len + 8); @@ -1800,11 +1800,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { try self.genX8664BinMathCode(inst.base.src, inst.base.ty, dst_mcv, src_mcv, 7, 0x38); const info = inst.lhs.ty.intInfo(self.target.*); - if (info.signed) { - return MCValue{ .compare_flags_signed = op }; - } else { - return MCValue{ .compare_flags_unsigned = op }; - } + return switch (info.signedness) { + .signed => MCValue{ .compare_flags_signed = op }, + .unsigned => MCValue{ .compare_flags_unsigned = op }, + }; }, else => return self.fail(inst.base.src, "TODO implement cmp for {}", .{self.target.cpu.arch}), } @@ -2904,12 +2903,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { switch (mcv) { .immediate => |imm| { // This immediate is unsigned. - const U = @Type(.{ - .Int = .{ - .bits = ti.bits - @boolToInt(ti.is_signed), - .is_signed = false, - }, - }); + const U = std.meta.Int(.unsigned, ti.bits - @boolToInt(ti.signedness == .signed)); if (imm >= math.maxInt(U)) { return MCValue{ .register = try self.copyToTmpRegister(inst.src, mcv) }; } @@ -2949,7 +2943,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { }, .Int => { const info = typed_value.ty.intInfo(self.target.*); - if (info.bits > ptr_bits or info.signed) { + if (info.bits > ptr_bits or info.signedness == .signed) { return self.fail(src, "TODO const int bigger than ptr and signed int", .{}); } return MCValue{ .immediate = typed_value.val.toUnsignedInt() }; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 94a946c3c..8fb9a9395 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2443,7 +2443,10 @@ fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !vo try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); // DW.AT_encoding, DW.FORM_data1 - dbg_info_buffer.appendAssumeCapacity(if (info.signed) DW.ATE_signed else DW.ATE_unsigned); + dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) { + .signed => DW.ATE_signed, + .unsigned => DW.ATE_unsigned, + }); // DW.AT_byte_size, DW.FORM_data1 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); // DW.AT_name, DW.FORM_string diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 2ed667593..16884c675 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -25306,11 +25306,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); result->data.x_struct.fields = fields; - // is_signed: bool - ensure_field_index(result->type, "is_signed", 0); + // is_signed: Signedness + ensure_field_index(result->type, "signedness", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = ira->codegen->builtin_types.entry_bool; - fields[0]->data.x_bool = type_entry->data.integral.is_signed; + fields[0]->type = get_builtin_type(ira->codegen, "Signedness"); + bigint_init_unsigned(&fields[0]->data.x_enum_tag, !type_entry->data.integral.is_signed); // bits: u8 ensure_field_index(result->type, "bits", 1); fields[1]->special = ConstValSpecialStatic; @@ -26073,9 +26073,11 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 1); if (bi == nullptr) return ira->codegen->invalid_inst_gen->value->type; - bool is_signed; - if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_signed", 0, &is_signed))) + ZigValue *value = get_const_field(ira, source_instr->source_node, payload, "signedness", 0); + if (value == nullptr) return ira->codegen->invalid_inst_gen->value->type; + assert(value->type == get_builtin_type(ira->codegen, "Signedness")); + bool is_signed = !bigint_as_u32(&value->data.x_enum_tag); return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); } case ZigTypeIdFloat: diff --git a/src/type.zig b/src/type.zig index 31f84cdec..1f16b9d84 100644 --- a/src/type.zig +++ b/src/type.zig @@ -186,7 +186,7 @@ pub const Type = extern union { // The target will not be branched upon, because we handled target-dependent cases above. const info_a = a.intInfo(@as(Target, undefined)); const info_b = b.intInfo(@as(Target, undefined)); - return info_a.signed == info_b.signed and info_a.bits == info_b.bits; + return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits; }, .Array => { if (a.arrayLen() != b.arrayLen()) @@ -266,7 +266,7 @@ pub const Type = extern union { // Remaining cases are arbitrary sized integers. // The target will not be branched upon, because we handled target-dependent cases above. const info = self.intInfo(@as(Target, undefined)); - std.hash.autoHash(&hasher, info.signed); + std.hash.autoHash(&hasher, info.signedness); std.hash.autoHash(&hasher, info.bits); } }, @@ -1908,7 +1908,7 @@ pub const Type = extern union { } /// Asserts the type is an integer. - pub fn intInfo(self: Type, target: Target) struct { signed: bool, bits: u16 } { + pub fn intInfo(self: Type, target: Target) struct { signedness: std.builtin.Signedness, bits: u16 } { return switch (self.tag()) { .f16, .f32, @@ -1958,26 +1958,26 @@ pub const Type = extern union { .empty_struct, => unreachable, - .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits }, - .int_signed => .{ .signed = true, .bits = self.cast(Payload.IntSigned).?.bits }, - .u8 => .{ .signed = false, .bits = 8 }, - .i8 => .{ .signed = true, .bits = 8 }, - .u16 => .{ .signed = false, .bits = 16 }, - .i16 => .{ .signed = true, .bits = 16 }, - .u32 => .{ .signed = false, .bits = 32 }, - .i32 => .{ .signed = true, .bits = 32 }, - .u64 => .{ .signed = false, .bits = 64 }, - .i64 => .{ .signed = true, .bits = 64 }, - .usize => .{ .signed = false, .bits = target.cpu.arch.ptrBitWidth() }, - .isize => .{ .signed = true, .bits = target.cpu.arch.ptrBitWidth() }, - .c_short => .{ .signed = true, .bits = CType.short.sizeInBits(target) }, - .c_ushort => .{ .signed = false, .bits = CType.ushort.sizeInBits(target) }, - .c_int => .{ .signed = true, .bits = CType.int.sizeInBits(target) }, - .c_uint => .{ .signed = false, .bits = CType.uint.sizeInBits(target) }, - .c_long => .{ .signed = true, .bits = CType.long.sizeInBits(target) }, - .c_ulong => .{ .signed = false, .bits = CType.ulong.sizeInBits(target) }, - .c_longlong => .{ .signed = true, .bits = CType.longlong.sizeInBits(target) }, - .c_ulonglong => .{ .signed = false, .bits = CType.ulonglong.sizeInBits(target) }, + .int_unsigned => .{ .signedness = .unsigned, .bits = self.cast(Payload.IntUnsigned).?.bits }, + .int_signed => .{ .signedness = .signed, .bits = self.cast(Payload.IntSigned).?.bits }, + .u8 => .{ .signedness = .unsigned, .bits = 8 }, + .i8 => .{ .signedness = .signed, .bits = 8 }, + .u16 => .{ .signedness = .unsigned, .bits = 16 }, + .i16 => .{ .signedness = .signed, .bits = 16 }, + .u32 => .{ .signedness = .unsigned, .bits = 32 }, + .i32 => .{ .signedness = .signed, .bits = 32 }, + .u64 => .{ .signedness = .unsigned, .bits = 64 }, + .i64 => .{ .signedness = .signed, .bits = 64 }, + .usize => .{ .signedness = .unsigned, .bits = target.cpu.arch.ptrBitWidth() }, + .isize => .{ .signedness = .signed, .bits = target.cpu.arch.ptrBitWidth() }, + .c_short => .{ .signedness = .signed, .bits = CType.short.sizeInBits(target) }, + .c_ushort => .{ .signedness = .unsigned, .bits = CType.ushort.sizeInBits(target) }, + .c_int => .{ .signedness = .signed, .bits = CType.int.sizeInBits(target) }, + .c_uint => .{ .signedness = .unsigned, .bits = CType.uint.sizeInBits(target) }, + .c_long => .{ .signedness = .signed, .bits = CType.long.sizeInBits(target) }, + .c_ulong => .{ .signedness = .unsigned, .bits = CType.ulong.sizeInBits(target) }, + .c_longlong => .{ .signedness = .signed, .bits = CType.longlong.sizeInBits(target) }, + .c_ulonglong => .{ .signedness = .unsigned, .bits = CType.ulonglong.sizeInBits(target) }, }; } @@ -2869,7 +2869,7 @@ pub const Type = extern union { assert(self.zigTypeTag() == .Int); const info = self.intInfo(target); - if (!info.signed) { + if (info.signedness == .unsigned) { return Value.initTag(.zero); } @@ -2902,13 +2902,13 @@ pub const Type = extern union { assert(self.zigTypeTag() == .Int); const info = self.intInfo(target); - if (info.signed and (info.bits - 1) <= std.math.maxInt(u6)) { + if (info.signedness == .signed and (info.bits - 1) <= std.math.maxInt(u6)) { const payload = try arena.allocator.create(Value.Payload.Int_i64); payload.* = .{ .int = (@as(i64, 1) << @truncate(u6, info.bits - 1)) - 1, }; return Value.initPayload(&payload.base); - } else if (!info.signed and info.bits <= std.math.maxInt(u6)) { + } else if (info.signedness == .signed and info.bits <= std.math.maxInt(u6)) { const payload = try arena.allocator.create(Value.Payload.Int_u64); payload.* = .{ .int = (@as(u64, 1) << @truncate(u6, info.bits)) - 1, @@ -2917,7 +2917,7 @@ pub const Type = extern union { } var res = try std.math.big.int.Managed.initSet(&arena.allocator, 1); - try res.shiftLeft(res, info.bits - @boolToInt(info.signed)); + try res.shiftLeft(res, info.bits - @boolToInt(info.signedness == .signed)); const one = std.math.big.int.Const{ .limbs = &[_]std.math.big.Limb{1}, .positive = true, diff --git a/src/value.zig b/src/value.zig index 8cbffecab..4271ae66f 100644 --- a/src/value.zig +++ b/src/value.zig @@ -929,11 +929,10 @@ pub const Value = extern union { .bool_true, => { const info = ty.intInfo(target); - if (info.signed) { - return info.bits >= 2; - } else { - return info.bits >= 1; - } + return switch (info.signedness) { + .signed => info.bits >= 2, + .unsigned => info.bits >= 1, + }; }, .int_u64 => switch (ty.zigTypeTag()) { @@ -941,7 +940,7 @@ pub const Value = extern union { const x = self.cast(Payload.Int_u64).?.int; if (x == 0) return true; const info = ty.intInfo(target); - const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signed); + const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); return info.bits >= needed_bits; }, .ComptimeInt => return true, @@ -952,7 +951,7 @@ pub const Value = extern union { const x = self.cast(Payload.Int_i64).?.int; if (x == 0) return true; const info = ty.intInfo(target); - if (!info.signed and x < 0) + if (info.signedness == .unsigned and x < 0) return false; @panic("TODO implement i64 intFitsInType"); }, @@ -962,7 +961,7 @@ pub const Value = extern union { .int_big_positive => switch (ty.zigTypeTag()) { .Int => { const info = ty.intInfo(target); - return self.cast(Payload.IntBigPositive).?.asBigInt().fitsInTwosComp(info.signed, info.bits); + return self.cast(Payload.IntBigPositive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, @@ -970,7 +969,7 @@ pub const Value = extern union { .int_big_negative => switch (ty.zigTypeTag()) { .Int => { const info = ty.intInfo(target); - return self.cast(Payload.IntBigNegative).?.asBigInt().fitsInTwosComp(info.signed, info.bits); + return self.cast(Payload.IntBigNegative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, diff --git a/src/zir.zig b/src/zir.zig index a03b492bd..7db2a11e5 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -2687,7 +2687,10 @@ const EmitZIR = struct { }, .Int => { const info = ty.intInfo(self.old_module.getTarget()); - const signed = try self.emitPrimitive(src, if (info.signed) .@"true" else .@"false"); + const signed = try self.emitPrimitive(src, switch (info.signedness) { + .signed => .@"true", + .unsigned => .@"false", + }); const bits_payload = try self.arena.allocator.create(Value.Payload.Int_u64); bits_payload.* = .{ .int = info.bits }; const bits = try self.emitComptimeIntVal(src, Value.initPayload(&bits_payload.base)); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 48775c3bc..420ec1e56 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -72,6 +72,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:8:12: note: called from here", }); + cases.add("@Type with TypeInfo.Int", + \\const builtin = @import("builtin"); + \\export fn entry() void { + \\ _ = @Type(builtin.TypeInfo.Int { + \\ .signedness = .signed, + \\ .bits = 8, + \\ }); + \\} + , &[_][]const u8{ + "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'", + }); + cases.add("indexing a undefined slice at comptime", \\comptime { \\ var slice: []u8 = undefined; @@ -1827,17 +1839,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:4:15: error: unable to evaluate constant expression", }); - cases.add("@Type with TypeInfo.Int", - \\const builtin = @import("builtin"); - \\export fn entry() void { - \\ _ = @Type(builtin.TypeInfo.Int { - \\ .is_signed = true, - \\ .bits = 8, - \\ }); - \\} - , &[_][]const u8{ - "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'", - }); cases.add("wrong type for argument tuple to @asyncCall", \\export fn entry1() void { \\ var frame: @Frame(foo) = undefined; diff --git a/test/stage1/behavior/type.zig b/test/stage1/behavior/type.zig index 53a47228d..7b0f3a9e6 100644 --- a/test/stage1/behavior/type.zig +++ b/test/stage1/behavior/type.zig @@ -31,12 +31,12 @@ test "Type.NoReturn" { } test "Type.Int" { - testing.expect(u1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = false, .bits = 1 } })); - testing.expect(i1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = true, .bits = 1 } })); - testing.expect(u8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = false, .bits = 8 } })); - testing.expect(i8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = true, .bits = 8 } })); - testing.expect(u64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = false, .bits = 64 } })); - testing.expect(i64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = true, .bits = 64 } })); + testing.expect(u1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 1 } })); + testing.expect(i1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 1 } })); + testing.expect(u8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 8 } })); + testing.expect(i8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 8 } })); + testing.expect(u64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 64 } })); + testing.expect(i64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 64 } })); testTypes(&[_]type{ u8, u32, i64 }); } diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index 92d205935..b19a404e2 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -28,7 +28,7 @@ test "type info: integer, floating point type info" { fn testIntFloat() void { const u8_info = @typeInfo(u8); expect(u8_info == .Int); - expect(!u8_info.Int.is_signed); + expect(u8_info.Int.signedness == .unsigned); expect(u8_info.Int.bits == 8); const f64_info = @typeInfo(f64);