mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-05-07 02:12:40 +03:00
compiler: remove i0 from the language
Resolves: https://github.com/ziglang/zig/issues/1593
This commit is contained in:
+58
-50
@@ -8073,39 +8073,42 @@ fn identifier(
|
||||
return rvalue(gz, ri, zir_const_ref, ident);
|
||||
}
|
||||
|
||||
if (ident_name_raw.len >= 2) integer: {
|
||||
// Keep in sync with logic in `comptimeExpr2`.
|
||||
const first_c = ident_name_raw[0];
|
||||
if (first_c == 'i' or first_c == 'u') {
|
||||
const signedness: std.builtin.Signedness = switch (first_c == 'i') {
|
||||
true => .signed,
|
||||
false => .unsigned,
|
||||
};
|
||||
if (ident_name_raw.len >= 3 and ident_name_raw[1] == '0') {
|
||||
return astgen.failNode(
|
||||
ident,
|
||||
"primitive integer type '{s}' has leading zero",
|
||||
.{ident_name_raw},
|
||||
);
|
||||
}
|
||||
const bit_count = parseBitCount(ident_name_raw[1..]) catch |err| switch (err) {
|
||||
error.Overflow => return astgen.failNode(
|
||||
ident,
|
||||
"primitive integer type '{s}' exceeds maximum bit width of 65535",
|
||||
.{ident_name_raw},
|
||||
),
|
||||
error.InvalidCharacter => break :integer,
|
||||
};
|
||||
const result = try gz.add(.{
|
||||
.tag = .int_type,
|
||||
.data = .{ .int_type = .{
|
||||
.src_node = gz.nodeIndexToRelative(ident),
|
||||
.signedness = signedness,
|
||||
.bit_count = bit_count,
|
||||
} },
|
||||
});
|
||||
return rvalue(gz, ri, result, ident);
|
||||
int_type: {
|
||||
if (ident_name_raw.len < 2) break :int_type;
|
||||
const signedness: std.builtin.Signedness = switch (ident_name_raw[0]) {
|
||||
'u' => .unsigned,
|
||||
'i' => .signed,
|
||||
else => break :int_type,
|
||||
};
|
||||
// `u0` already handled by `primitive_instrs`
|
||||
if (std.mem.eql(u8, ident_name_raw, "i0")) {
|
||||
return astgen.failNode(ident, "signed integer cannot have bit width 0", .{});
|
||||
}
|
||||
if (ident_name_raw[1] == '0') {
|
||||
assert(ident_name_raw.len >= 3); // `u0` and `i0` handled
|
||||
return astgen.failNode(
|
||||
ident,
|
||||
"primitive integer type '{s}' has leading zero",
|
||||
.{ident_name_raw},
|
||||
);
|
||||
}
|
||||
const bit_count = parseBitCount(ident_name_raw[1..]) catch |err| switch (err) {
|
||||
error.Overflow => return astgen.failNode(
|
||||
ident,
|
||||
"primitive integer type '{s}' exceeds maximum bit width of 65535",
|
||||
.{ident_name_raw},
|
||||
),
|
||||
error.InvalidCharacter => break :int_type,
|
||||
};
|
||||
const result = try gz.add(.{
|
||||
.tag = .int_type,
|
||||
.data = .{ .int_type = .{
|
||||
.src_node = gz.nodeIndexToRelative(ident),
|
||||
.signedness = signedness,
|
||||
.bit_count = bit_count,
|
||||
} },
|
||||
});
|
||||
return rvalue(gz, ri, result, ident);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10122,32 +10125,37 @@ const primitive_instrs = std.StaticStringMap(Zir.Inst.Ref).initComptime(.{
|
||||
.{ "c_ushort", .c_ushort_type },
|
||||
.{ "comptime_float", .comptime_float_type },
|
||||
.{ "comptime_int", .comptime_int_type },
|
||||
.{ "f128", .f128_type },
|
||||
.{ "f16", .f16_type },
|
||||
.{ "f32", .f32_type },
|
||||
.{ "f64", .f64_type },
|
||||
.{ "f80", .f80_type },
|
||||
.{ "false", .bool_false },
|
||||
.{ "i16", .i16_type },
|
||||
.{ "i32", .i32_type },
|
||||
.{ "i64", .i64_type },
|
||||
.{ "i128", .i128_type },
|
||||
.{ "i8", .i8_type },
|
||||
.{ "isize", .isize_type },
|
||||
.{ "noreturn", .noreturn_type },
|
||||
.{ "null", .null_value },
|
||||
.{ "true", .bool_true },
|
||||
.{ "type", .type_type },
|
||||
.{ "u16", .u16_type },
|
||||
.{ "u29", .u29_type },
|
||||
.{ "u32", .u32_type },
|
||||
.{ "u64", .u64_type },
|
||||
.{ "u128", .u128_type },
|
||||
.{ "undefined", .undef },
|
||||
.{ "void", .void_type },
|
||||
|
||||
.{ "f16", .f16_type },
|
||||
.{ "f32", .f32_type },
|
||||
.{ "f64", .f64_type },
|
||||
.{ "f80", .f80_type },
|
||||
.{ "f128", .f128_type },
|
||||
|
||||
.{ "u0", .u0_type },
|
||||
.{ "u1", .u1_type },
|
||||
.{ "u8", .u8_type },
|
||||
.{ "undefined", .undef },
|
||||
.{ "i8", .i8_type },
|
||||
.{ "u16", .u16_type },
|
||||
.{ "i16", .i16_type },
|
||||
.{ "u29", .u29_type },
|
||||
.{ "u32", .u32_type },
|
||||
.{ "i32", .i32_type },
|
||||
.{ "u64", .u64_type },
|
||||
.{ "i64", .i64_type },
|
||||
.{ "u80", .u80_type },
|
||||
.{ "u128", .u128_type },
|
||||
.{ "i128", .i128_type },
|
||||
.{ "u256", .u256_type },
|
||||
.{ "usize", .usize_type },
|
||||
.{ "void", .void_type },
|
||||
.{ "isize", .isize_type },
|
||||
});
|
||||
|
||||
comptime {
|
||||
|
||||
@@ -2197,7 +2197,6 @@ pub const Inst = struct {
|
||||
/// and `[]Ref`.
|
||||
pub const Ref = enum(u32) {
|
||||
u0_type,
|
||||
i0_type,
|
||||
u1_type,
|
||||
u8_type,
|
||||
i8_type,
|
||||
|
||||
@@ -1032,7 +1032,6 @@ pub const Inst = struct {
|
||||
/// The ref `none` is an exception: it has the tag bit set but refers to the InternPool.
|
||||
pub const Ref = enum(u32) {
|
||||
u0_type = @intFromEnum(InternPool.Index.u0_type),
|
||||
i0_type = @intFromEnum(InternPool.Index.i0_type),
|
||||
u1_type = @intFromEnum(InternPool.Index.u1_type),
|
||||
u8_type = @intFromEnum(InternPool.Index.u8_type),
|
||||
i8_type = @intFromEnum(InternPool.Index.i8_type),
|
||||
|
||||
+1
-8
@@ -3902,7 +3902,6 @@ pub const Index = enum(u32) {
|
||||
pub const last_value: Index = .empty_tuple;
|
||||
|
||||
u0_type,
|
||||
i0_type,
|
||||
u1_type,
|
||||
u8_type,
|
||||
i8_type,
|
||||
@@ -4350,11 +4349,6 @@ pub const static_keys: [static_len]Key = .{
|
||||
.bits = 0,
|
||||
} },
|
||||
|
||||
.{ .int_type = .{
|
||||
.signedness = .signed,
|
||||
.bits = 0,
|
||||
} },
|
||||
|
||||
.{ .int_type = .{
|
||||
.signedness = .unsigned,
|
||||
.bits = 1,
|
||||
@@ -7207,6 +7201,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
|
||||
try items.ensureUnusedCapacity(1);
|
||||
switch (key) {
|
||||
.int_type => |int_type| {
|
||||
if (int_type.signedness == .signed) assert(int_type.bits > 0);
|
||||
const t: Tag = switch (int_type.signedness) {
|
||||
.signed => .type_int_signed,
|
||||
.unsigned => .type_int_unsigned,
|
||||
@@ -11447,7 +11442,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
|
||||
// mean that the range of type indices would not be dense.
|
||||
return switch (index) {
|
||||
.u0_type,
|
||||
.i0_type,
|
||||
.u1_type,
|
||||
.u8_type,
|
||||
.i8_type,
|
||||
@@ -11772,7 +11766,6 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
|
||||
pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
|
||||
return switch (index) {
|
||||
.u0_type,
|
||||
.i0_type,
|
||||
.u1_type,
|
||||
.u8_type,
|
||||
.i8_type,
|
||||
|
||||
+5
-2
@@ -19617,6 +19617,9 @@ fn zirReifyInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const signedness = try sema.resolveBuiltinEnum(block, signedness_src, extra.lhs, .Signedness, .{ .simple = .int_signedness });
|
||||
const bits: u16 = @intCast(try sema.resolveInt(block, bits_src, extra.rhs, .u16, .{ .simple = .int_bit_width }));
|
||||
if (bits == 0 and signedness == .signed) {
|
||||
return sema.fail(block, bits_src, "signed integer cannot have bit width 0", .{});
|
||||
}
|
||||
return .fromType(try sema.pt.intType(signedness, bits));
|
||||
}
|
||||
|
||||
@@ -20708,7 +20711,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, operand_src);
|
||||
if (dest_scalar_ty.intInfo(zcu).bits == 0) {
|
||||
if (dest_scalar_ty.toIntern() == .u0_type) {
|
||||
if (block.wantSafety()) {
|
||||
// Emit an explicit safety check. We can do this one like `abs(x) < 1`.
|
||||
const abs_ref = try block.addTyOp(.abs, operand_ty, operand);
|
||||
@@ -20824,7 +20827,7 @@ fn zirRoundCast(
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, operand_src);
|
||||
|
||||
if (dest_scalar_ty.intInfo(zcu).bits == 0) {
|
||||
if (dest_scalar_ty.toIntern() == .u0_type) {
|
||||
if (block.wantSafety()) {
|
||||
const abs_ref = try block.addTyOp(.abs, operand_ty, operand);
|
||||
const is_vector = dest_ty.zigTypeTag(zcu) == .vector;
|
||||
|
||||
@@ -448,16 +448,12 @@ fn lowerInt(
|
||||
// If lhs has less than the 32 bits rhs can hold, we need to check the max and
|
||||
// min values
|
||||
if (std.math.cast(u5, lhs_info.bits)) |bits| {
|
||||
const min_int: i32 = if (lhs_info.signedness == .unsigned or bits == 0) b: {
|
||||
break :b 0;
|
||||
} else b: {
|
||||
break :b -(@as(i32, 1) << (bits - 1));
|
||||
};
|
||||
const max_int: i32 = if (bits == 0) b: {
|
||||
break :b 0;
|
||||
} else b: {
|
||||
break :b (@as(i32, 1) << (bits - @intFromBool(lhs_info.signedness == .signed))) - 1;
|
||||
const unsigned_bits = bits - @intFromBool(lhs_info.signedness == .signed);
|
||||
const min_int: i32 = switch (lhs_info.signedness) {
|
||||
.unsigned => 0,
|
||||
.signed => -(@as(i32, 1) << unsigned_bits),
|
||||
};
|
||||
const max_int: i32 = (@as(i32, 1) << unsigned_bits) - 1;
|
||||
if (rhs < min_int or rhs > max_int) {
|
||||
return self.fail(
|
||||
node,
|
||||
|
||||
+9
-5
@@ -20,7 +20,7 @@ pub fn incrementDefinedInt(
|
||||
const zcu = pt.zcu;
|
||||
assert(prev_val.typeOf(zcu).toIntern() == ty.toIntern());
|
||||
assert(!prev_val.isUndef(zcu));
|
||||
if (ty.intInfo(zcu).bits == 0) {
|
||||
if (ty.toIntern() == .u0_type) {
|
||||
return .{ .overflow = true, .val = try comptimeIntAdd(sema, prev_val, .one_comptime_int) };
|
||||
}
|
||||
const res = try intAdd(sema, prev_val, try pt.intValue(ty, 1), ty);
|
||||
@@ -1313,7 +1313,7 @@ fn bitwiseBinScalar(
|
||||
0b11 => return pt.undefValue(ty),
|
||||
};
|
||||
};
|
||||
if (ty.toIntern() == .u0_type or ty.toIntern() == .i0_type) return pt.intValue(ty, 0);
|
||||
if (ty.toIntern() == .u0_type) return pt.intValue(ty, 0);
|
||||
// zig fmt: off
|
||||
switch (op) {
|
||||
.@"and" => return intBitwiseAnd(sema, def_lhs, def_rhs, ty),
|
||||
@@ -2209,9 +2209,13 @@ fn intBitwiseNot(sema: *Sema, val: Value, ty: Type) !Value {
|
||||
const zcu = pt.zcu;
|
||||
|
||||
if (val.isUndef(zcu)) return pt.undefValue(ty);
|
||||
if (ty.toIntern() == .bool_type) return .makeBool(!val.toBool());
|
||||
switch (ty.toIntern()) {
|
||||
.bool_type => return .makeBool(!val.toBool()),
|
||||
.u0_type => return val,
|
||||
else => {},
|
||||
}
|
||||
|
||||
const info = ty.intInfo(zcu);
|
||||
if (info.bits == 0) return val;
|
||||
|
||||
var val_space: Value.BigIntSpace = undefined;
|
||||
const val_bigint = val.toBigInt(&val_space, zcu);
|
||||
@@ -2231,7 +2235,7 @@ fn intValueAa(sema: *Sema, ty: Type) !Value {
|
||||
const zcu = pt.zcu;
|
||||
|
||||
if (ty.toIntern() == .bool_type) return .true;
|
||||
if (ty.toIntern() == .u0_type or ty.toIntern() == .i0_type) return pt.intValue(ty, 0);
|
||||
if (ty.toIntern() == .u0_type) return pt.intValue(ty, 0);
|
||||
const info = ty.intInfo(zcu);
|
||||
|
||||
const buf = try sema.arena.alloc(u8, (info.bits + 7) / 8);
|
||||
|
||||
+1
-1
@@ -2272,7 +2272,7 @@ pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
|
||||
pub fn minIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
|
||||
const zcu = pt.zcu;
|
||||
const info = ty.intInfo(zcu);
|
||||
if (info.signedness == .unsigned or info.bits == 0) return pt.intValue(dest_ty, 0);
|
||||
if (info.signedness == .unsigned) return pt.intValue(dest_ty, 0);
|
||||
|
||||
if (std.math.cast(u6, info.bits - 1)) |shift| {
|
||||
const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);
|
||||
|
||||
+1
-1
@@ -518,9 +518,9 @@ pub fn readFromPackedMemory(
|
||||
},
|
||||
.int => {
|
||||
if (buffer.len == 0) return pt.intValue(ty, 0);
|
||||
if (ty.toIntern() == .u0_type) return pt.intValue(ty, 0);
|
||||
const int_info = ty.intInfo(zcu);
|
||||
const bits = int_info.bits;
|
||||
if (bits == 0) return pt.intValue(ty, 0);
|
||||
|
||||
// Fast path for integers <= u64
|
||||
if (bits <= 64) switch (int_info.signedness) {
|
||||
|
||||
@@ -2948,7 +2948,7 @@ pub const Object = struct {
|
||||
const target = zcu.getTarget();
|
||||
const ip = &zcu.intern_pool;
|
||||
return switch (t.toIntern()) {
|
||||
.u0_type, .i0_type => unreachable, // no runtime bits
|
||||
.u0_type => unreachable, // no runtime bits
|
||||
inline .u1_type,
|
||||
.u8_type,
|
||||
.i8_type,
|
||||
|
||||
@@ -7410,7 +7410,7 @@ fn toLlvmAtomicRmwBinOp(
|
||||
|
||||
fn minIntConst(b: *Builder, min_ty: Type, as_ty: Builder.Type, zcu: *const Zcu) Allocator.Error!Builder.Constant {
|
||||
const info = min_ty.intInfo(zcu);
|
||||
if (info.signedness == .unsigned or info.bits == 0) {
|
||||
if (info.signedness == .unsigned) {
|
||||
return b.intConst(as_ty, 0);
|
||||
}
|
||||
if (std.math.cast(u6, info.bits - 1)) |shift| {
|
||||
|
||||
@@ -1327,12 +1327,12 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
||||
.indirect => return try cg.resolveType(.u1, .indirect),
|
||||
},
|
||||
.int => {
|
||||
const int_info = ty.intInfo(zcu);
|
||||
if (int_info.bits == 0) {
|
||||
if (ty.toIntern() == .u0_type) {
|
||||
assert(repr == .indirect);
|
||||
if (target.os.tag != .opencl) return cg.fail("cannot generate opaque type", .{});
|
||||
return try cg.module.opaqueType("u0");
|
||||
}
|
||||
const int_info = ty.intInfo(zcu);
|
||||
return try cg.module.intType(int_info.signedness, int_info.bits);
|
||||
},
|
||||
.@"enum" => return try cg.resolveType(ty.intTagType(zcu), repr),
|
||||
|
||||
Reference in New Issue
Block a user