| author | |
| committer | |
| log | 57634b7809d07c8a07a015bec55829937d5795e1 |
| tree | 033baabefeb61b5c291a2b0f044a5b002c0b4f99 |
| parent | 213c4fc25f214a0d8763bd7976db9ae3eec0f232 |
| signature |
Resolves: https://github.com/ziglang/zig/issues/159312 files changed, 81 insertions(+), 79 deletions(-)
lib/std/zig/AstGen.zig+55-47| ... | ... | @@ -8073,39 +8073,42 @@ fn identifier( |
| 8073 | 8073 | return rvalue(gz, ri, zir_const_ref, ident); |
| 8074 | 8074 | } |
| 8075 | 8075 | |
| 8076 | if (ident_name_raw.len >= 2) integer: { | |
| 8077 | // Keep in sync with logic in `comptimeExpr2`. | |
| 8078 | const first_c = ident_name_raw[0]; | |
| 8079 | if (first_c == 'i' or first_c == 'u') { | |
| 8080 | const signedness: std.builtin.Signedness = switch (first_c == 'i') { | |
| 8081 | true => .signed, | |
| 8082 | false => .unsigned, | |
| 8083 | }; | |
| 8084 | if (ident_name_raw.len >= 3 and ident_name_raw[1] == '0') { | |
| 8085 | return astgen.failNode( | |
| 8086 | ident, | |
| 8087 | "primitive integer type '{s}' has leading zero", | |
| 8088 | .{ident_name_raw}, | |
| 8089 | ); | |
| 8090 | } | |
| 8091 | const bit_count = parseBitCount(ident_name_raw[1..]) catch |err| switch (err) { | |
| 8092 | error.Overflow => return astgen.failNode( | |
| 8093 | ident, | |
| 8094 | "primitive integer type '{s}' exceeds maximum bit width of 65535", | |
| 8095 | .{ident_name_raw}, | |
| 8096 | ), | |
| 8097 | error.InvalidCharacter => break :integer, | |
| 8098 | }; | |
| 8099 | const result = try gz.add(.{ | |
| 8100 | .tag = .int_type, | |
| 8101 | .data = .{ .int_type = .{ | |
| 8102 | .src_node = gz.nodeIndexToRelative(ident), | |
| 8103 | .signedness = signedness, | |
| 8104 | .bit_count = bit_count, | |
| 8105 | } }, | |
| 8106 | }); | |
| 8107 | return rvalue(gz, ri, result, ident); | |
| 8076 | int_type: { | |
| 8077 | if (ident_name_raw.len < 2) break :int_type; | |
| 8078 | const signedness: std.builtin.Signedness = switch (ident_name_raw[0]) { | |
| 8079 | 'u' => .unsigned, | |
| 8080 | 'i' => .signed, | |
| 8081 | else => break :int_type, | |
| 8082 | }; | |
| 8083 | // `u0` already handled by `primitive_instrs` | |
| 8084 | if (std.mem.eql(u8, ident_name_raw, "i0")) { | |
| 8085 | return astgen.failNode(ident, "signed integer cannot have bit width 0", .{}); | |
| 8086 | } | |
| 8087 | if (ident_name_raw[1] == '0') { | |
| 8088 | assert(ident_name_raw.len >= 3); // `u0` and `i0` handled | |
| 8089 | return astgen.failNode( | |
| 8090 | ident, | |
| 8091 | "primitive integer type '{s}' has leading zero", | |
| 8092 | .{ident_name_raw}, | |
| 8093 | ); | |
| 8108 | 8094 | } |
| 8095 | const bit_count = parseBitCount(ident_name_raw[1..]) catch |err| switch (err) { | |
| 8096 | error.Overflow => return astgen.failNode( | |
| 8097 | ident, | |
| 8098 | "primitive integer type '{s}' exceeds maximum bit width of 65535", | |
| 8099 | .{ident_name_raw}, | |
| 8100 | ), | |
| 8101 | error.InvalidCharacter => break :int_type, | |
| 8102 | }; | |
| 8103 | const result = try gz.add(.{ | |
| 8104 | .tag = .int_type, | |
| 8105 | .data = .{ .int_type = .{ | |
| 8106 | .src_node = gz.nodeIndexToRelative(ident), | |
| 8107 | .signedness = signedness, | |
| 8108 | .bit_count = bit_count, | |
| 8109 | } }, | |
| 8110 | }); | |
| 8111 | return rvalue(gz, ri, result, ident); | |
| 8109 | 8112 | } |
| 8110 | 8113 | } |
| 8111 | 8114 | |
| ... | ... | @@ -10122,32 +10125,37 @@ const primitive_instrs = std.StaticStringMap(Zir.Inst.Ref).initComptime(.{ |
| 10122 | 10125 | .{ "c_ushort", .c_ushort_type }, |
| 10123 | 10126 | .{ "comptime_float", .comptime_float_type }, |
| 10124 | 10127 | .{ "comptime_int", .comptime_int_type }, |
| 10125 | .{ "f128", .f128_type }, | |
| 10126 | .{ "f16", .f16_type }, | |
| 10127 | .{ "f32", .f32_type }, | |
| 10128 | .{ "f64", .f64_type }, | |
| 10129 | .{ "f80", .f80_type }, | |
| 10130 | 10128 | .{ "false", .bool_false }, |
| 10131 | .{ "i16", .i16_type }, | |
| 10132 | .{ "i32", .i32_type }, | |
| 10133 | .{ "i64", .i64_type }, | |
| 10134 | .{ "i128", .i128_type }, | |
| 10135 | .{ "i8", .i8_type }, | |
| 10136 | .{ "isize", .isize_type }, | |
| 10137 | 10129 | .{ "noreturn", .noreturn_type }, |
| 10138 | 10130 | .{ "null", .null_value }, |
| 10139 | 10131 | .{ "true", .bool_true }, |
| 10140 | 10132 | .{ "type", .type_type }, |
| 10133 | .{ "undefined", .undef }, | |
| 10134 | .{ "void", .void_type }, | |
| 10135 | ||
| 10136 | .{ "f16", .f16_type }, | |
| 10137 | .{ "f32", .f32_type }, | |
| 10138 | .{ "f64", .f64_type }, | |
| 10139 | .{ "f80", .f80_type }, | |
| 10140 | .{ "f128", .f128_type }, | |
| 10141 | ||
| 10142 | .{ "u0", .u0_type }, | |
| 10143 | .{ "u1", .u1_type }, | |
| 10144 | .{ "u8", .u8_type }, | |
| 10145 | .{ "i8", .i8_type }, | |
| 10141 | 10146 | .{ "u16", .u16_type }, |
| 10147 | .{ "i16", .i16_type }, | |
| 10142 | 10148 | .{ "u29", .u29_type }, |
| 10143 | 10149 | .{ "u32", .u32_type }, |
| 10150 | .{ "i32", .i32_type }, | |
| 10144 | 10151 | .{ "u64", .u64_type }, |
| 10152 | .{ "i64", .i64_type }, | |
| 10153 | .{ "u80", .u80_type }, | |
| 10145 | 10154 | .{ "u128", .u128_type }, |
| 10146 | .{ "u1", .u1_type }, | |
| 10147 | .{ "u8", .u8_type }, | |
| 10148 | .{ "undefined", .undef }, | |
| 10155 | .{ "i128", .i128_type }, | |
| 10156 | .{ "u256", .u256_type }, | |
| 10149 | 10157 | .{ "usize", .usize_type }, |
| 10150 | .{ "void", .void_type }, | |
| 10158 | .{ "isize", .isize_type }, | |
| 10151 | 10159 | }); |
| 10152 | 10160 | |
| 10153 | 10161 | comptime { |
lib/std/zig/Zir.zig-1| ... | ... | @@ -2197,7 +2197,6 @@ pub const Inst = struct { |
| 2197 | 2197 | /// and `[]Ref`. |
| 2198 | 2198 | pub const Ref = enum(u32) { |
| 2199 | 2199 | u0_type, |
| 2200 | i0_type, | |
| 2201 | 2200 | u1_type, |
| 2202 | 2201 | u8_type, |
| 2203 | 2202 | i8_type, |
src/Air.zig-1| ... | ... | @@ -1032,7 +1032,6 @@ pub const Inst = struct { |
| 1032 | 1032 | /// The ref `none` is an exception: it has the tag bit set but refers to the InternPool. |
| 1033 | 1033 | pub const Ref = enum(u32) { |
| 1034 | 1034 | u0_type = @intFromEnum(InternPool.Index.u0_type), |
| 1035 | i0_type = @intFromEnum(InternPool.Index.i0_type), | |
| 1036 | 1035 | u1_type = @intFromEnum(InternPool.Index.u1_type), |
| 1037 | 1036 | u8_type = @intFromEnum(InternPool.Index.u8_type), |
| 1038 | 1037 | i8_type = @intFromEnum(InternPool.Index.i8_type), |
src/InternPool.zig+1-8| ... | ... | @@ -3902,7 +3902,6 @@ pub const Index = enum(u32) { |
| 3902 | 3902 | pub const last_value: Index = .empty_tuple; |
| 3903 | 3903 | |
| 3904 | 3904 | u0_type, |
| 3905 | i0_type, | |
| 3906 | 3905 | u1_type, |
| 3907 | 3906 | u8_type, |
| 3908 | 3907 | i8_type, |
| ... | ... | @@ -4350,11 +4349,6 @@ pub const static_keys: [static_len]Key = .{ |
| 4350 | 4349 | .bits = 0, |
| 4351 | 4350 | } }, |
| 4352 | 4351 | |
| 4353 | .{ .int_type = .{ | |
| 4354 | .signedness = .signed, | |
| 4355 | .bits = 0, | |
| 4356 | } }, | |
| 4357 | ||
| 4358 | 4352 | .{ .int_type = .{ |
| 4359 | 4353 | .signedness = .unsigned, |
| 4360 | 4354 | .bits = 1, |
| ... | ... | @@ -7207,6 +7201,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7207 | 7201 | try items.ensureUnusedCapacity(1); |
| 7208 | 7202 | switch (key) { |
| 7209 | 7203 | .int_type => |int_type| { |
| 7204 | if (int_type.signedness == .signed) assert(int_type.bits > 0); | |
| 7210 | 7205 | const t: Tag = switch (int_type.signedness) { |
| 7211 | 7206 | .signed => .type_int_signed, |
| 7212 | 7207 | .unsigned => .type_int_unsigned, |
| ... | ... | @@ -11447,7 +11442,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11447 | 11442 | // mean that the range of type indices would not be dense. |
| 11448 | 11443 | return switch (index) { |
| 11449 | 11444 | .u0_type, |
| 11450 | .i0_type, | |
| 11451 | 11445 | .u1_type, |
| 11452 | 11446 | .u8_type, |
| 11453 | 11447 | .i8_type, |
| ... | ... | @@ -11772,7 +11766,6 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta |
| 11772 | 11766 | pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 11773 | 11767 | return switch (index) { |
| 11774 | 11768 | .u0_type, |
| 11775 | .i0_type, | |
| 11776 | 11769 | .u1_type, |
| 11777 | 11770 | .u8_type, |
| 11778 | 11771 | .i8_type, |
src/Sema.zig+5-2| ... | ... | @@ -19617,6 +19617,9 @@ fn zirReifyInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 19617 | 19617 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 19618 | 19618 | const signedness = try sema.resolveBuiltinEnum(block, signedness_src, extra.lhs, .Signedness, .{ .simple = .int_signedness }); |
| 19619 | 19619 | const bits: u16 = @intCast(try sema.resolveInt(block, bits_src, extra.rhs, .u16, .{ .simple = .int_bit_width })); |
| 19620 | if (bits == 0 and signedness == .signed) { | |
| 19621 | return sema.fail(block, bits_src, "signed integer cannot have bit width 0", .{}); | |
| 19622 | } | |
| 19620 | 19623 | return .fromType(try sema.pt.intType(signedness, bits)); |
| 19621 | 19624 | } |
| 19622 | 19625 | |
| ... | ... | @@ -20708,7 +20711,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 20708 | 20711 | } |
| 20709 | 20712 | |
| 20710 | 20713 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 20711 | if (dest_scalar_ty.intInfo(zcu).bits == 0) { | |
| 20714 | if (dest_scalar_ty.toIntern() == .u0_type) { | |
| 20712 | 20715 | if (block.wantSafety()) { |
| 20713 | 20716 | // Emit an explicit safety check. We can do this one like `abs(x) < 1`. |
| 20714 | 20717 | const abs_ref = try block.addTyOp(.abs, operand_ty, operand); |
| ... | ... | @@ -20824,7 +20827,7 @@ fn zirRoundCast( |
| 20824 | 20827 | |
| 20825 | 20828 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 20826 | 20829 | |
| 20827 | if (dest_scalar_ty.intInfo(zcu).bits == 0) { | |
| 20830 | if (dest_scalar_ty.toIntern() == .u0_type) { | |
| 20828 | 20831 | if (block.wantSafety()) { |
| 20829 | 20832 | const abs_ref = try block.addTyOp(.abs, operand_ty, operand); |
| 20830 | 20833 | const is_vector = dest_ty.zigTypeTag(zcu) == .vector; |
src/Sema/LowerZon.zig+5-9| ... | ... | @@ -448,16 +448,12 @@ fn lowerInt( |
| 448 | 448 | // If lhs has less than the 32 bits rhs can hold, we need to check the max and |
| 449 | 449 | // min values |
| 450 | 450 | if (std.math.cast(u5, lhs_info.bits)) |bits| { |
| 451 | const min_int: i32 = if (lhs_info.signedness == .unsigned or bits == 0) b: { | |
| 452 | break :b 0; | |
| 453 | } else b: { | |
| 454 | break :b -(@as(i32, 1) << (bits - 1)); | |
| 455 | }; | |
| 456 | const max_int: i32 = if (bits == 0) b: { | |
| 457 | break :b 0; | |
| 458 | } else b: { | |
| 459 | break :b (@as(i32, 1) << (bits - @intFromBool(lhs_info.signedness == .signed))) - 1; | |
| 451 | const unsigned_bits = bits - @intFromBool(lhs_info.signedness == .signed); | |
| 452 | const min_int: i32 = switch (lhs_info.signedness) { | |
| 453 | .unsigned => 0, | |
| 454 | .signed => -(@as(i32, 1) << unsigned_bits), | |
| 460 | 455 | }; |
| 456 | const max_int: i32 = (@as(i32, 1) << unsigned_bits) - 1; | |
| 461 | 457 | if (rhs < min_int or rhs > max_int) { |
| 462 | 458 | return self.fail( |
| 463 | 459 | node, |
src/Sema/arith.zig+9-5| ... | ... | @@ -20,7 +20,7 @@ pub fn incrementDefinedInt( |
| 20 | 20 | const zcu = pt.zcu; |
| 21 | 21 | assert(prev_val.typeOf(zcu).toIntern() == ty.toIntern()); |
| 22 | 22 | assert(!prev_val.isUndef(zcu)); |
| 23 | if (ty.intInfo(zcu).bits == 0) { | |
| 23 | if (ty.toIntern() == .u0_type) { | |
| 24 | 24 | return .{ .overflow = true, .val = try comptimeIntAdd(sema, prev_val, .one_comptime_int) }; |
| 25 | 25 | } |
| 26 | 26 | const res = try intAdd(sema, prev_val, try pt.intValue(ty, 1), ty); |
| ... | ... | @@ -1313,7 +1313,7 @@ fn bitwiseBinScalar( |
| 1313 | 1313 | 0b11 => return pt.undefValue(ty), |
| 1314 | 1314 | }; |
| 1315 | 1315 | }; |
| 1316 | if (ty.toIntern() == .u0_type or ty.toIntern() == .i0_type) return pt.intValue(ty, 0); | |
| 1316 | if (ty.toIntern() == .u0_type) return pt.intValue(ty, 0); | |
| 1317 | 1317 | // zig fmt: off |
| 1318 | 1318 | switch (op) { |
| 1319 | 1319 | .@"and" => return intBitwiseAnd(sema, def_lhs, def_rhs, ty), |
| ... | ... | @@ -2209,9 +2209,13 @@ fn intBitwiseNot(sema: *Sema, val: Value, ty: Type) !Value { |
| 2209 | 2209 | const zcu = pt.zcu; |
| 2210 | 2210 | |
| 2211 | 2211 | if (val.isUndef(zcu)) return pt.undefValue(ty); |
| 2212 | if (ty.toIntern() == .bool_type) return .makeBool(!val.toBool()); | |
| 2212 | switch (ty.toIntern()) { | |
| 2213 | .bool_type => return .makeBool(!val.toBool()), | |
| 2214 | .u0_type => return val, | |
| 2215 | else => {}, | |
| 2216 | } | |
| 2217 | ||
| 2213 | 2218 | const info = ty.intInfo(zcu); |
| 2214 | if (info.bits == 0) return val; | |
| 2215 | 2219 | |
| 2216 | 2220 | var val_space: Value.BigIntSpace = undefined; |
| 2217 | 2221 | const val_bigint = val.toBigInt(&val_space, zcu); |
| ... | ... | @@ -2231,7 +2235,7 @@ fn intValueAa(sema: *Sema, ty: Type) !Value { |
| 2231 | 2235 | const zcu = pt.zcu; |
| 2232 | 2236 | |
| 2233 | 2237 | if (ty.toIntern() == .bool_type) return .true; |
| 2234 | if (ty.toIntern() == .u0_type or ty.toIntern() == .i0_type) return pt.intValue(ty, 0); | |
| 2238 | if (ty.toIntern() == .u0_type) return pt.intValue(ty, 0); | |
| 2235 | 2239 | const info = ty.intInfo(zcu); |
| 2236 | 2240 | |
| 2237 | 2241 | const buf = try sema.arena.alloc(u8, (info.bits + 7) / 8); |
src/Type.zig+1-1| ... | ... | @@ -2272,7 +2272,7 @@ pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 2272 | 2272 | pub fn minIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 2273 | 2273 | const zcu = pt.zcu; |
| 2274 | 2274 | const info = ty.intInfo(zcu); |
| 2275 | if (info.signedness == .unsigned or info.bits == 0) return pt.intValue(dest_ty, 0); | |
| 2275 | if (info.signedness == .unsigned) return pt.intValue(dest_ty, 0); | |
| 2276 | 2276 | |
| 2277 | 2277 | if (std.math.cast(u6, info.bits - 1)) |shift| { |
| 2278 | 2278 | const n = @as(i64, std.math.minInt(i64)) >> (63 - shift); |
src/Value.zig+1-1| ... | ... | @@ -518,9 +518,9 @@ pub fn readFromPackedMemory( |
| 518 | 518 | }, |
| 519 | 519 | .int => { |
| 520 | 520 | if (buffer.len == 0) return pt.intValue(ty, 0); |
| 521 | if (ty.toIntern() == .u0_type) return pt.intValue(ty, 0); | |
| 521 | 522 | const int_info = ty.intInfo(zcu); |
| 522 | 523 | const bits = int_info.bits; |
| 523 | if (bits == 0) return pt.intValue(ty, 0); | |
| 524 | 524 | |
| 525 | 525 | // Fast path for integers <= u64 |
| 526 | 526 | if (bits <= 64) switch (int_info.signedness) { |
src/codegen/llvm.zig+1-1| ... | ... | @@ -2948,7 +2948,7 @@ pub const Object = struct { |
| 2948 | 2948 | const target = zcu.getTarget(); |
| 2949 | 2949 | const ip = &zcu.intern_pool; |
| 2950 | 2950 | return switch (t.toIntern()) { |
| 2951 | .u0_type, .i0_type => unreachable, // no runtime bits | |
| 2951 | .u0_type => unreachable, // no runtime bits | |
| 2952 | 2952 | inline .u1_type, |
| 2953 | 2953 | .u8_type, |
| 2954 | 2954 | .i8_type, |
src/codegen/llvm/FuncGen.zig+1-1| ... | ... | @@ -7410,7 +7410,7 @@ fn toLlvmAtomicRmwBinOp( |
| 7410 | 7410 | |
| 7411 | 7411 | fn minIntConst(b: *Builder, min_ty: Type, as_ty: Builder.Type, zcu: *const Zcu) Allocator.Error!Builder.Constant { |
| 7412 | 7412 | const info = min_ty.intInfo(zcu); |
| 7413 | if (info.signedness == .unsigned or info.bits == 0) { | |
| 7413 | if (info.signedness == .unsigned) { | |
| 7414 | 7414 | return b.intConst(as_ty, 0); |
| 7415 | 7415 | } |
| 7416 | 7416 | if (std.math.cast(u6, info.bits - 1)) |shift| { |
src/codegen/spirv/CodeGen.zig+2-2| ... | ... | @@ -1327,12 +1327,12 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id { |
| 1327 | 1327 | .indirect => return try cg.resolveType(.u1, .indirect), |
| 1328 | 1328 | }, |
| 1329 | 1329 | .int => { |
| 1330 | const int_info = ty.intInfo(zcu); | |
| 1331 | if (int_info.bits == 0) { | |
| 1330 | if (ty.toIntern() == .u0_type) { | |
| 1332 | 1331 | assert(repr == .indirect); |
| 1333 | 1332 | if (target.os.tag != .opencl) return cg.fail("cannot generate opaque type", .{}); |
| 1334 | 1333 | return try cg.module.opaqueType("u0"); |
| 1335 | 1334 | } |
| 1335 | const int_info = ty.intInfo(zcu); | |
| 1336 | 1336 | return try cg.module.intType(int_info.signedness, int_info.bits); |
| 1337 | 1337 | }, |
| 1338 | 1338 | .@"enum" => return try cg.resolveType(ty.intTagType(zcu), repr), |