Commit aadccc4206

Jan Prudil <57442prudil@sstebrno.eu>
2020-10-17 14:09:59
Make std.meta.Int accept a signedness parameter
1 parent 245d98d
lib/std/debug/leb128.zig
@@ -55,7 +55,7 @@ pub fn writeULEB128(writer: anytype, uint_value: anytype) !void {
     }
 }
 
-/// Read a single unsinged integer from the given memory as type T.
+/// Read a single unsigned integer from the given memory as type T.
 /// The provided slice reference will be updated to point to the byte after the last byte read.
 pub fn readULEB128Mem(comptime T: type, ptr: *[]const u8) !T {
     var buf = std.io.fixedBufferStream(ptr.*);
@@ -78,7 +78,7 @@ pub fn writeULEB128Mem(ptr: []u8, uint_value: anytype) !usize {
 /// or error.Overflow if the value cannot fit.
 pub fn readILEB128(comptime T: type, reader: anytype) !T {
     const S = if (@typeInfo(T).Int.bits < 8) i8 else T;
-    const U = std.meta.Int(false, @typeInfo(S).Int.bits);
+    const U = std.meta.Int(.unsigned, @typeInfo(S).Int.bits);
     const ShiftU = std.math.Log2Int(U);
 
     const max_group = (@typeInfo(U).Int.bits + 6) / 7;
@@ -128,7 +128,7 @@ pub fn readILEB128(comptime T: type, reader: anytype) !T {
 pub fn writeILEB128(writer: anytype, int_value: anytype) !void {
     const T = @TypeOf(int_value);
     const S = if (@typeInfo(T).Int.bits < 8) i8 else T;
-    const U = std.meta.Int(false, @typeInfo(S).Int.bits);
+    const U = std.meta.Int(.unsigned, @typeInfo(S).Int.bits);
 
     var value = @intCast(S, int_value);
 
@@ -171,7 +171,7 @@ pub fn writeILEB128Mem(ptr: []u8, int_value: anytype) !usize {
 /// An example use case of this is in emitting DWARF info where one wants to make a ULEB128 field
 /// "relocatable", meaning that it becomes possible to later go back and patch the number to be a
 /// different value without shifting all the following code.
-pub fn writeUnsignedFixed(comptime l: usize, ptr: *[l]u8, int: std.meta.Int(false, l * 7)) void {
+pub fn writeUnsignedFixed(comptime l: usize, ptr: *[l]u8, int: std.meta.Int(.unsigned, l * 7)) void {
     const T = @TypeOf(int);
     const U = if (@typeInfo(T).Int.bits < 8) u8 else T;
     var value = @intCast(U, int);
@@ -347,6 +347,7 @@ 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 writeStream = if (t_signed) writeILEB128 else writeULEB128;
     const writeMem = if (t_signed) writeILEB128Mem else writeULEB128Mem;
@@ -356,10 +357,10 @@ fn test_write_leb128(value: anytype) !void {
     // decode to a larger bit size too, to ensure sign extension
     // is working as expected
     const larger_type_bits = ((@typeInfo(T).Int.bits + 8) / 8) * 8;
-    const B = std.meta.Int(t_signed, larger_type_bits);
+    const B = std.meta.Int(signedness, larger_type_bits);
 
     const bytes_needed = bn: {
-        const S = std.meta.Int(t_signed, @sizeOf(T) * 8);
+        const S = std.meta.Int(signedness, @sizeOf(T) * 8);
         if (@typeInfo(T).Int.bits <= 7) break :bn @as(u16, 1);
 
         const unused_bits = if (value < 0) @clz(T, ~value) else @clz(T, value);
@@ -412,10 +413,10 @@ test "serialize unsigned LEB128" {
 
     comptime var t = 0;
     inline while (t <= max_bits) : (t += 1) {
-        const T = std.meta.Int(false, t);
+        const T = std.meta.Int(.unsigned, t);
         const min = std.math.minInt(T);
         const max = std.math.maxInt(T);
-        var i = @as(std.meta.Int(false, @typeInfo(T).Int.bits + 1), min);
+        var i = @as(std.meta.Int(.unsigned, @typeInfo(T).Int.bits + 1), min);
 
         while (i <= max) : (i += 1) try test_write_leb128(@intCast(T, i));
     }
@@ -430,10 +431,10 @@ test "serialize signed LEB128" {
 
     comptime var t = 1;
     inline while (t <= max_bits) : (t += 1) {
-        const T = std.meta.Int(true, t);
+        const T = std.meta.Int(.signed, t);
         const min = std.math.minInt(T);
         const max = std.math.maxInt(T);
-        var i = @as(std.meta.Int(true, @typeInfo(T).Int.bits + 1), min);
+        var i = @as(std.meta.Int(.signed, @typeInfo(T).Int.bits + 1), min);
 
         while (i <= max) : (i += 1) try test_write_leb128(@intCast(T, i));
     }
lib/std/event/wait_group.zig
@@ -22,7 +22,7 @@ const Loop = std.event.Loop;
 pub const WaitGroup = WaitGroupGeneric(std.meta.bitCount(usize));
 
 pub fn WaitGroupGeneric(comptime counter_size: u16) type {
-    const CounterType = std.meta.Int(false, counter_size);
+    const CounterType = std.meta.Int(.unsigned, counter_size);
 
     const global_event_loop = Loop.instance orelse
         @compileError("std.event.WaitGroup currently only works with event-based I/O");
lib/std/fmt/parse_float.zig
@@ -374,7 +374,7 @@ test "fmt.parseFloat" {
     const epsilon = 1e-7;
 
     inline for ([_]type{ f16, f32, f64, f128 }) |T| {
-        const Z = std.meta.Int(false, @typeInfo(T).Float.bits);
+        const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
 
         testing.expectError(error.InvalidCharacter, parseFloat(T, ""));
         testing.expectError(error.InvalidCharacter, parseFloat(T, "   1"));
lib/std/hash/wyhash.zig
@@ -15,7 +15,7 @@ const primes = [_]u64{
 };
 
 fn read_bytes(comptime bytes: u8, data: []const u8) u64 {
-    const T = std.meta.Int(false, 8 * bytes);
+    const T = std.meta.Int(.unsigned, 8 * bytes);
     return mem.readIntLittle(T, data[0..bytes]);
 }
 
lib/std/heap/general_purpose_allocator.zig
@@ -107,7 +107,7 @@ const page_size = std.mem.page_size;
 const StackTrace = std.builtin.StackTrace;
 
 /// Integer type for pointing to slots in a small allocation
-const SlotIndex = std.meta.Int(false, math.log2(page_size) + 1);
+const SlotIndex = std.meta.Int(.unsigned, math.log2(page_size) + 1);
 
 const sys_can_stack_trace = switch (std.Target.current.cpu.arch) {
     // Observed to go into an infinite loop.
lib/std/io/bit_reader.zig
@@ -60,7 +60,7 @@ pub fn BitReader(endian: builtin.Endian, comptime ReaderType: type) type {
                 assert(u_bit_count >= bits);
                 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;
             };
-            const Buf = std.meta.Int(false, buf_bit_count);
+            const Buf = std.meta.Int(.unsigned, buf_bit_count);
             const BufShift = math.Log2Int(Buf);
 
             out_bits.* = @as(usize, 0);
lib/std/io/bit_writer.zig
@@ -52,7 +52,7 @@ pub fn BitWriter(endian: builtin.Endian, comptime WriterType: type) type {
                 assert(u_bit_count >= bits);
                 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;
             };
-            const Buf = std.meta.Int(false, buf_bit_count);
+            const Buf = std.meta.Int(.unsigned, buf_bit_count);
             const BufShift = math.Log2Int(Buf);
 
             const buf_value = @intCast(Buf, value);
lib/std/io/serialization.zig
@@ -58,7 +58,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
             const u8_bit_count = 8;
             const t_bit_count = comptime meta.bitCount(T);
 
-            const U = std.meta.Int(false, t_bit_count);
+            const U = std.meta.Int(.unsigned, t_bit_count);
             const Log2U = math.Log2Int(U);
             const int_size = (t_bit_count + 7) / 8;
 
@@ -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(@typeInfo(T).Int.is_signed, 8);
+                const PossiblySignedByte = std.meta.Int(if (@typeInfo(T).Int.is_signed) .signed else .unsigned, 8);
                 return @truncate(T, @bitCast(PossiblySignedByte, buffer[0]));
             }
 
@@ -245,7 +245,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
             const t_bit_count = comptime meta.bitCount(T);
             const u8_bit_count = comptime meta.bitCount(u8);
 
-            const U = std.meta.Int(false, t_bit_count);
+            const U = std.meta.Int(.unsigned, t_bit_count);
             const Log2U = math.Log2Int(U);
             const int_size = (t_bit_count + 7) / 8;
 
@@ -381,8 +381,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
 
     comptime var i = 0;
     inline while (i <= max_test_bitsize) : (i += 1) {
-        const U = std.meta.Int(false, i);
-        const S = std.meta.Int(true, i);
+        const U = std.meta.Int(.unsigned, i);
+        const S = std.meta.Int(.signed, i);
         try _serializer.serializeInt(@as(U, i));
         if (i != 0) try _serializer.serializeInt(@as(S, -1)) else try _serializer.serialize(@as(S, 0));
     }
@@ -390,8 +390,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
 
     i = 0;
     inline while (i <= max_test_bitsize) : (i += 1) {
-        const U = std.meta.Int(false, i);
-        const S = std.meta.Int(true, i);
+        const U = std.meta.Int(.unsigned, i);
+        const S = std.meta.Int(.signed, i);
         const x = try _deserializer.deserializeInt(U);
         const y = try _deserializer.deserializeInt(S);
         testing.expect(x == @as(U, i));
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(false, info.bits - 1) else T;
+            const UT = if (info.is_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(false, info.bits - 1) else T;
+                const UT = if (info.is_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
@@ -1092,7 +1092,7 @@ pub const Const = struct {
     pub fn to(self: Const, comptime T: type) ConvertError!T {
         switch (@typeInfo(T)) {
             .Int => |info| {
-                const UT = std.meta.Int(false, info.bits);
+                const UT = std.meta.Int(.unsigned, info.bits);
 
                 if (self.bitCountTwosComp() > info.bits) {
                     return error.TargetTooSmall;
lib/std/math/big/rational.zig
@@ -136,7 +136,7 @@ pub const Rational = struct {
         // Translated from golang.go/src/math/big/rat.go.
         debug.assert(@typeInfo(T) == .Float);
 
-        const UnsignedInt = std.meta.Int(false, @typeInfo(T).Float.bits);
+        const UnsignedInt = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
         const f_bits = @bitCast(UnsignedInt, f);
 
         const exponent_bits = math.floatExponentBits(T);
@@ -195,7 +195,7 @@ pub const Rational = struct {
         debug.assert(@typeInfo(T) == .Float);
 
         const fsize = @typeInfo(T).Float.bits;
-        const BitReprType = std.meta.Int(false, fsize);
+        const BitReprType = std.meta.Int(.unsigned, fsize);
 
         const msize = math.floatMantissaBits(T);
         const msize1 = msize + 1;
lib/std/math/big.zig
@@ -10,8 +10,8 @@ pub const Rational = @import("big/rational.zig").Rational;
 pub const int = @import("big/int.zig");
 pub const Limb = usize;
 const limb_info = @typeInfo(Limb).Int;
-pub const DoubleLimb = std.meta.IntType(false, 2 * limb_info.bits);
-pub const SignedDoubleLimb = std.meta.IntType(true, 2 * limb_info.bits);
+pub const DoubleLimb = std.meta.Int(.unsigned, 2 * limb_info.bits);
+pub const SignedDoubleLimb = std.meta.Int(.signed, 2 * limb_info.bits);
 pub const Log2Limb = std.math.Log2Int(Limb);
 
 comptime {
lib/std/math/cos.zig
@@ -49,7 +49,7 @@ const pi4c = 2.69515142907905952645E-15;
 const m4pi = 1.273239544735162542821171882678754627704620361328125;
 
 fn cos_(comptime T: type, x_: T) T {
-    const I = std.meta.Int(true, @typeInfo(T).Float.bits);
+    const I = std.meta.Int(.signed, @typeInfo(T).Float.bits);
 
     var x = x_;
     if (math.isNan(x) or math.isInf(x)) {
lib/std/math/pow.zig
@@ -150,7 +150,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {
     var xe = r2.exponent;
     var x1 = r2.significand;
 
-    var i = @floatToInt(std.meta.Int(true, @typeInfo(T).Float.bits), yi);
+    var i = @floatToInt(std.meta.Int(.signed, @typeInfo(T).Float.bits), yi);
     while (i != 0) : (i >>= 1) {
         const overflow_shift = math.floatExponentBits(T) + 1;
         if (xe < -(1 << overflow_shift) or (1 << overflow_shift) < xe) {
lib/std/math/sin.zig
@@ -50,7 +50,7 @@ const pi4c = 2.69515142907905952645E-15;
 const m4pi = 1.273239544735162542821171882678754627704620361328125;
 
 fn sin_(comptime T: type, x_: T) T {
-    const I = std.meta.Int(true, @typeInfo(T).Float.bits);
+    const I = std.meta.Int(.signed, @typeInfo(T).Float.bits);
 
     var x = x_;
     if (x == 0 or math.isNan(x)) {
lib/std/math/sqrt.zig
@@ -36,7 +36,7 @@ pub fn sqrt(x: anytype) Sqrt(@TypeOf(x)) {
     }
 }
 
-fn sqrt_int(comptime T: type, value: T) std.meta.Int(false, @typeInfo(T).Int.bits / 2) {
+fn sqrt_int(comptime T: type, value: T) std.meta.Int(.unsigned, @typeInfo(T).Int.bits / 2) {
     var op = value;
     var res: T = 0;
     var one: T = 1 << (@typeInfo(T).Int.bits - 2);
@@ -55,7 +55,7 @@ fn sqrt_int(comptime T: type, value: T) std.meta.Int(false, @typeInfo(T).Int.bit
         one >>= 2;
     }
 
-    const ResultType = std.meta.Int(false, @typeInfo(T).Int.bits / 2);
+    const ResultType = std.meta.Int(.unsigned, @typeInfo(T).Int.bits / 2);
     return @intCast(ResultType, res);
 }
 
@@ -71,7 +71,7 @@ test "math.sqrt_int" {
 /// Returns the return type `sqrt` will return given an operand of type `T`.
 pub fn Sqrt(comptime T: type) type {
     return switch (@typeInfo(T)) {
-        .Int => |int| std.meta.Int(false, int.bits / 2),
+        .Int => |int| std.meta.Int(.unsigned, int.bits / 2),
         else => T,
     };
 }
lib/std/math/tan.zig
@@ -43,7 +43,7 @@ const pi4c = 2.69515142907905952645E-15;
 const m4pi = 1.273239544735162542821171882678754627704620361328125;
 
 fn tan_(comptime T: type, x_: T) T {
-    const I = std.meta.Int(true, @typeInfo(T).Float.bits);
+    const I = std.meta.Int(.signed, @typeInfo(T).Float.bits);
 
     var x = x_;
     if (x == 0 or math.isNan(x)) {
lib/std/meta/trailer_flags.zig
@@ -18,7 +18,7 @@ pub fn TrailerFlags(comptime Fields: type) type {
     return struct {
         bits: Int,
 
-        pub const Int = meta.Int(false, bit_count);
+        pub const Int = meta.Int(.unsigned, bit_count);
         pub const bit_count = @typeInfo(Fields).Struct.fields.len;
 
         pub const FieldEnum = blk: {
lib/std/os/bits/linux.zig
@@ -1073,7 +1073,7 @@ pub const dl_phdr_info = extern struct {
 
 pub const CPU_SETSIZE = 128;
 pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
-pub const cpu_count_t = std.meta.Int(false, std.math.log2(CPU_SETSIZE * 8));
+pub const cpu_count_t = std.meta.Int(.unsigned, std.math.log2(CPU_SETSIZE * 8));
 
 pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
     var sum: cpu_count_t = 0;
lib/std/special/compiler_rt/addXf3.zig
@@ -59,14 +59,14 @@ pub fn __aeabi_dsub(a: f64, b: f64) callconv(.AAPCS) f64 {
 }
 
 // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
-fn normalize(comptime T: type, significand: *std.meta.Int(false, @typeInfo(T).Float.bits)) i32 {
+fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
     const bits = @typeInfo(T).Float.bits;
-    const Z = std.meta.Int(false, bits);
-    const S = std.meta.Int(false, bits - @clz(Z, @as(Z, bits) - 1));
+    const Z = std.meta.Int(.unsigned, bits);
+    const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
     const significandBits = std.math.floatMantissaBits(T);
     const implicitBit = @as(Z, 1) << significandBits;
 
-    const shift = @clz(std.meta.Int(false, bits), significand.*) - @clz(Z, implicitBit);
+    const shift = @clz(std.meta.Int(.unsigned, bits), significand.*) - @clz(Z, implicitBit);
     significand.* <<= @intCast(S, shift);
     return 1 - shift;
 }
@@ -74,8 +74,8 @@ fn normalize(comptime T: type, significand: *std.meta.Int(false, @typeInfo(T).Fl
 // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
 fn addXf3(comptime T: type, a: T, b: T) T {
     const bits = @typeInfo(T).Float.bits;
-    const Z = std.meta.Int(false, bits);
-    const S = std.meta.Int(false, bits - @clz(Z, @as(Z, bits) - 1));
+    const Z = std.meta.Int(.unsigned, bits);
+    const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
 
     const typeWidth = bits;
     const significandBits = std.math.floatMantissaBits(T);
@@ -189,7 +189,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
         // If partial cancellation occured, we need to left-shift the result
         // and adjust the exponent:
         if (aSignificand < implicitBit << 3) {
-            const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(std.meta.Int(false, bits), implicitBit << 3));
+            const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(std.meta.Int(.unsigned, bits), implicitBit << 3));
             aSignificand <<= @intCast(S, shift);
             aExponent -= shift;
         }
lib/std/special/compiler_rt/compareXf2.zig
@@ -28,8 +28,8 @@ pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {
     @setRuntimeSafety(builtin.is_test);
 
     const bits = @typeInfo(T).Float.bits;
-    const srep_t = std.meta.Int(true, bits);
-    const rep_t = std.meta.Int(false, bits);
+    const srep_t = std.meta.Int(.signed, bits);
+    const rep_t = std.meta.Int(.unsigned, bits);
 
     const significandBits = std.math.floatMantissaBits(T);
     const exponentBits = std.math.floatExponentBits(T);
@@ -74,7 +74,7 @@ pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {
 pub fn unordcmp(comptime T: type, a: T, b: T) i32 {
     @setRuntimeSafety(builtin.is_test);
 
-    const rep_t = std.meta.Int(false, @typeInfo(T).Float.bits);
+    const rep_t = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
 
     const significandBits = std.math.floatMantissaBits(T);
     const exponentBits = std.math.floatExponentBits(T);
lib/std/special/compiler_rt/divdf3.zig
@@ -12,8 +12,8 @@ const builtin = @import("builtin");
 
 pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
     @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(false, 64);
-    const SignedZ = std.meta.Int(true, 64);
+    const Z = std.meta.Int(.unsigned, 64);
+    const SignedZ = std.meta.Int(.signed, 64);
 
     const significandBits = std.math.floatMantissaBits(f64);
     const exponentBits = std.math.floatExponentBits(f64);
@@ -316,9 +316,9 @@ pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
     }
 }
 
-pub fn normalize(comptime T: type, significand: *std.meta.Int(false, @typeInfo(T).Float.bits)) i32 {
+pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
     @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(false, @typeInfo(T).Float.bits);
+    const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
     const significandBits = std.math.floatMantissaBits(T);
     const implicitBit = @as(Z, 1) << significandBits;
 
lib/std/special/compiler_rt/divsf3.zig
@@ -12,7 +12,7 @@ const builtin = @import("builtin");
 
 pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
     @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(false, 32);
+    const Z = std.meta.Int(.unsigned, 32);
 
     const significandBits = std.math.floatMantissaBits(f32);
     const exponentBits = std.math.floatExponentBits(f32);
@@ -189,9 +189,9 @@ pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
     }
 }
 
-fn normalize(comptime T: type, significand: *std.meta.Int(false, @typeInfo(T).Float.bits)) i32 {
+fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
     @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(false, @typeInfo(T).Float.bits);
+    const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
     const significandBits = std.math.floatMantissaBits(T);
     const implicitBit = @as(Z, 1) << significandBits;
 
lib/std/special/compiler_rt/divtf3.zig
@@ -11,8 +11,8 @@ const wideMultiply = @import("divdf3.zig").wideMultiply;
 
 pub fn __divtf3(a: f128, b: f128) callconv(.C) f128 {
     @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(false, 128);
-    const SignedZ = std.meta.Int(true, 128);
+    const Z = std.meta.Int(.unsigned, 128);
+    const SignedZ = std.meta.Int(.signed, 128);
 
     const significandBits = std.math.floatMantissaBits(f128);
     const exponentBits = std.math.floatExponentBits(f128);
lib/std/special/compiler_rt/extendXfYf2.zig
@@ -35,11 +35,11 @@ pub fn __aeabi_f2d(arg: f32) callconv(.AAPCS) f64 {
 
 const CHAR_BIT = 8;
 
-fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.Int(false, @typeInfo(src_t).Float.bits)) dst_t {
+fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits)) dst_t {
     @setRuntimeSafety(builtin.is_test);
 
-    const src_rep_t = std.meta.Int(false, @typeInfo(src_t).Float.bits);
-    const dst_rep_t = std.meta.Int(false, @typeInfo(dst_t).Float.bits);
+    const src_rep_t = std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits);
+    const dst_rep_t = std.meta.Int(.unsigned, @typeInfo(dst_t).Float.bits);
     const srcSigBits = std.math.floatMantissaBits(src_t);
     const dstSigBits = std.math.floatMantissaBits(dst_t);
     const SrcShift = std.math.Log2Int(src_rep_t);
lib/std/special/compiler_rt/fixint.zig
@@ -51,7 +51,7 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
 
     // The unsigned result needs to be large enough to handle an fixint_t or rep_t
     const fixint_bits = @typeInfo(fixint_t).Int.bits;
-    const fixuint_t = std.meta.Int(false, fixint_bits);
+    const fixuint_t = std.meta.Int(.unsigned, fixint_bits);
     const UintResultType = if (fixint_bits > typeWidth) fixuint_t else rep_t;
     var uint_result: UintResultType = undefined;
 
lib/std/special/compiler_rt/fixuint.zig
@@ -16,7 +16,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
         else => unreachable,
     };
     const typeWidth = @typeInfo(rep_t).Int.bits;
-    const srep_t = @import("std").meta.Int(true, typeWidth);
+    const srep_t = @import("std").meta.Int(.signed, typeWidth);
     const significandBits = switch (fp_t) {
         f32 => 23,
         f64 => 52,
lib/std/special/compiler_rt/floatsiXf.zig
@@ -11,8 +11,8 @@ fn floatsiXf(comptime T: type, a: i32) T {
     @setRuntimeSafety(builtin.is_test);
 
     const bits = @typeInfo(T).Float.bits;
-    const Z = std.meta.Int(false, bits);
-    const S = std.meta.Int(false, bits - @clz(Z, @as(Z, bits) - 1));
+    const Z = std.meta.Int(.unsigned, bits);
+    const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
 
     if (a == 0) {
         return @as(T, 0.0);
lib/std/special/compiler_rt/floatXisf.zig
@@ -13,8 +13,8 @@ fn __floatXisf(comptime T: type, arg: T) f32 {
     @setRuntimeSafety(builtin.is_test);
 
     const bits = @typeInfo(T).Int.bits;
-    const Z = std.meta.Int(false, bits);
-    const S = std.meta.Int(false, bits - @clz(Z, @as(Z, bits) - 1));
+    const Z = std.meta.Int(.unsigned, bits);
+    const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
 
     if (arg == 0) {
         return @as(f32, 0.0);
lib/std/special/compiler_rt/mulXf3.zig
@@ -34,7 +34,7 @@ pub fn __aeabi_dmul(a: f64, b: f64) callconv(.C) f64 {
 fn mulXf3(comptime T: type, a: T, b: T) T {
     @setRuntimeSafety(builtin.is_test);
     const typeWidth = @typeInfo(T).Float.bits;
-    const Z = std.meta.Int(false, typeWidth);
+    const Z = std.meta.Int(.unsigned, typeWidth);
 
     const significandBits = std.math.floatMantissaBits(T);
     const exponentBits = std.math.floatExponentBits(T);
@@ -269,9 +269,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
     }
 }
 
-fn normalize(comptime T: type, significand: *std.meta.Int(false, @typeInfo(T).Float.bits)) i32 {
+fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
     @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(false, @typeInfo(T).Float.bits);
+    const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
     const significandBits = std.math.floatMantissaBits(T);
     const implicitBit = @as(Z, 1) << significandBits;
 
lib/std/special/compiler_rt/negXf2.zig
@@ -24,7 +24,7 @@ pub fn __aeabi_dneg(arg: f64) callconv(.AAPCS) f64 {
 }
 
 fn negXf2(comptime T: type, a: T) T {
-    const Z = std.meta.Int(false, @typeInfo(T).Float.bits);
+    const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
 
     const significandBits = std.math.floatMantissaBits(T);
     const exponentBits = std.math.floatExponentBits(T);
lib/std/special/compiler_rt/shift.zig
@@ -10,8 +10,8 @@ const Log2Int = std.math.Log2Int;
 fn Dwords(comptime T: type, comptime signed_half: bool) type {
     return extern union {
         pub const bits = @divExact(@typeInfo(T).Int.bits, 2);
-        pub const HalfTU = std.meta.Int(false, bits);
-        pub const HalfTS = std.meta.Int(true, bits);
+        pub const HalfTU = std.meta.Int(.unsigned, bits);
+        pub const HalfTS = std.meta.Int(.signed, bits);
         pub const HalfT = if (signed_half) HalfTS else HalfTU;
 
         all: T,
lib/std/special/compiler_rt/truncXfYf2.zig
@@ -41,8 +41,8 @@ pub fn __aeabi_f2h(a: f32) callconv(.AAPCS) u16 {
 }
 
 fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
-    const src_rep_t = std.meta.Int(false, @typeInfo(src_t).Float.bits);
-    const dst_rep_t = std.meta.Int(false, @typeInfo(dst_t).Float.bits);
+    const src_rep_t = std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits);
+    const dst_rep_t = std.meta.Int(.unsigned, @typeInfo(dst_t).Float.bits);
     const srcSigBits = std.math.floatMantissaBits(src_t);
     const dstSigBits = std.math.floatMantissaBits(dst_t);
     const SrcShift = std.math.Log2Int(src_rep_t);
lib/std/special/compiler_rt/udivmod.zig
@@ -17,8 +17,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
 
     const double_int_bits = @typeInfo(DoubleInt).Int.bits;
     const single_int_bits = @divExact(double_int_bits, 2);
-    const SingleInt = @import("std").meta.Int(false, single_int_bits);
-    const SignedDoubleInt = @import("std").meta.Int(true, double_int_bits);
+    const SingleInt = @import("std").meta.Int(.unsigned, single_int_bits);
+    const SignedDoubleInt = @import("std").meta.Int(.signed, double_int_bits);
     const Log2SingleInt = @import("std").math.Log2Int(SingleInt);
 
     const n = @ptrCast(*const [2]SingleInt, &a).*; // TODO issue #421
lib/std/special/c.zig
@@ -652,7 +652,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
     @setRuntimeSafety(false);
 
     const bits = @typeInfo(T).Float.bits;
-    const uint = std.meta.Int(false, bits);
+    const uint = std.meta.Int(.unsigned, bits);
     const log2uint = math.Log2Int(uint);
     const digits = if (T == f32) 23 else 52;
     const exp_bits = if (T == f32) 9 else 12;
lib/std/child_process.zig
@@ -826,7 +826,7 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
     os.exit(1);
 }
 
-const ErrInt = std.meta.Int(false, @sizeOf(anyerror) * 8);
+const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8);
 
 fn writeIntFd(fd: i32, value: ErrInt) !void {
     const file = File{
lib/std/fmt.zig
@@ -950,7 +950,7 @@ pub fn formatInt(
     // The type must have the same size as `base` or be wider in order for the
     // division to work
     const min_int_bits = comptime math.max(value_info.bits, 8);
-    const MinInt = std.meta.Int(false, min_int_bits);
+    const MinInt = std.meta.Int(.unsigned, min_int_bits);
 
     const abs_value = math.absCast(int_value);
     // The worst case in terms of space needed is base 2, plus 1 for the sign
lib/std/heap.zig
@@ -963,7 +963,7 @@ pub fn testAllocatorLargeAlignment(base_allocator: *mem.Allocator) mem.Allocator
     //  very near usize?
     if (mem.page_size << 2 > maxInt(usize)) return;
 
-    const USizeShift = std.meta.Int(false, std.math.log2(std.meta.bitCount(usize)));
+    const USizeShift = std.meta.Int(.unsigned, std.math.log2(std.meta.bitCount(usize)));
     const large_align = @as(u29, mem.page_size << 2);
 
     var align_mask: usize = undefined;
lib/std/math.zig
@@ -448,7 +448,7 @@ pub fn Log2Int(comptime T: type) type {
         count += 1;
     }
 
-    return std.meta.Int(false, count);
+    return std.meta.Int(.unsigned, count);
 }
 
 pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {
@@ -456,15 +456,15 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
     if (from == 0 and to == 0) {
         return u0;
     }
-    const is_signed = from < 0;
+    const sign: std.meta.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;
     var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
-    if (is_signed) {
+    if (sign == .signed) {
         magnitude_bits += 1;
     }
-    return std.meta.Int(is_signed, magnitude_bits);
+    return std.meta.Int(sign, magnitude_bits);
 }
 
 test "math.IntFittingRange" {
@@ -729,7 +729,7 @@ fn testRem() void {
 /// Result is an unsigned integer.
 pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) {
     .ComptimeInt => comptime_int,
-    .Int => |intInfo| std.meta.Int(false, intInfo.bits),
+    .Int => |intInfo| std.meta.Int(.unsigned, intInfo.bits),
     else => @compileError("absCast only accepts integers"),
 } {
     switch (@typeInfo(@TypeOf(x))) {
@@ -741,7 +741,7 @@ pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) {
             }
         },
         .Int => |intInfo| {
-            const Uint = std.meta.Int(false, intInfo.bits);
+            const Uint = std.meta.Int(.unsigned, intInfo.bits);
             if (x < 0) {
                 return ~@bitCast(Uint, x +% -1);
             } else {
@@ -762,10 +762,10 @@ test "math.absCast" {
 
 /// Returns the negation of the integer parameter.
 /// Result is a signed integer.
-pub fn negateCast(x: anytype) !std.meta.Int(true, std.meta.bitCount(@TypeOf(x))) {
+pub fn negateCast(x: anytype) !std.meta.Int(.signed, std.meta.bitCount(@TypeOf(x))) {
     if (@typeInfo(@TypeOf(x)).Int.is_signed) return negate(x);
 
-    const int = std.meta.Int(true, std.meta.bitCount(@TypeOf(x)));
+    const int = std.meta.Int(.signed, std.meta.bitCount(@TypeOf(x)));
     if (x > -minInt(int)) return error.Overflow;
 
     if (x == -minInt(int)) return minInt(int);
@@ -852,11 +852,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(@typeInfo(T).Int.is_signed, @typeInfo(T).Int.bits + 1) {
+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) {
     comptime assert(@typeInfo(T) == .Int);
     comptime assert(!@typeInfo(T).Int.is_signed);
     assert(value != 0);
-    comptime const PromotedType = std.meta.Int(@typeInfo(T).Int.is_signed, @typeInfo(T).Int.bits + 1);
+    comptime const PromotedType = std.meta.Int(if (@typeInfo(T).Int.is_signed) .signed else .unsigned, @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));
 }
@@ -868,7 +868,7 @@ 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(info.is_signed, info.bits + 1);
+    comptime const PromotedType = std.meta.Int(if (info.is_signed) .signed else .unsigned, info.bits + 1);
     comptime const overflowBit = @as(PromotedType, 1) << info.bits;
     var x = ceilPowerOfTwoPromote(T, value);
     if (overflowBit & x != 0) {
@@ -1014,8 +1014,8 @@ test "max value type" {
     testing.expect(x == 2147483647);
 }
 
-pub fn mulWide(comptime T: type, a: T, b: T) std.meta.Int(@typeInfo(T).Int.is_signed, @typeInfo(T).Int.bits * 2) {
-    const ResultInt = std.meta.Int(@typeInfo(T).Int.is_signed, @typeInfo(T).Int.bits * 2);
+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);
     return @as(ResultInt, a) * @as(ResultInt, b);
 }
 
lib/std/mem.zig
@@ -1106,7 +1106,7 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
         return set(u8, buffer, 0);
 
     // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough
-    const uint = std.meta.Int(false, @typeInfo(T).Int.bits);
+    const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
     var bits = @truncate(uint, value);
     for (buffer) |*b| {
         b.* = @truncate(u8, bits);
@@ -1126,7 +1126,7 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
         return set(u8, buffer, 0);
 
     // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough
-    const uint = std.meta.Int(false, @typeInfo(T).Int.bits);
+    const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
     var bits = @truncate(uint, value);
     var index: usize = buffer.len;
     while (index != 0) {
lib/std/meta.zig
@@ -678,10 +678,15 @@ pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const De
 /// Deprecated: use Int
 pub const IntType = Int;
 
-pub fn Int(comptime is_signed: bool, comptime bit_count: u16) type {
+pub const Signedness = enum {
+    unsigned,
+    signed,
+};
+
+pub fn Int(comptime signedness: Signedness, comptime bit_count: u16) type {
     return @Type(TypeInfo{
         .Int = .{
-            .is_signed = is_signed,
+            .is_signed = signedness == .signed,
             .bits = bit_count,
         },
     });
lib/std/os.zig
@@ -4494,7 +4494,7 @@ pub fn res_mkquery(
     // Make a reasonably unpredictable id
     var ts: timespec = undefined;
     clock_gettime(CLOCK_REALTIME, &ts) catch {};
-    const UInt = std.meta.Int(false, std.meta.bitCount(@TypeOf(ts.tv_nsec)));
+    const UInt = std.meta.Int(.unsigned, std.meta.bitCount(@TypeOf(ts.tv_nsec)));
     const unsec = @bitCast(UInt, ts.tv_nsec);
     const id = @truncate(u32, unsec + unsec / 65536);
     q[0] = @truncate(u8, id / 256);
lib/std/packed_int_array.zig
@@ -39,13 +39,13 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
 
     //we bitcast the desired Int type to an unsigned version of itself
     // to avoid issues with shifting signed ints.
-    const UnInt = std.meta.Int(false, int_bits);
+    const UnInt = std.meta.Int(.unsigned, int_bits);
 
     //The maximum container int type
-    const MinIo = std.meta.Int(false, min_io_bits);
+    const MinIo = std.meta.Int(.unsigned, min_io_bits);
 
     //The minimum container int type
-    const MaxIo = std.meta.Int(false, max_io_bits);
+    const MaxIo = std.meta.Int(.unsigned, max_io_bits);
 
     return struct {
         pub fn get(bytes: []const u8, index: usize, bit_offset: u7) Int {
@@ -416,7 +416,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
 
     comptime var bits = 0;
     inline while (bits <= max_bits) : (bits += 1) {
-        const Int = std.meta.Int(false, bits);
+        const Int = std.meta.Int(.unsigned, bits);
 
         const PackedArray = PackedIntArray(Int, int_count);
         var packed_array = @as(PackedArray, undefined);
lib/std/rand.zig
@@ -52,8 +52,8 @@ pub const Random = struct {
     /// `i` is evenly distributed.
     pub fn int(r: *Random, comptime T: type) T {
         const bits = @typeInfo(T).Int.bits;
-        const UnsignedT = std.meta.Int(false, bits);
-        const ByteAlignedT = std.meta.Int(false, @divTrunc(bits + 7, 8) * 8);
+        const UnsignedT = std.meta.Int(.unsigned, bits);
+        const ByteAlignedT = std.meta.Int(.unsigned, @divTrunc(bits + 7, 8) * 8);
 
         var rand_bytes: [@sizeOf(ByteAlignedT)]u8 = undefined;
         r.bytes(rand_bytes[0..]);
@@ -95,9 +95,9 @@ pub const Random = struct {
         assert(0 < less_than);
         // Small is typically u32
         const small_bits = @divTrunc(bits + 31, 32) * 32;
-        const Small = std.meta.Int(false, small_bits);
+        const Small = std.meta.Int(.unsigned, small_bits);
         // Large is typically u64
-        const Large = std.meta.Int(false, small_bits * 2);
+        const Large = std.meta.Int(.unsigned, small_bits * 2);
 
         // adapted from:
         //   http://www.pcg-random.org/posts/bounded-rands.html
@@ -109,7 +109,7 @@ pub const Random = struct {
             // TODO: workaround for https://github.com/ziglang/zig/issues/1770
             // should be:
             //   var t: Small = -%less_than;
-            var t: Small = @bitCast(Small, -%@bitCast(std.meta.Int(true, small_bits), @as(Small, less_than)));
+            var t: Small = @bitCast(Small, -%@bitCast(std.meta.Int(.signed, small_bits), @as(Small, less_than)));
 
             if (t >= less_than) {
                 t -= less_than;
@@ -156,7 +156,7 @@ pub const Random = struct {
         const info = @typeInfo(T).Int;
         if (info.is_signed) {
             // Two's complement makes this math pretty easy.
-            const UnsignedT = std.meta.Int(false, info.bits);
+            const UnsignedT = std.meta.Int(.unsigned, info.bits);
             const lo = @bitCast(UnsignedT, at_least);
             const hi = @bitCast(UnsignedT, less_than);
             const result = lo +% r.uintLessThanBiased(UnsignedT, hi -% lo);
@@ -175,7 +175,7 @@ pub const Random = struct {
         const info = @typeInfo(T).Int;
         if (info.is_signed) {
             // Two's complement makes this math pretty easy.
-            const UnsignedT = std.meta.Int(false, info.bits);
+            const UnsignedT = std.meta.Int(.unsigned, info.bits);
             const lo = @bitCast(UnsignedT, at_least);
             const hi = @bitCast(UnsignedT, less_than);
             const result = lo +% r.uintLessThan(UnsignedT, hi -% lo);
@@ -193,7 +193,7 @@ pub const Random = struct {
         const info = @typeInfo(T).Int;
         if (info.is_signed) {
             // Two's complement makes this math pretty easy.
-            const UnsignedT = std.meta.Int(false, info.bits);
+            const UnsignedT = std.meta.Int(.unsigned, info.bits);
             const lo = @bitCast(UnsignedT, at_least);
             const hi = @bitCast(UnsignedT, at_most);
             const result = lo +% r.uintAtMostBiased(UnsignedT, hi -% lo);
@@ -212,7 +212,7 @@ pub const Random = struct {
         const info = @typeInfo(T).Int;
         if (info.is_signed) {
             // Two's complement makes this math pretty easy.
-            const UnsignedT = std.meta.Int(false, info.bits);
+            const UnsignedT = std.meta.Int(.unsigned, info.bits);
             const lo = @bitCast(UnsignedT, at_least);
             const hi = @bitCast(UnsignedT, at_most);
             const result = lo +% r.uintAtMost(UnsignedT, hi -% lo);
@@ -290,7 +290,7 @@ pub const Random = struct {
 pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {
     comptime assert(@typeInfo(T).Int.is_signed == false);
     const bits = @typeInfo(T).Int.bits;
-    const T2 = std.meta.Int(false, bits * 2);
+    const T2 = std.meta.Int(.unsigned, bits * 2);
 
     // adapted from:
     //   http://www.pcg-random.org/posts/bounded-rands.html
lib/std/target.zig
@@ -554,7 +554,7 @@ pub const Target = struct {
                 pub const needed_bit_count = 168;
                 pub const byte_count = (needed_bit_count + 7) / 8;
                 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
-                pub const Index = std.math.Log2Int(std.meta.Int(false, usize_count * @bitSizeOf(usize)));
+                pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)));
                 pub const ShiftInt = std.math.Log2Int(usize);
 
                 pub const empty = Set{ .ints = [1]usize{0} ** usize_count };