Commit ca3cf93b21
Changed files (12)
src/codegen/c.zig
@@ -1191,7 +1191,7 @@ pub const DeclGen = struct {
}
},
.Bool => {
- if (val.toBool()) {
+ if (val.toBool(mod)) {
return writer.writeAll("true");
} else {
return writer.writeAll("false");
src/codegen/llvm.zig
@@ -2793,7 +2793,7 @@ pub const DeclGen = struct {
if (std.debug.runtime_safety and false) check: {
if (t.zigTypeTag(mod) == .Opaque) break :check;
if (!t.hasRuntimeBits(mod)) break :check;
- if (!llvm_ty.isSized().toBool()) break :check;
+ if (!llvm_ty.isSized().toBool(mod)) break :check;
const zig_size = t.abiSize(mod);
const llvm_size = dg.object.target_data.abiSizeOfType(llvm_ty);
@@ -3272,7 +3272,7 @@ pub const DeclGen = struct {
switch (tv.ty.zigTypeTag(mod)) {
.Bool => {
const llvm_type = try dg.lowerType(tv.ty);
- return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
+ return if (tv.val.toBool(mod)) llvm_type.constAllOnes() else llvm_type.constNull();
},
// TODO this duplicates code with Pointer but they should share the handling
// of the tv.val.tag() and then Int should do extra constPtrToInt on top
src/codegen/spirv.zig
@@ -621,7 +621,7 @@ pub const DeclGen = struct {
switch (ty.zigTypeTag(mod)) {
.Int => try self.addInt(ty, val),
.Float => try self.addFloat(ty, val),
- .Bool => try self.addConstBool(val.toBool()),
+ .Bool => try self.addConstBool(val.toBool(mod)),
.Array => switch (val.tag()) {
.aggregate => {
const elem_vals = val.castTag(.aggregate).?.data;
@@ -989,8 +989,8 @@ pub const DeclGen = struct {
}
},
.Bool => switch (repr) {
- .direct => return try self.spv.constBool(result_ty_ref, val.toBool()),
- .indirect => return try self.spv.constInt(result_ty_ref, @boolToInt(val.toBool())),
+ .direct => return try self.spv.constBool(result_ty_ref, val.toBool(mod)),
+ .indirect => return try self.spv.constInt(result_ty_ref, @boolToInt(val.toBool(mod))),
},
.Float => return switch (ty.floatBits(target)) {
16 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float16 = val.toFloat(f16) } } }),
src/Air.zig
@@ -899,8 +899,10 @@ pub const Inst = struct {
type_info_type = @enumToInt(InternPool.Index.type_info_type),
manyptr_u8_type = @enumToInt(InternPool.Index.manyptr_u8_type),
manyptr_const_u8_type = @enumToInt(InternPool.Index.manyptr_const_u8_type),
+ manyptr_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.manyptr_const_u8_sentinel_0_type),
single_const_pointer_to_comptime_int_type = @enumToInt(InternPool.Index.single_const_pointer_to_comptime_int_type),
const_slice_u8_type = @enumToInt(InternPool.Index.const_slice_u8_type),
+ const_slice_u8_sentinel_0_type = @enumToInt(InternPool.Index.const_slice_u8_sentinel_0_type),
anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
var_args_param_type = @enumToInt(InternPool.Index.var_args_param_type),
@@ -908,6 +910,7 @@ pub const Inst = struct {
undef = @enumToInt(InternPool.Index.undef),
zero = @enumToInt(InternPool.Index.zero),
zero_usize = @enumToInt(InternPool.Index.zero_usize),
+ zero_u8 = @enumToInt(InternPool.Index.zero_u8),
one = @enumToInt(InternPool.Index.one),
one_usize = @enumToInt(InternPool.Index.one_usize),
calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
src/codegen.zig
@@ -494,7 +494,7 @@ pub fn generateSymbol(
return Result.ok;
},
.Bool => {
- const x: u8 = @boolToInt(typed_value.val.toBool());
+ const x: u8 = @boolToInt(typed_value.val.toBool(mod));
try code.append(x);
return Result.ok;
},
@@ -1213,7 +1213,7 @@ pub fn genTypedValue(
}
},
.Bool => {
- return GenResult.mcv(.{ .immediate = @boolToInt(typed_value.val.toBool()) });
+ return GenResult.mcv(.{ .immediate = @boolToInt(typed_value.val.toBool(mod)) });
},
.Optional => {
if (typed_value.ty.isPtrLikeOptional(mod)) {
src/InternPool.zig
@@ -318,8 +318,10 @@ pub const Index = enum(u32) {
type_info_type,
manyptr_u8_type,
manyptr_const_u8_type,
+ manyptr_const_u8_sentinel_0_type,
single_const_pointer_to_comptime_int_type,
const_slice_u8_type,
+ const_slice_u8_sentinel_0_type,
anyerror_void_error_union_type,
generic_poison_type,
var_args_param_type,
@@ -331,6 +333,8 @@ pub const Index = enum(u32) {
zero,
/// `0` (usize)
zero_usize,
+ /// `0` (u8)
+ zero_u8,
/// `1` (comptime_int)
one,
/// `1` (usize)
@@ -489,24 +493,43 @@ pub const static_keys = [_]Key{
.size = .Many,
} },
+ // manyptr_const_u8_type
.{ .ptr_type = .{
.elem_type = .u8_type,
.size = .Many,
.is_const = true,
} },
+ // manyptr_const_u8_sentinel_0_type
+ .{ .ptr_type = .{
+ .elem_type = .u8_type,
+ .sentinel = .zero_u8,
+ .size = .Many,
+ .is_const = true,
+ } },
+
.{ .ptr_type = .{
.elem_type = .comptime_int_type,
.size = .One,
.is_const = true,
} },
+ // const_slice_u8_type
.{ .ptr_type = .{
.elem_type = .u8_type,
.size = .Slice,
.is_const = true,
} },
+ // const_slice_u8_sentinel_0_type
+ .{ .ptr_type = .{
+ .elem_type = .u8_type,
+ .sentinel = .zero_u8,
+ .size = .Slice,
+ .is_const = true,
+ } },
+
+ // anyerror_void_error_union_type
.{ .error_union_type = .{
.error_set_type = .anyerror_type,
.payload_type = .void_type,
@@ -541,6 +564,14 @@ pub const static_keys = [_]Key{
},
} },
+ .{ .int = .{
+ .ty = .u8_type,
+ .big_int = .{
+ .limbs = &.{0},
+ .positive = true,
+ },
+ } },
+
.{ .int = .{
.ty = .comptime_int_type,
.big_int = .{
src/Module.zig
@@ -4847,31 +4847,37 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
decl.owns_tv = false;
var queue_linker_work = false;
var is_extern = false;
- switch (decl_tv.val.tag()) {
- .variable => {
- const variable = decl_tv.val.castTag(.variable).?.data;
- if (variable.owner_decl == decl_index) {
- decl.owns_tv = true;
- queue_linker_work = true;
-
- const copied_init = try variable.init.copy(decl_arena_allocator);
- variable.init = copied_init;
- }
- },
- .extern_fn => {
- const extern_fn = decl_tv.val.castTag(.extern_fn).?.data;
- if (extern_fn.owner_decl == decl_index) {
- decl.owns_tv = true;
- queue_linker_work = true;
- is_extern = true;
- }
- },
-
+ switch (decl_tv.val.ip_index) {
.generic_poison => unreachable,
- .unreachable_value => unreachable,
+ .none => switch (decl_tv.val.tag()) {
+ .variable => {
+ const variable = decl_tv.val.castTag(.variable).?.data;
+ if (variable.owner_decl == decl_index) {
+ decl.owns_tv = true;
+ queue_linker_work = true;
+
+ const copied_init = try variable.init.copy(decl_arena_allocator);
+ variable.init = copied_init;
+ }
+ },
+ .extern_fn => {
+ const extern_fn = decl_tv.val.castTag(.extern_fn).?.data;
+ if (extern_fn.owner_decl == decl_index) {
+ decl.owns_tv = true;
+ queue_linker_work = true;
+ is_extern = true;
+ }
+ },
+
+ .unreachable_value => unreachable,
- .function => {},
+ .function => {},
+ else => {
+ log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name });
+ queue_linker_work = true;
+ },
+ },
else => {
log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name });
queue_linker_work = true;
src/Sema.zig
@@ -1569,6 +1569,7 @@ fn analyzeBodyInner(
},
.condbr => blk: {
if (!block.is_comptime) break sema.zirCondbr(block, inst);
+ const mod = sema.mod;
// Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220
const inst_data = datas[inst].pl_node;
const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
@@ -1579,7 +1580,7 @@ fn analyzeBodyInner(
if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
return err;
};
- const inline_body = if (cond.val.toBool()) then_body else else_body;
+ const inline_body = if (cond.val.toBool(mod)) then_body else else_body;
try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
@@ -1591,6 +1592,7 @@ fn analyzeBodyInner(
}
},
.condbr_inline => blk: {
+ const mod = sema.mod;
const inst_data = datas[inst].pl_node;
const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
@@ -1600,7 +1602,7 @@ fn analyzeBodyInner(
if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
return err;
};
- const inline_body = if (cond.val.toBool()) then_body else else_body;
+ const inline_body = if (cond.val.toBool(mod)) then_body else else_body;
try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
const old_runtime_index = block.runtime_index;
@@ -1634,7 +1636,7 @@ fn analyzeBodyInner(
if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
return err;
};
- if (is_non_err_val.toBool()) {
+ if (is_non_err_val.toBool(mod)) {
break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);
}
const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
@@ -1647,6 +1649,7 @@ fn analyzeBodyInner(
},
.try_ptr => blk: {
if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst);
+ const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const src = inst_data.src();
const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
@@ -1660,7 +1663,7 @@ fn analyzeBodyInner(
if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
return err;
};
- if (is_non_err_val.toBool()) {
+ if (is_non_err_val.toBool(mod)) {
break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
}
const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
@@ -1741,11 +1744,12 @@ fn resolveConstBool(
zir_ref: Zir.Inst.Ref,
reason: []const u8,
) !bool {
+ const mod = sema.mod;
const air_inst = try sema.resolveInst(zir_ref);
const wanted_type = Type.bool;
const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
const val = try sema.resolveConstValue(block, src, coerced_inst, reason);
- return val.toBool();
+ return val.toBool(mod);
}
pub fn resolveConstString(
@@ -1843,9 +1847,12 @@ fn resolveConstMaybeUndefVal(
reason: []const u8,
) CompileError!Value {
if (try sema.resolveMaybeUndefValAllowVariables(inst)) |val| {
- switch (val.tag()) {
- .variable => return sema.failWithNeededComptime(block, src, reason),
+ switch (val.ip_index) {
.generic_poison => return error.GenericPoison,
+ .none => switch (val.tag()) {
+ .variable => return sema.failWithNeededComptime(block, src, reason),
+ else => return val,
+ },
else => return val,
}
}
@@ -1862,10 +1869,13 @@ fn resolveConstValue(
reason: []const u8,
) CompileError!Value {
if (try sema.resolveMaybeUndefValAllowVariables(air_ref)) |val| {
- switch (val.tag()) {
- .undef => return sema.failWithUseOfUndef(block, src),
- .variable => return sema.failWithNeededComptime(block, src, reason),
+ switch (val.ip_index) {
.generic_poison => return error.GenericPoison,
+ .none => switch (val.tag()) {
+ .undef => return sema.failWithUseOfUndef(block, src),
+ .variable => return sema.failWithNeededComptime(block, src, reason),
+ else => return val,
+ },
else => return val,
}
}
@@ -1900,12 +1910,11 @@ fn resolveMaybeUndefVal(
const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
switch (val.ip_index) {
.generic_poison => return error.GenericPoison,
- else => return val,
.none => switch (val.tag()) {
.variable => return null,
- .generic_poison => return error.GenericPoison,
else => return val,
},
+ else => return val,
}
}
@@ -1919,12 +1928,18 @@ fn resolveMaybeUndefValIntable(
) CompileError!?Value {
const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
var check = val;
- while (true) switch (check.tag()) {
- .variable, .decl_ref, .decl_ref_mut, .comptime_field_ptr => return null,
- .field_ptr => check = check.castTag(.field_ptr).?.data.container_ptr,
- .elem_ptr => check = check.castTag(.elem_ptr).?.data.array_ptr,
- .eu_payload_ptr, .opt_payload_ptr => check = check.cast(Value.Payload.PayloadPtr).?.data.container_ptr,
+ while (true) switch (check.ip_index) {
.generic_poison => return error.GenericPoison,
+ .none => switch (check.tag()) {
+ .variable, .decl_ref, .decl_ref_mut, .comptime_field_ptr => return null,
+ .field_ptr => check = check.castTag(.field_ptr).?.data.container_ptr,
+ .elem_ptr => check = check.castTag(.elem_ptr).?.data.array_ptr,
+ .eu_payload_ptr, .opt_payload_ptr => check = check.cast(Value.Payload.PayloadPtr).?.data.container_ptr,
+ else => {
+ try sema.resolveLazyValue(val);
+ return val;
+ },
+ },
else => {
try sema.resolveLazyValue(val);
return val;
@@ -6208,12 +6223,13 @@ fn popErrorReturnTrace(
operand: Air.Inst.Ref,
saved_error_trace_index: Air.Inst.Ref,
) CompileError!void {
+ const mod = sema.mod;
var is_non_error: ?bool = null;
var is_non_error_inst: Air.Inst.Ref = undefined;
if (operand != .none) {
is_non_error_inst = try sema.analyzeIsNonErr(block, src, operand);
if (try sema.resolveDefinedValue(block, src, is_non_error_inst)) |cond_val|
- is_non_error = cond_val.toBool();
+ is_non_error = cond_val.toBool(mod);
} else is_non_error = true; // no operand means pop unconditionally
if (is_non_error == true) {
@@ -7222,7 +7238,7 @@ fn analyzeInlineCallArg(
if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err);
return err;
};
- switch (arg_val.tag()) {
+ switch (arg_val.ip_index) {
.generic_poison, .generic_poison_type => {
// This function is currently evaluated as part of an as-of-yet unresolvable
// parameter or return type.
@@ -7261,7 +7277,7 @@ fn analyzeInlineCallArg(
if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err);
return err;
};
- switch (arg_val.tag()) {
+ switch (arg_val.ip_index) {
.generic_poison, .generic_poison_type => {
// This function is currently evaluated as part of an as-of-yet unresolvable
// parameter or return type.
@@ -7443,13 +7459,13 @@ fn instantiateGenericCall(
arg_ty.hashWithHasher(&hasher, mod);
generic_args[i] = .{
.ty = arg_ty,
- .val = Value.initTag(.generic_poison),
+ .val = Value.generic_poison,
.is_anytype = true,
};
} else {
generic_args[i] = .{
.ty = arg_ty,
- .val = Value.initTag(.generic_poison),
+ .val = Value.generic_poison,
.is_anytype = false,
};
}
@@ -7815,7 +7831,7 @@ fn resolveGenericInstantiationType(
} else {
child_sema.comptime_args[arg_i] = .{
.ty = copied_arg_ty,
- .val = Value.initTag(.generic_poison),
+ .val = Value.generic_poison,
};
}
@@ -8780,9 +8796,9 @@ fn resolveGenericBody(
switch (err) {
error.GenericPoison => {
if (dest_ty.ip_index == .type_type) {
- return Value.initTag(.generic_poison_type);
+ return Value.generic_poison_type;
} else {
- return Value.initTag(.generic_poison);
+ return Value.generic_poison;
}
},
else => |e| return e,
@@ -9394,7 +9410,7 @@ fn zirParam(
if (is_comptime) {
// If this is a comptime parameter we can add a constant generic_poison
// since this is also a generic parameter.
- const result = try sema.addConstant(param_ty, Value.initTag(.generic_poison));
+ const result = try sema.addConstant(param_ty, Value.generic_poison);
sema.inst_map.putAssumeCapacityNoClobber(inst, result);
} else {
// Otherwise we need a dummy runtime instruction.
@@ -11819,8 +11835,9 @@ fn validateSwitchItemBool(
src_node_offset: i32,
switch_prong_src: Module.SwitchProngSrc,
) CompileError!void {
+ const mod = sema.mod;
const item_val = (try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none)).val;
- if (item_val.toBool()) {
+ if (item_val.toBool(mod)) {
true_count.* += 1;
} else {
false_count.* += 1;
@@ -15462,7 +15479,7 @@ fn cmpSelf(
} else {
if (resolved_type.zigTypeTag(mod) == .Bool) {
// We can lower bool eq/neq more efficiently.
- return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src);
+ return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(mod), rhs_src);
}
break :src rhs_src;
}
@@ -15472,7 +15489,7 @@ fn cmpSelf(
if (resolved_type.zigTypeTag(mod) == .Bool) {
if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
- return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);
+ return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(mod), lhs_src);
}
}
break :src lhs_src;
@@ -16815,6 +16832,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const tracy = trace(@src());
defer tracy.end();
+ const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
@@ -16824,7 +16842,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
if (try sema.resolveMaybeUndefVal(operand)) |val| {
return if (val.isUndef())
sema.addConstUndef(Type.bool)
- else if (val.toBool())
+ else if (val.toBool(mod))
Air.Inst.Ref.bool_false
else
Air.Inst.Ref.bool_true;
@@ -16842,6 +16860,7 @@ fn zirBoolBr(
const tracy = trace(@src());
defer tracy.end();
+ const mod = sema.mod;
const datas = sema.code.instructions.items(.data);
const inst_data = datas[inst].bool_br;
const lhs = try sema.resolveInst(inst_data.lhs);
@@ -16851,9 +16870,9 @@ fn zirBoolBr(
const gpa = sema.gpa;
if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| {
- if (is_bool_or and lhs_val.toBool()) {
+ if (is_bool_or and lhs_val.toBool(mod)) {
return Air.Inst.Ref.bool_true;
- } else if (!is_bool_or and !lhs_val.toBool()) {
+ } else if (!is_bool_or and !lhs_val.toBool(mod)) {
return Air.Inst.Ref.bool_false;
}
// comptime-known left-hand side. No need for a block here; the result
@@ -16897,9 +16916,9 @@ fn zirBoolBr(
const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst);
if (!sema.typeOf(rhs_result).isNoReturn()) {
if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| {
- if (is_bool_or and rhs_val.toBool()) {
+ if (is_bool_or and rhs_val.toBool(mod)) {
return Air.Inst.Ref.bool_true;
- } else if (!is_bool_or and !rhs_val.toBool()) {
+ } else if (!is_bool_or and !rhs_val.toBool(mod)) {
return Air.Inst.Ref.bool_false;
}
}
@@ -17053,7 +17072,7 @@ fn zirCondbr(
const cond = try sema.coerce(parent_block, Type.bool, uncasted_cond, cond_src);
if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| {
- const body = if (cond_val.toBool()) then_body else else_body;
+ const body = if (cond_val.toBool(mod)) then_body else else_body;
try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src);
// We use `analyzeBodyInner` since we want to propagate any possible
@@ -17126,7 +17145,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
if (is_non_err != .none) {
const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?;
- if (is_non_err_val.toBool()) {
+ if (is_non_err_val.toBool(mod)) {
return sema.analyzeErrUnionPayload(parent_block, src, err_union_ty, err_union, operand_src, false);
}
// We can analyze the body directly in the parent block because we know there are
@@ -17173,7 +17192,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
if (is_non_err != .none) {
const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?;
- if (is_non_err_val.toBool()) {
+ if (is_non_err_val.toBool(mod)) {
return sema.analyzeErrUnionPayloadPtr(parent_block, src, operand, false, false);
}
// We can analyze the body directly in the parent block because we know there are
@@ -18509,11 +18528,12 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
}
fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
+ const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const operand = try sema.resolveInst(inst_data.operand);
if (try sema.resolveMaybeUndefVal(operand)) |val| {
if (val.isUndef()) return sema.addConstUndef(Type.u1);
- if (val.toBool()) return sema.addConstant(Type.u1, Value.one);
+ if (val.toBool(mod)) return sema.addConstant(Type.u1, Value.one);
return sema.addConstant(Type.u1, Value.zero);
}
return block.addUnOp(.bool_to_int, operand);
@@ -18811,12 +18831,12 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
const ty = try Type.ptr(sema.arena, mod, .{
.size = ptr_size,
- .mutable = !is_const_val.toBool(),
- .@"volatile" = is_volatile_val.toBool(),
+ .mutable = !is_const_val.toBool(mod),
+ .@"volatile" = is_volatile_val.toBool(mod),
.@"align" = abi_align,
.@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
.pointee_type = try elem_ty.copy(sema.arena),
- .@"allowzero" = is_allowzero_val.toBool(),
+ .@"allowzero" = is_allowzero_val.toBool(mod),
.sentinel = actual_sentinel,
});
return sema.addType(ty);
@@ -18932,7 +18952,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
}
- return try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy, is_tuple_val.toBool());
+ return try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
},
.Enum => {
const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
@@ -18961,7 +18981,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
const enum_ty_payload = try new_decl_arena_allocator.create(Type.Payload.EnumFull);
enum_ty_payload.* = .{
.base = .{
- .tag = if (!is_exhaustive_val.toBool())
+ .tag = if (!is_exhaustive_val.toBool(mod))
.enum_nonexhaustive
else
.enum_full,
@@ -19295,9 +19315,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
// alignment: comptime_int,
const alignment_val = struct_val[1];
// is_generic: bool,
- const is_generic = struct_val[2].toBool();
+ const is_generic = struct_val[2].toBool(mod);
// is_var_args: bool,
- const is_var_args = struct_val[3].toBool();
+ const is_var_args = struct_val[3].toBool(mod);
// return_type: ?type,
const return_type_val = struct_val[4];
// args: []const Param,
@@ -19339,9 +19359,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
const arg_val = arg.castTag(.aggregate).?.data;
// TODO use reflection instead of magic numbers here
// is_generic: bool,
- const arg_is_generic = arg_val[0].toBool();
+ const arg_is_generic = arg_val[0].toBool(mod);
// is_noalias: bool,
- const arg_is_noalias = arg_val[1].toBool();
+ const arg_is_noalias = arg_val[1].toBool(mod);
// type: ?type,
const param_type_opt_val = arg_val[2];
@@ -19455,9 +19475,9 @@ fn reifyStruct(
if (layout == .Packed) {
if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
- if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});
+ if (is_comptime_val.toBool(mod)) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});
}
- if (layout == .Extern and is_comptime_val.toBool()) {
+ if (layout == .Extern and is_comptime_val.toBool(mod)) {
return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});
}
@@ -19499,7 +19519,7 @@ fn reifyStruct(
opt_val;
break :blk try payload_val.copy(new_decl_arena_allocator);
} else Value.initTag(.unreachable_value);
- if (is_comptime_val.toBool() and default_val.tag() == .unreachable_value) {
+ if (is_comptime_val.toBool(mod) and default_val.tag() == .unreachable_value) {
return sema.fail(block, src, "comptime field without default initialization value", .{});
}
@@ -19508,7 +19528,7 @@ fn reifyStruct(
.ty = field_ty,
.abi_align = abi_align,
.default_val = default_val,
- .is_comptime = is_comptime_val.toBool(),
+ .is_comptime = is_comptime_val.toBool(mod),
.offset = undefined,
};
@@ -21446,7 +21466,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
const elems = try sema.gpa.alloc(Value, vec_len);
for (elems, 0..) |*elem, i| {
const pred_elem_val = pred_val.elemValueBuffer(sema.mod, i, &buf);
- const should_choose_a = pred_elem_val.toBool();
+ const should_choose_a = pred_elem_val.toBool(mod);
if (should_choose_a) {
elem.* = a_val.elemValueBuffer(sema.mod, i, &buf);
} else {
@@ -22956,7 +22976,7 @@ fn resolveExternOptions(
.name = name,
.library_name = library_name,
.linkage = linkage,
- .is_thread_local = is_thread_local_val.toBool(),
+ .is_thread_local = is_thread_local_val.toBool(mod),
};
}
@@ -31760,8 +31780,10 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
.enum_literal_type,
.manyptr_u8_type,
.manyptr_const_u8_type,
+ .manyptr_const_u8_sentinel_0_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .const_slice_u8_sentinel_0_type,
.anyerror_void_error_union_type,
.generic_poison_type,
.var_args_param_type,
@@ -31771,6 +31793,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
.undef => unreachable,
.zero => unreachable,
.zero_usize => unreachable,
+ .zero_u8 => unreachable,
.one => unreachable,
.one_usize => unreachable,
.calling_convention_c => unreachable,
@@ -34225,12 +34248,9 @@ fn intFitsInType(
switch (val.tag()) {
.zero,
.undef,
- .bool_false,
=> return true,
- .one,
- .bool_true,
- => switch (ty.zigTypeTag(mod)) {
+ .one => switch (ty.zigTypeTag(mod)) {
.Int => {
const info = ty.intInfo(mod);
return switch (info.signedness) {
src/type.zig
@@ -2054,22 +2054,22 @@ pub const Type = struct {
pub fn toValue(self: Type, allocator: Allocator) Allocator.Error!Value {
if (self.ip_index != .none) return self.ip_index.toValue();
switch (self.tag()) {
- .u1 => return Value.initTag(.u1_type),
- .u8 => return Value.initTag(.u8_type),
- .i8 => return Value.initTag(.i8_type),
- .u16 => return Value.initTag(.u16_type),
- .u29 => return Value.initTag(.u29_type),
- .i16 => return Value.initTag(.i16_type),
- .u32 => return Value.initTag(.u32_type),
- .i32 => return Value.initTag(.i32_type),
- .u64 => return Value.initTag(.u64_type),
- .i64 => return Value.initTag(.i64_type),
- .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
- .const_slice_u8 => return Value.initTag(.const_slice_u8_type),
- .const_slice_u8_sentinel_0 => return Value.initTag(.const_slice_u8_sentinel_0_type),
- .manyptr_u8 => return Value.initTag(.manyptr_u8_type),
- .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type),
- .manyptr_const_u8_sentinel_0 => return Value.initTag(.manyptr_const_u8_sentinel_0_type),
+ .u1 => return Value{ .ip_index = .u1_type, .legacy = undefined },
+ .u8 => return Value{ .ip_index = .u8_type, .legacy = undefined },
+ .i8 => return Value{ .ip_index = .i8_type, .legacy = undefined },
+ .u16 => return Value{ .ip_index = .u16_type, .legacy = undefined },
+ .u29 => return Value{ .ip_index = .u29_type, .legacy = undefined },
+ .i16 => return Value{ .ip_index = .i16_type, .legacy = undefined },
+ .u32 => return Value{ .ip_index = .u32_type, .legacy = undefined },
+ .i32 => return Value{ .ip_index = .i32_type, .legacy = undefined },
+ .u64 => return Value{ .ip_index = .u64_type, .legacy = undefined },
+ .i64 => return Value{ .ip_index = .i64_type, .legacy = undefined },
+ .single_const_pointer_to_comptime_int => return Value{ .ip_index = .single_const_pointer_to_comptime_int_type, .legacy = undefined },
+ .const_slice_u8 => return Value{ .ip_index = .const_slice_u8_type, .legacy = undefined },
+ .const_slice_u8_sentinel_0 => return Value{ .ip_index = .const_slice_u8_sentinel_0_type, .legacy = undefined },
+ .manyptr_u8 => return Value{ .ip_index = .manyptr_u8_type, .legacy = undefined },
+ .manyptr_const_u8 => return Value{ .ip_index = .manyptr_const_u8_type, .legacy = undefined },
+ .manyptr_const_u8_sentinel_0 => return Value{ .ip_index = .manyptr_const_u8_sentinel_0_type, .legacy = undefined },
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
else => return Value.Tag.ty.create(allocator, self),
src/TypedValue.zig
@@ -77,66 +77,14 @@ pub fn print(
return writer.writeAll("(variable)");
while (true) switch (val.tag()) {
- .u1_type => return writer.writeAll("u1"),
- .u8_type => return writer.writeAll("u8"),
- .i8_type => return writer.writeAll("i8"),
- .u16_type => return writer.writeAll("u16"),
- .i16_type => return writer.writeAll("i16"),
- .u29_type => return writer.writeAll("u29"),
- .u32_type => return writer.writeAll("u32"),
- .i32_type => return writer.writeAll("i32"),
- .u64_type => return writer.writeAll("u64"),
- .i64_type => return writer.writeAll("i64"),
- .u128_type => return writer.writeAll("u128"),
- .i128_type => return writer.writeAll("i128"),
- .isize_type => return writer.writeAll("isize"),
- .usize_type => return writer.writeAll("usize"),
- .c_char_type => return writer.writeAll("c_char"),
- .c_short_type => return writer.writeAll("c_short"),
- .c_ushort_type => return writer.writeAll("c_ushort"),
- .c_int_type => return writer.writeAll("c_int"),
- .c_uint_type => return writer.writeAll("c_uint"),
- .c_long_type => return writer.writeAll("c_long"),
- .c_ulong_type => return writer.writeAll("c_ulong"),
- .c_longlong_type => return writer.writeAll("c_longlong"),
- .c_ulonglong_type => return writer.writeAll("c_ulonglong"),
- .c_longdouble_type => return writer.writeAll("c_longdouble"),
- .f16_type => return writer.writeAll("f16"),
- .f32_type => return writer.writeAll("f32"),
- .f64_type => return writer.writeAll("f64"),
- .f80_type => return writer.writeAll("f80"),
- .f128_type => return writer.writeAll("f128"),
- .anyopaque_type => return writer.writeAll("anyopaque"),
- .bool_type => return writer.writeAll("bool"),
- .void_type => return writer.writeAll("void"),
- .type_type => return writer.writeAll("type"),
- .anyerror_type => return writer.writeAll("anyerror"),
- .comptime_int_type => return writer.writeAll("comptime_int"),
- .comptime_float_type => return writer.writeAll("comptime_float"),
- .noreturn_type => return writer.writeAll("noreturn"),
- .null_type => return writer.writeAll("@Type(.Null)"),
- .undefined_type => return writer.writeAll("@Type(.Undefined)"),
.single_const_pointer_to_comptime_int_type => return writer.writeAll("*const comptime_int"),
- .anyframe_type => return writer.writeAll("anyframe"),
.const_slice_u8_type => return writer.writeAll("[]const u8"),
.const_slice_u8_sentinel_0_type => return writer.writeAll("[:0]const u8"),
.anyerror_void_error_union_type => return writer.writeAll("anyerror!void"),
- .enum_literal_type => return writer.writeAll("@Type(.EnumLiteral)"),
.manyptr_u8_type => return writer.writeAll("[*]u8"),
.manyptr_const_u8_type => return writer.writeAll("[*]const u8"),
.manyptr_const_u8_sentinel_0_type => return writer.writeAll("[*:0]const u8"),
- .atomic_order_type => return writer.writeAll("std.builtin.AtomicOrder"),
- .atomic_rmw_op_type => return writer.writeAll("std.builtin.AtomicRmwOp"),
- .calling_convention_type => return writer.writeAll("std.builtin.CallingConvention"),
- .address_space_type => return writer.writeAll("std.builtin.AddressSpace"),
- .float_mode_type => return writer.writeAll("std.builtin.FloatMode"),
- .reduce_op_type => return writer.writeAll("std.builtin.ReduceOp"),
- .modifier_type => return writer.writeAll("std.builtin.CallModifier"),
- .prefetch_options_type => return writer.writeAll("std.builtin.PrefetchOptions"),
- .export_options_type => return writer.writeAll("std.builtin.ExportOptions"),
- .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"),
- .type_info_type => return writer.writeAll("std.builtin.Type"),
.empty_struct_value, .aggregate => {
if (level == 0) {
@@ -221,11 +169,8 @@ pub fn print(
.undef => return writer.writeAll("undefined"),
.zero => return writer.writeAll("0"),
.one => return writer.writeAll("1"),
- .void_value => return writer.writeAll("{}"),
.unreachable_value => return writer.writeAll("unreachable"),
.the_only_possible_value => return writer.writeAll("0"),
- .bool_true => return writer.writeAll("true"),
- .bool_false => return writer.writeAll("false"),
.ty => return val.castTag(.ty).?.data.print(writer, mod),
.int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
.int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
@@ -487,8 +432,6 @@ pub fn print(
// TODO these should not appear in this function
.inferred_alloc => return writer.writeAll("(inferred allocation value)"),
.inferred_alloc_comptime => return writer.writeAll("(inferred comptime allocation value)"),
- .generic_poison_type => return writer.writeAll("(generic poison type)"),
- .generic_poison => return writer.writeAll("(generic poison)"),
.runtime_value => return writer.writeAll("[runtime value]"),
};
}
src/value.zig
@@ -33,58 +33,6 @@ pub const Value = struct {
// Keep in sync with tools/stage2_pretty_printers_common.py
pub const Tag = enum(usize) {
// The first section of this enum are tags that require no payload.
- u1_type,
- u8_type,
- i8_type,
- u16_type,
- i16_type,
- u29_type,
- u32_type,
- i32_type,
- u64_type,
- i64_type,
- u128_type,
- i128_type,
- usize_type,
- isize_type,
- c_char_type,
- c_short_type,
- c_ushort_type,
- c_int_type,
- c_uint_type,
- c_long_type,
- c_ulong_type,
- c_longlong_type,
- c_ulonglong_type,
- c_longdouble_type,
- f16_type,
- f32_type,
- f64_type,
- f80_type,
- f128_type,
- anyopaque_type,
- bool_type,
- void_type,
- type_type,
- anyerror_type,
- comptime_int_type,
- comptime_float_type,
- noreturn_type,
- anyframe_type,
- null_type,
- undefined_type,
- enum_literal_type,
- atomic_order_type,
- atomic_rmw_op_type,
- calling_convention_type,
- address_space_type,
- float_mode_type,
- reduce_op_type,
- modifier_type,
- prefetch_options_type,
- export_options_type,
- extern_options_type,
- type_info_type,
manyptr_u8_type,
manyptr_const_u8_type,
manyptr_const_u8_sentinel_0_type,
@@ -92,19 +40,14 @@ pub const Value = struct {
const_slice_u8_type,
const_slice_u8_sentinel_0_type,
anyerror_void_error_union_type,
- generic_poison_type,
undef,
zero,
one,
- void_value,
unreachable_value,
/// The only possible value for a particular type, which is stored externally.
the_only_possible_value,
null_value,
- bool_true,
- bool_false,
- generic_poison,
empty_struct_value,
empty_array, // See last_no_payload_tag below.
@@ -197,78 +140,22 @@ pub const Value = struct {
pub fn Type(comptime t: Tag) type {
return switch (t) {
- .u1_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u29_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_char_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f80_type,
- .f128_type,
- .anyopaque_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
.single_const_pointer_to_comptime_int_type,
- .anyframe_type,
.const_slice_u8_type,
.const_slice_u8_sentinel_0_type,
.anyerror_void_error_union_type,
- .generic_poison_type,
- .enum_literal_type,
+
.undef,
.zero,
.one,
- .void_value,
.unreachable_value,
.the_only_possible_value,
.empty_struct_value,
.empty_array,
.null_value,
- .bool_true,
- .bool_false,
.manyptr_u8_type,
.manyptr_const_u8_type,
.manyptr_const_u8_sentinel_0_type,
- .atomic_order_type,
- .atomic_rmw_op_type,
- .calling_convention_type,
- .address_space_type,
- .float_mode_type,
- .reduce_op_type,
- .modifier_type,
- .prefetch_options_type,
- .export_options_type,
- .extern_options_type,
- .type_info_type,
- .generic_poison,
=> @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),
.int_big_positive,
@@ -418,78 +305,22 @@ pub const Value = struct {
.legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
};
} else switch (self.legacy.ptr_otherwise.tag) {
- .u1_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u29_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_char_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f80_type,
- .f128_type,
- .anyopaque_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
.single_const_pointer_to_comptime_int_type,
- .anyframe_type,
.const_slice_u8_type,
.const_slice_u8_sentinel_0_type,
.anyerror_void_error_union_type,
- .generic_poison_type,
- .enum_literal_type,
+
.undef,
.zero,
.one,
- .void_value,
.unreachable_value,
.the_only_possible_value,
.empty_array,
.null_value,
- .bool_true,
- .bool_false,
.empty_struct_value,
.manyptr_u8_type,
.manyptr_const_u8_type,
.manyptr_const_u8_sentinel_0_type,
- .atomic_order_type,
- .atomic_rmw_op_type,
- .calling_convention_type,
- .address_space_type,
- .float_mode_type,
- .reduce_op_type,
- .modifier_type,
- .prefetch_options_type,
- .export_options_type,
- .extern_options_type,
- .type_info_type,
- .generic_poison,
=> unreachable,
.ty, .lazy_align, .lazy_size => {
@@ -722,67 +553,13 @@ pub const Value = struct {
}
var val = start_val;
while (true) switch (val.tag()) {
- .u1_type => return out_stream.writeAll("u1"),
- .u8_type => return out_stream.writeAll("u8"),
- .i8_type => return out_stream.writeAll("i8"),
- .u16_type => return out_stream.writeAll("u16"),
- .u29_type => return out_stream.writeAll("u29"),
- .i16_type => return out_stream.writeAll("i16"),
- .u32_type => return out_stream.writeAll("u32"),
- .i32_type => return out_stream.writeAll("i32"),
- .u64_type => return out_stream.writeAll("u64"),
- .i64_type => return out_stream.writeAll("i64"),
- .u128_type => return out_stream.writeAll("u128"),
- .i128_type => return out_stream.writeAll("i128"),
- .isize_type => return out_stream.writeAll("isize"),
- .usize_type => return out_stream.writeAll("usize"),
- .c_char_type => return out_stream.writeAll("c_char"),
- .c_short_type => return out_stream.writeAll("c_short"),
- .c_ushort_type => return out_stream.writeAll("c_ushort"),
- .c_int_type => return out_stream.writeAll("c_int"),
- .c_uint_type => return out_stream.writeAll("c_uint"),
- .c_long_type => return out_stream.writeAll("c_long"),
- .c_ulong_type => return out_stream.writeAll("c_ulong"),
- .c_longlong_type => return out_stream.writeAll("c_longlong"),
- .c_ulonglong_type => return out_stream.writeAll("c_ulonglong"),
- .c_longdouble_type => return out_stream.writeAll("c_longdouble"),
- .f16_type => return out_stream.writeAll("f16"),
- .f32_type => return out_stream.writeAll("f32"),
- .f64_type => return out_stream.writeAll("f64"),
- .f80_type => return out_stream.writeAll("f80"),
- .f128_type => return out_stream.writeAll("f128"),
- .anyopaque_type => return out_stream.writeAll("anyopaque"),
- .bool_type => return out_stream.writeAll("bool"),
- .void_type => return out_stream.writeAll("void"),
- .type_type => return out_stream.writeAll("type"),
- .anyerror_type => return out_stream.writeAll("anyerror"),
- .comptime_int_type => return out_stream.writeAll("comptime_int"),
- .comptime_float_type => return out_stream.writeAll("comptime_float"),
- .noreturn_type => return out_stream.writeAll("noreturn"),
- .null_type => return out_stream.writeAll("@Type(.Null)"),
- .undefined_type => return out_stream.writeAll("@Type(.Undefined)"),
.single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
- .anyframe_type => return out_stream.writeAll("anyframe"),
.const_slice_u8_type => return out_stream.writeAll("[]const u8"),
.const_slice_u8_sentinel_0_type => return out_stream.writeAll("[:0]const u8"),
.anyerror_void_error_union_type => return out_stream.writeAll("anyerror!void"),
- .generic_poison_type => return out_stream.writeAll("(generic poison type)"),
- .generic_poison => return out_stream.writeAll("(generic poison)"),
- .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
.manyptr_u8_type => return out_stream.writeAll("[*]u8"),
.manyptr_const_u8_type => return out_stream.writeAll("[*]const u8"),
.manyptr_const_u8_sentinel_0_type => return out_stream.writeAll("[*:0]const u8"),
- .atomic_order_type => return out_stream.writeAll("std.builtin.AtomicOrder"),
- .atomic_rmw_op_type => return out_stream.writeAll("std.builtin.AtomicRmwOp"),
- .calling_convention_type => return out_stream.writeAll("std.builtin.CallingConvention"),
- .address_space_type => return out_stream.writeAll("std.builtin.AddressSpace"),
- .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),
- .reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"),
- .modifier_type => return out_stream.writeAll("std.builtin.CallModifier"),
- .prefetch_options_type => return out_stream.writeAll("std.builtin.PrefetchOptions"),
- .export_options_type => return out_stream.writeAll("std.builtin.ExportOptions"),
- .extern_options_type => return out_stream.writeAll("std.builtin.ExternOptions"),
- .type_info_type => return out_stream.writeAll("std.builtin.Type"),
.empty_struct_value => return out_stream.writeAll("struct {}{}"),
.aggregate => {
@@ -795,11 +572,8 @@ pub const Value = struct {
.undef => return out_stream.writeAll("undefined"),
.zero => return out_stream.writeAll("0"),
.one => return out_stream.writeAll("1"),
- .void_value => return out_stream.writeAll("{}"),
.unreachable_value => return out_stream.writeAll("unreachable"),
.the_only_possible_value => return out_stream.writeAll("(the only possible value)"),
- .bool_true => return out_stream.writeAll("true"),
- .bool_false => return out_stream.writeAll("false"),
.ty => return val.castTag(.ty).?.data.dump("", options, out_stream),
.lazy_align => {
try out_stream.writeAll("@alignOf(");
@@ -943,74 +717,16 @@ pub const Value = struct {
/// Asserts that the value is representable as a type.
pub fn toType(self: Value) Type {
- if (self.ip_index != .none) {
- return .{
- .ip_index = self.ip_index,
- .legacy = undefined,
- };
- }
+ if (self.ip_index != .none) return self.ip_index.toType();
return switch (self.tag()) {
.ty => self.castTag(.ty).?.data,
- .u1_type => Type.u1,
- .u8_type => Type.u8,
- .i8_type => Type.i8,
- .u16_type => Type.u16,
- .i16_type => Type.i16,
- .u29_type => Type.u29,
- .u32_type => Type.u32,
- .i32_type => Type.i32,
- .u64_type => Type.u64,
- .i64_type => Type.i64,
- .u128_type => Type.u128,
- .i128_type => Type.i128,
- .usize_type => Type.usize,
- .isize_type => Type.isize,
- .c_char_type => Type.c_char,
- .c_short_type => Type.c_short,
- .c_ushort_type => Type.c_ushort,
- .c_int_type => Type.c_int,
- .c_uint_type => Type.c_uint,
- .c_long_type => Type.c_long,
- .c_ulong_type => Type.c_ulong,
- .c_longlong_type => Type.c_longlong,
- .c_ulonglong_type => Type.c_ulonglong,
- .c_longdouble_type => Type.c_longdouble,
- .f16_type => Type.f16,
- .f32_type => Type.f32,
- .f64_type => Type.f64,
- .f80_type => Type.f80,
- .f128_type => Type.f128,
- .anyopaque_type => Type.anyopaque,
- .bool_type => Type.bool,
- .void_type => Type.void,
- .type_type => Type.type,
- .anyerror_type => Type.anyerror,
- .comptime_int_type => Type.comptime_int,
- .comptime_float_type => Type.comptime_float,
- .noreturn_type => Type.noreturn,
- .null_type => Type.null,
- .undefined_type => Type.undefined,
.single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
- .anyframe_type => Type.@"anyframe",
.const_slice_u8_type => Type.initTag(.const_slice_u8),
.const_slice_u8_sentinel_0_type => Type.initTag(.const_slice_u8_sentinel_0),
.anyerror_void_error_union_type => Type.initTag(.anyerror_void_error_union),
- .generic_poison_type => .{ .ip_index = .generic_poison_type, .legacy = undefined },
- .enum_literal_type => .{ .ip_index = .enum_literal_type, .legacy = undefined },
.manyptr_u8_type => Type.initTag(.manyptr_u8),
.manyptr_const_u8_type => Type.initTag(.manyptr_const_u8),
.manyptr_const_u8_sentinel_0_type => Type.initTag(.manyptr_const_u8_sentinel_0),
- .atomic_order_type => .{ .ip_index = .atomic_order_type, .legacy = undefined },
- .atomic_rmw_op_type => .{ .ip_index = .atomic_rmw_op_type, .legacy = undefined },
- .calling_convention_type => .{ .ip_index = .calling_convention_type, .legacy = undefined },
- .address_space_type => .{ .ip_index = .address_space_type, .legacy = undefined },
- .float_mode_type => .{ .ip_index = .float_mode_type, .legacy = undefined },
- .reduce_op_type => .{ .ip_index = .reduce_op_type, .legacy = undefined },
- .modifier_type => .{ .ip_index = .call_modifier_type, .legacy = undefined },
- .prefetch_options_type => .{ .ip_index = .prefetch_options_type, .legacy = undefined },
- .export_options_type => .{ .ip_index = .export_options_type, .legacy = undefined },
- .extern_options_type => .{ .ip_index = .extern_options_type, .legacy = undefined },
- .type_info_type => .{ .ip_index = .type_info_type, .legacy = undefined },
else => unreachable,
};
@@ -1133,58 +849,63 @@ pub const Value = struct {
mod: *const Module,
opt_sema: ?*Sema,
) Module.CompileError!BigIntConst {
- switch (val.tag()) {
- .null_value,
- .zero,
- .bool_false,
- .the_only_possible_value, // i0, u0
- => return BigIntMutable.init(&space.limbs, 0).toConst(),
+ switch (val.ip_index) {
+ .bool_false => return BigIntMutable.init(&space.limbs, 0).toConst(),
+ .bool_true => return BigIntMutable.init(&space.limbs, 1).toConst(),
+ .none => switch (val.tag()) {
+ .null_value,
+ .zero,
+ .the_only_possible_value, // i0, u0
+ => return BigIntMutable.init(&space.limbs, 0).toConst(),
- .one,
- .bool_true,
- => return BigIntMutable.init(&space.limbs, 1).toConst(),
+ .one => return BigIntMutable.init(&space.limbs, 1).toConst(),
- .enum_field_index => {
- const index = val.castTag(.enum_field_index).?.data;
- return BigIntMutable.init(&space.limbs, index).toConst();
- },
- .runtime_value => {
- const sub_val = val.castTag(.runtime_value).?.data;
- return sub_val.toBigIntAdvanced(space, mod, opt_sema);
- },
- .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
- .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
- .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
- .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
+ .enum_field_index => {
+ const index = val.castTag(.enum_field_index).?.data;
+ return BigIntMutable.init(&space.limbs, index).toConst();
+ },
+ .runtime_value => {
+ const sub_val = val.castTag(.runtime_value).?.data;
+ return sub_val.toBigIntAdvanced(space, mod, opt_sema);
+ },
+ .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
+ .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
+ .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
+ .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
- .undef => unreachable,
+ .undef => unreachable,
- .lazy_align => {
- const ty = val.castTag(.lazy_align).?.data;
- if (opt_sema) |sema| {
- try sema.resolveTypeLayout(ty);
- }
- const x = ty.abiAlignment(mod);
- return BigIntMutable.init(&space.limbs, x).toConst();
- },
- .lazy_size => {
- const ty = val.castTag(.lazy_size).?.data;
- if (opt_sema) |sema| {
- try sema.resolveTypeLayout(ty);
- }
- const x = ty.abiSize(mod);
- return BigIntMutable.init(&space.limbs, x).toConst();
- },
+ .lazy_align => {
+ const ty = val.castTag(.lazy_align).?.data;
+ if (opt_sema) |sema| {
+ try sema.resolveTypeLayout(ty);
+ }
+ const x = ty.abiAlignment(mod);
+ return BigIntMutable.init(&space.limbs, x).toConst();
+ },
+ .lazy_size => {
+ const ty = val.castTag(.lazy_size).?.data;
+ if (opt_sema) |sema| {
+ try sema.resolveTypeLayout(ty);
+ }
+ const x = ty.abiSize(mod);
+ return BigIntMutable.init(&space.limbs, x).toConst();
+ },
- .elem_ptr => {
- const elem_ptr = val.castTag(.elem_ptr).?.data;
- const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(mod, opt_sema)).?;
- const elem_size = elem_ptr.elem_ty.abiSize(mod);
- const new_addr = array_addr + elem_size * elem_ptr.index;
- return BigIntMutable.init(&space.limbs, new_addr).toConst();
- },
+ .elem_ptr => {
+ const elem_ptr = val.castTag(.elem_ptr).?.data;
+ const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(mod, opt_sema)).?;
+ const elem_size = elem_ptr.elem_ty.abiSize(mod);
+ const new_addr = array_addr + elem_size * elem_ptr.index;
+ return BigIntMutable.init(&space.limbs, new_addr).toConst();
+ },
- else => unreachable,
+ else => unreachable,
+ },
+ else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
+ .int => |int| return int.big_int,
+ else => unreachable,
+ },
}
}
@@ -1197,41 +918,46 @@ pub const Value = struct {
/// If the value fits in a u64, return it, otherwise null.
/// Asserts not undefined.
pub fn getUnsignedIntAdvanced(val: Value, mod: *const Module, opt_sema: ?*Sema) !?u64 {
- switch (val.tag()) {
- .zero,
- .bool_false,
- .the_only_possible_value, // i0, u0
- => return 0,
+ switch (val.ip_index) {
+ .bool_false => return 0,
+ .bool_true => return 1,
+ .none => switch (val.tag()) {
+ .zero,
+ .the_only_possible_value, // i0, u0
+ => return 0,
- .one,
- .bool_true,
- => return 1,
+ .one => return 1,
- .int_u64 => return val.castTag(.int_u64).?.data,
- .int_i64 => return @intCast(u64, val.castTag(.int_i64).?.data),
- .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null,
- .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
+ .int_u64 => return val.castTag(.int_u64).?.data,
+ .int_i64 => return @intCast(u64, val.castTag(.int_i64).?.data),
+ .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null,
+ .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
- .undef => unreachable,
+ .undef => unreachable,
- .lazy_align => {
- const ty = val.castTag(.lazy_align).?.data;
- if (opt_sema) |sema| {
- return (try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
- } else {
- return ty.abiAlignment(mod);
- }
+ .lazy_align => {
+ const ty = val.castTag(.lazy_align).?.data;
+ if (opt_sema) |sema| {
+ return (try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
+ } else {
+ return ty.abiAlignment(mod);
+ }
+ },
+ .lazy_size => {
+ const ty = val.castTag(.lazy_size).?.data;
+ if (opt_sema) |sema| {
+ return (try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
+ } else {
+ return ty.abiSize(mod);
+ }
+ },
+
+ else => return null,
},
- .lazy_size => {
- const ty = val.castTag(.lazy_size).?.data;
- if (opt_sema) |sema| {
- return (try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
- } else {
- return ty.abiSize(mod);
- }
+ else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
+ .int => |int| return int.big_int.to(u64) catch null,
+ else => unreachable,
},
-
- else => return null,
}
}
@@ -1242,51 +968,65 @@ pub const Value = struct {
/// Asserts the value is an integer and it fits in a i64
pub fn toSignedInt(val: Value, mod: *const Module) i64 {
- switch (val.tag()) {
- .zero,
- .bool_false,
- .the_only_possible_value, // i0, u0
- => return 0,
+ switch (val.ip_index) {
+ .bool_false => return 0,
+ .bool_true => return 1,
+ .none => switch (val.tag()) {
+ .zero,
+ .the_only_possible_value, // i0, u0
+ => return 0,
- .one,
- .bool_true,
- => return 1,
+ .one => return 1,
- .int_u64 => return @intCast(i64, val.castTag(.int_u64).?.data),
- .int_i64 => return val.castTag(.int_i64).?.data,
- .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
- .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
+ .int_u64 => return @intCast(i64, val.castTag(.int_u64).?.data),
+ .int_i64 => return val.castTag(.int_i64).?.data,
+ .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
+ .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
- .lazy_align => {
- const ty = val.castTag(.lazy_align).?.data;
- return @intCast(i64, ty.abiAlignment(mod));
+ .lazy_align => {
+ const ty = val.castTag(.lazy_align).?.data;
+ return @intCast(i64, ty.abiAlignment(mod));
+ },
+ .lazy_size => {
+ const ty = val.castTag(.lazy_size).?.data;
+ return @intCast(i64, ty.abiSize(mod));
+ },
+
+ .undef => unreachable,
+ else => unreachable,
},
- .lazy_size => {
- const ty = val.castTag(.lazy_size).?.data;
- return @intCast(i64, ty.abiSize(mod));
+ else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
+ .int => |int| return int.big_int.to(i64) catch unreachable,
+ else => unreachable,
},
-
- .undef => unreachable,
- else => unreachable,
}
}
- pub fn toBool(self: Value) bool {
- return switch (self.tag()) {
- .bool_true, .one => true,
- .bool_false, .zero => false,
- .int_u64 => switch (self.castTag(.int_u64).?.data) {
- 0 => false,
- 1 => true,
+ pub fn toBool(val: Value, mod: *const Module) bool {
+ switch (val.ip_index) {
+ .bool_true => return true,
+ .bool_false => return false,
+ .none => return switch (val.tag()) {
+ .one => true,
+ .zero => false,
+
+ .int_u64 => switch (val.castTag(.int_u64).?.data) {
+ 0 => false,
+ 1 => true,
+ else => unreachable,
+ },
+ .int_i64 => switch (val.castTag(.int_i64).?.data) {
+ 0 => false,
+ 1 => true,
+ else => unreachable,
+ },
else => unreachable,
},
- .int_i64 => switch (self.castTag(.int_i64).?.data) {
- 0 => false,
- 1 => true,
+ else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
+ .int => |int| return !int.big_int.eqZero(),
else => unreachable,
},
- else => unreachable,
- };
+ }
}
fn isDeclRef(val: Value) bool {
@@ -1319,7 +1059,7 @@ pub const Value = struct {
switch (ty.zigTypeTag(mod)) {
.Void => {},
.Bool => {
- buffer[0] = @boolToInt(val.toBool());
+ buffer[0] = @boolToInt(val.toBool(mod));
},
.Int, .Enum => {
const int_info = ty.intInfo(mod);
@@ -1442,7 +1182,7 @@ pub const Value = struct {
.Little => bit_offset / 8,
.Big => buffer.len - bit_offset / 8 - 1,
};
- if (val.toBool()) {
+ if (val.toBool(mod)) {
buffer[byte_index] |= (@as(u8, 1) << @intCast(u3, bit_offset % 8));
} else {
buffer[byte_index] &= ~(@as(u8, 1) << @intCast(u3, bit_offset % 8));
@@ -1802,90 +1542,117 @@ pub const Value = struct {
pub fn clz(val: Value, ty: Type, mod: *const Module) u64 {
const ty_bits = ty.intInfo(mod).bits;
- switch (val.tag()) {
- .zero, .bool_false => return ty_bits,
- .one, .bool_true => return ty_bits - 1,
+ switch (val.ip_index) {
+ .bool_false => return ty_bits,
+ .bool_true => return ty_bits - 1,
+ .none => switch (val.tag()) {
+ .zero => return ty_bits,
+ .one => return ty_bits - 1,
+
+ .int_u64 => {
+ const big = @clz(val.castTag(.int_u64).?.data);
+ return big + ty_bits - 64;
+ },
+ .int_i64 => {
+ @panic("TODO implement i64 Value clz");
+ },
+ .int_big_positive => {
+ const bigint = val.castTag(.int_big_positive).?.asBigInt();
+ return bigint.clz(ty_bits);
+ },
+ .int_big_negative => {
+ @panic("TODO implement int_big_negative Value clz");
+ },
- .int_u64 => {
- const big = @clz(val.castTag(.int_u64).?.data);
- return big + ty_bits - 64;
- },
- .int_i64 => {
- @panic("TODO implement i64 Value clz");
- },
- .int_big_positive => {
- const bigint = val.castTag(.int_big_positive).?.asBigInt();
- return bigint.clz(ty_bits);
- },
- .int_big_negative => {
- @panic("TODO implement int_big_negative Value clz");
- },
+ .the_only_possible_value => {
+ assert(ty_bits == 0);
+ return ty_bits;
+ },
- .the_only_possible_value => {
- assert(ty_bits == 0);
- return ty_bits;
- },
+ .lazy_align, .lazy_size => {
+ var bigint_buf: BigIntSpace = undefined;
+ const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
+ return bigint.clz(ty_bits);
+ },
- .lazy_align, .lazy_size => {
- var bigint_buf: BigIntSpace = undefined;
- const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
- return bigint.clz(ty_bits);
+ else => unreachable,
+ },
+ else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
+ .int => |int| return int.big_int.clz(ty_bits),
+ else => unreachable,
},
-
- else => unreachable,
}
}
pub fn ctz(val: Value, ty: Type, mod: *const Module) u64 {
const ty_bits = ty.intInfo(mod).bits;
- switch (val.tag()) {
- .zero, .bool_false => return ty_bits,
- .one, .bool_true => return 0,
+ switch (val.ip_index) {
+ .bool_false => return ty_bits,
+ .bool_true => return 0,
+ .none => switch (val.tag()) {
+ .zero => return ty_bits,
+ .one => return 0,
+
+ .int_u64 => {
+ const big = @ctz(val.castTag(.int_u64).?.data);
+ return if (big == 64) ty_bits else big;
+ },
+ .int_i64 => {
+ @panic("TODO implement i64 Value ctz");
+ },
+ .int_big_positive => {
+ const bigint = val.castTag(.int_big_positive).?.asBigInt();
+ return bigint.ctz();
+ },
+ .int_big_negative => {
+ @panic("TODO implement int_big_negative Value ctz");
+ },
- .int_u64 => {
- const big = @ctz(val.castTag(.int_u64).?.data);
- return if (big == 64) ty_bits else big;
- },
- .int_i64 => {
- @panic("TODO implement i64 Value ctz");
- },
- .int_big_positive => {
- const bigint = val.castTag(.int_big_positive).?.asBigInt();
- return bigint.ctz();
- },
- .int_big_negative => {
- @panic("TODO implement int_big_negative Value ctz");
- },
+ .the_only_possible_value => {
+ assert(ty_bits == 0);
+ return ty_bits;
+ },
- .the_only_possible_value => {
- assert(ty_bits == 0);
- return ty_bits;
- },
+ .lazy_align, .lazy_size => {
+ var bigint_buf: BigIntSpace = undefined;
+ const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
+ return bigint.ctz();
+ },
- .lazy_align, .lazy_size => {
- var bigint_buf: BigIntSpace = undefined;
- const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
- return bigint.ctz();
+ else => unreachable,
+ },
+ else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
+ .int => |int| return int.big_int.ctz(),
+ else => unreachable,
},
-
- else => unreachable,
}
}
pub fn popCount(val: Value, ty: Type, mod: *const Module) u64 {
assert(!val.isUndef());
- switch (val.tag()) {
- .zero, .bool_false => return 0,
- .one, .bool_true => return 1,
+ switch (val.ip_index) {
+ .bool_false => return 0,
+ .bool_true => return 1,
+ .none => switch (val.tag()) {
+ .zero => return 0,
+ .one => return 1,
- .int_u64 => return @popCount(val.castTag(.int_u64).?.data),
+ .int_u64 => return @popCount(val.castTag(.int_u64).?.data),
- else => {
- const info = ty.intInfo(mod);
+ else => {
+ const info = ty.intInfo(mod);
- var buffer: Value.BigIntSpace = undefined;
- const int = val.toBigInt(&buffer, mod);
- return @intCast(u64, int.popCount(info.bits));
+ var buffer: Value.BigIntSpace = undefined;
+ const int = val.toBigInt(&buffer, mod);
+ return @intCast(u64, int.popCount(info.bits));
+ },
+ },
+ else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
+ .int => |int| {
+ const info = ty.intInfo(mod);
+ return int.big_int.popCount(info.bits);
+ },
+ else => unreachable,
},
}
}
@@ -1933,37 +1700,42 @@ pub const Value = struct {
/// Returns the number of bits the value requires to represent stored in twos complement form.
pub fn intBitCountTwosComp(self: Value, mod: *const Module) usize {
const target = mod.getTarget();
- switch (self.tag()) {
- .zero,
- .bool_false,
- .the_only_possible_value,
- => return 0,
-
- .one,
- .bool_true,
- => return 1,
+ switch (self.ip_index) {
+ .bool_false => return 0,
+ .bool_true => return 1,
+ .none => switch (self.tag()) {
+ .zero,
+ .the_only_possible_value,
+ => return 0,
- .int_u64 => {
- const x = self.castTag(.int_u64).?.data;
- if (x == 0) return 0;
- return @intCast(usize, std.math.log2(x) + 1);
- },
- .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().bitCountTwosComp(),
- .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
+ .one => return 1,
- .decl_ref_mut,
- .comptime_field_ptr,
- .extern_fn,
- .decl_ref,
- .function,
- .variable,
- .eu_payload_ptr,
- .opt_payload_ptr,
- => return target.ptrBitWidth(),
+ .int_u64 => {
+ const x = self.castTag(.int_u64).?.data;
+ if (x == 0) return 0;
+ return @intCast(usize, std.math.log2(x) + 1);
+ },
+ .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().bitCountTwosComp(),
+ .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
+
+ .decl_ref_mut,
+ .comptime_field_ptr,
+ .extern_fn,
+ .decl_ref,
+ .function,
+ .variable,
+ .eu_payload_ptr,
+ .opt_payload_ptr,
+ => return target.ptrBitWidth(),
- else => {
- var buffer: BigIntSpace = undefined;
- return self.toBigInt(&buffer, mod).bitCountTwosComp();
+ else => {
+ var buffer: BigIntSpace = undefined;
+ return self.toBigInt(&buffer, mod).bitCountTwosComp();
+ },
+ },
+ else => switch (mod.intern_pool.indexToKey(self.ip_index)) {
+ .int => |int| return int.big_int.bitCountTwosComp(),
+ else => unreachable,
},
}
}
@@ -2008,82 +1780,88 @@ pub const Value = struct {
mod: *const Module,
opt_sema: ?*Sema,
) Module.CompileError!std.math.Order {
- return switch (lhs.tag()) {
- .zero,
- .bool_false,
- .the_only_possible_value,
- => .eq,
+ switch (lhs.ip_index) {
+ .bool_false => return .eq,
+ .bool_true => return .gt,
+ .none => return switch (lhs.tag()) {
+ .zero,
+ .the_only_possible_value,
+ => .eq,
- .one,
- .bool_true,
- .decl_ref,
- .decl_ref_mut,
- .comptime_field_ptr,
- .extern_fn,
- .function,
- .variable,
- => .gt,
+ .one,
+ .decl_ref,
+ .decl_ref_mut,
+ .comptime_field_ptr,
+ .extern_fn,
+ .function,
+ .variable,
+ => .gt,
+
+ .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0),
+ .runtime_value => {
+ // This is needed to correctly handle hashing the value.
+ // Checks in Sema should prevent direct comparisons from reaching here.
+ const val = lhs.castTag(.runtime_value).?.data;
+ return val.orderAgainstZeroAdvanced(mod, opt_sema);
+ },
+ .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),
+ .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),
+ .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
+ .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
+
+ .lazy_align => {
+ const ty = lhs.castTag(.lazy_align).?.data;
+ const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
+ if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
+ error.NeedLazy => unreachable,
+ else => |e| return e,
+ }) {
+ return .gt;
+ } else {
+ return .eq;
+ }
+ },
+ .lazy_size => {
+ const ty = lhs.castTag(.lazy_size).?.data;
+ const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
+ if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
+ error.NeedLazy => unreachable,
+ else => |e| return e,
+ }) {
+ return .gt;
+ } else {
+ return .eq;
+ }
+ },
- .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0),
- .runtime_value => {
- // This is needed to correctly handle hashing the value.
- // Checks in Sema should prevent direct comparisons from reaching here.
- const val = lhs.castTag(.runtime_value).?.data;
- return val.orderAgainstZeroAdvanced(mod, opt_sema);
- },
- .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),
- .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),
- .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
- .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
+ .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
+ .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
+ .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
+ .float_80 => std.math.order(lhs.castTag(.float_80).?.data, 0),
+ .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0),
+
+ .elem_ptr => {
+ const elem_ptr = lhs.castTag(.elem_ptr).?.data;
+ switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) {
+ .lt => unreachable,
+ .gt => return .gt,
+ .eq => {
+ if (elem_ptr.index == 0) {
+ return .eq;
+ } else {
+ return .gt;
+ }
+ },
+ }
+ },
- .lazy_align => {
- const ty = lhs.castTag(.lazy_align).?.data;
- const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
- if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
- error.NeedLazy => unreachable,
- else => |e| return e,
- }) {
- return .gt;
- } else {
- return .eq;
- }
- },
- .lazy_size => {
- const ty = lhs.castTag(.lazy_size).?.data;
- const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
- if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
- error.NeedLazy => unreachable,
- else => |e| return e,
- }) {
- return .gt;
- } else {
- return .eq;
- }
+ else => unreachable,
},
-
- .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
- .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
- .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
- .float_80 => std.math.order(lhs.castTag(.float_80).?.data, 0),
- .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0),
-
- .elem_ptr => {
- const elem_ptr = lhs.castTag(.elem_ptr).?.data;
- switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) {
- .lt => unreachable,
- .gt => return .gt,
- .eq => {
- if (elem_ptr.index == 0) {
- return .eq;
- } else {
- return .gt;
- }
- },
- }
+ else => switch (mod.intern_pool.indexToKey(lhs.ip_index)) {
+ .int => |int| return int.big_int.orderAgainstScalar(0),
+ else => unreachable,
},
-
- else => unreachable,
- };
+ }
}
/// Asserts the value is comparable.
@@ -2293,12 +2071,14 @@ pub const Value = struct {
mod: *Module,
opt_sema: ?*Sema,
) Module.CompileError!bool {
+ if (a.ip_index != .none or b.ip_index != .none) return a.ip_index == b.ip_index;
+
const target = mod.getTarget();
const a_tag = a.tag();
const b_tag = b.tag();
if (a_tag == b_tag) switch (a_tag) {
.undef => return true,
- .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,
+ .null_value, .the_only_possible_value, .empty_struct_value => return true,
.enum_literal => {
const a_name = a.castTag(.enum_literal).?.data;
const b_name = b.castTag(.enum_literal).?.data;
@@ -2574,6 +2354,13 @@ pub const Value = struct {
/// This function is used by hash maps and so treats floating-point NaNs as equal
/// to each other, and not equal to other floating-point values.
pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
+ if (val.ip_index != .none) {
+ // The InternPool data structure hashes based on Key to make interned objects
+ // unique. An Index can be treated simply as u32 value for the
+ // purpose of Type/Value hashing and equality.
+ std.hash.autoHash(hasher, val.ip_index);
+ return;
+ }
const zig_ty_tag = ty.zigTypeTag(mod);
std.hash.autoHash(hasher, zig_ty_tag);
if (val.isUndef()) return;
@@ -2908,8 +2695,6 @@ pub const Value = struct {
.int_i64,
.int_big_positive,
.int_big_negative,
- .bool_false,
- .bool_true,
.the_only_possible_value,
.lazy_align,
.lazy_size,
@@ -3051,15 +2836,6 @@ pub const Value = struct {
.opt_payload => return val.castTag(.opt_payload).?.data.elemValueAdvanced(mod, index, arena, buffer),
.eu_payload => return val.castTag(.eu_payload).?.data.elemValueAdvanced(mod, index, arena, buffer),
- // These values will implicitly be treated as `repeated`.
- .zero,
- .one,
- .bool_false,
- .bool_true,
- .int_i64,
- .int_u64,
- => return val,
-
else => unreachable,
}
}
@@ -3272,13 +3048,10 @@ pub const Value = struct {
// in which case the value 0 is null and other values are non-null.
.zero,
- .bool_false,
.the_only_possible_value,
=> true,
- .one,
- .bool_true,
- => false,
+ .one => false,
.int_u64,
.int_i64,
@@ -5419,11 +5192,7 @@ pub const Value = struct {
}
pub fn isGenericPoison(val: Value) bool {
- return switch (val.ip_index) {
- .generic_poison => true,
- .none => val.tag() == .generic_poison,
- else => false,
- };
+ return val.ip_index == .generic_poison;
}
/// This type is not copyable since it may contain pointers to its inner data.
@@ -5673,10 +5442,13 @@ pub const Value = struct {
.legacy = .{ .ptr_otherwise = &negative_one_payload.base },
};
pub const undef = initTag(.undef);
- pub const @"void" = initTag(.void_value);
+ pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };
pub const @"null" = initTag(.null_value);
- pub const @"false" = initTag(.bool_false);
- pub const @"true" = initTag(.bool_true);
+ pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined };
+ pub const @"true": Value = .{ .ip_index = .bool_true, .legacy = undefined };
+
+ pub const generic_poison: Value = .{ .ip_index = .generic_poison, .legacy = undefined };
+ pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined };
pub fn makeBool(x: bool) Value {
return if (x) Value.true else Value.false;
src/Zir.zig
@@ -2106,8 +2106,10 @@ pub const Inst = struct {
type_info_type = @enumToInt(InternPool.Index.type_info_type),
manyptr_u8_type = @enumToInt(InternPool.Index.manyptr_u8_type),
manyptr_const_u8_type = @enumToInt(InternPool.Index.manyptr_const_u8_type),
+ manyptr_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.manyptr_const_u8_sentinel_0_type),
single_const_pointer_to_comptime_int_type = @enumToInt(InternPool.Index.single_const_pointer_to_comptime_int_type),
const_slice_u8_type = @enumToInt(InternPool.Index.const_slice_u8_type),
+ const_slice_u8_sentinel_0_type = @enumToInt(InternPool.Index.const_slice_u8_sentinel_0_type),
anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
var_args_param_type = @enumToInt(InternPool.Index.var_args_param_type),
@@ -2115,6 +2117,7 @@ pub const Inst = struct {
undef = @enumToInt(InternPool.Index.undef),
zero = @enumToInt(InternPool.Index.zero),
zero_usize = @enumToInt(InternPool.Index.zero_usize),
+ zero_u8 = @enumToInt(InternPool.Index.zero_u8),
one = @enumToInt(InternPool.Index.one),
one_usize = @enumToInt(InternPool.Index.one_usize),
calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),