authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-03 19:12:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:40:04-07:00
logca3cf93b21bc77535fbaa7ca6aa411654dcfe069
tree2bec1cb13da757280595ef217556c1eeddf77414
parent836d8a1f64cb811641e621799429c54f222717eb

stage2: move most simple values to InternPool


12 files changed, 521 insertions(+), 743 deletions(-)

src/Air.zig+3
......@@ -899,8 +899,10 @@ pub const Inst = struct {
899899 type_info_type = @enumToInt(InternPool.Index.type_info_type),
900900 manyptr_u8_type = @enumToInt(InternPool.Index.manyptr_u8_type),
901901 manyptr_const_u8_type = @enumToInt(InternPool.Index.manyptr_const_u8_type),
902 manyptr_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.manyptr_const_u8_sentinel_0_type),
902903 single_const_pointer_to_comptime_int_type = @enumToInt(InternPool.Index.single_const_pointer_to_comptime_int_type),
903904 const_slice_u8_type = @enumToInt(InternPool.Index.const_slice_u8_type),
905 const_slice_u8_sentinel_0_type = @enumToInt(InternPool.Index.const_slice_u8_sentinel_0_type),
904906 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
905907 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
906908 var_args_param_type = @enumToInt(InternPool.Index.var_args_param_type),
......@@ -908,6 +910,7 @@ pub const Inst = struct {
908910 undef = @enumToInt(InternPool.Index.undef),
909911 zero = @enumToInt(InternPool.Index.zero),
910912 zero_usize = @enumToInt(InternPool.Index.zero_usize),
913 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
911914 one = @enumToInt(InternPool.Index.one),
912915 one_usize = @enumToInt(InternPool.Index.one_usize),
913916 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
src/InternPool.zig+31
......@@ -318,8 +318,10 @@ pub const Index = enum(u32) {
318318 type_info_type,
319319 manyptr_u8_type,
320320 manyptr_const_u8_type,
321 manyptr_const_u8_sentinel_0_type,
321322 single_const_pointer_to_comptime_int_type,
322323 const_slice_u8_type,
324 const_slice_u8_sentinel_0_type,
323325 anyerror_void_error_union_type,
324326 generic_poison_type,
325327 var_args_param_type,
......@@ -331,6 +333,8 @@ pub const Index = enum(u32) {
331333 zero,
332334 /// `0` (usize)
333335 zero_usize,
336 /// `0` (u8)
337 zero_u8,
334338 /// `1` (comptime_int)
335339 one,
336340 /// `1` (usize)
......@@ -489,24 +493,43 @@ pub const static_keys = [_]Key{
489493 .size = .Many,
490494 } },
491495
496 // manyptr_const_u8_type
492497 .{ .ptr_type = .{
493498 .elem_type = .u8_type,
494499 .size = .Many,
495500 .is_const = true,
496501 } },
497502
503 // manyptr_const_u8_sentinel_0_type
504 .{ .ptr_type = .{
505 .elem_type = .u8_type,
506 .sentinel = .zero_u8,
507 .size = .Many,
508 .is_const = true,
509 } },
510
498511 .{ .ptr_type = .{
499512 .elem_type = .comptime_int_type,
500513 .size = .One,
501514 .is_const = true,
502515 } },
503516
517 // const_slice_u8_type
504518 .{ .ptr_type = .{
505519 .elem_type = .u8_type,
506520 .size = .Slice,
507521 .is_const = true,
508522 } },
509523
524 // const_slice_u8_sentinel_0_type
525 .{ .ptr_type = .{
526 .elem_type = .u8_type,
527 .sentinel = .zero_u8,
528 .size = .Slice,
529 .is_const = true,
530 } },
531
532 // anyerror_void_error_union_type
510533 .{ .error_union_type = .{
511534 .error_set_type = .anyerror_type,
512535 .payload_type = .void_type,
......@@ -541,6 +564,14 @@ pub const static_keys = [_]Key{
541564 },
542565 } },
543566
567 .{ .int = .{
568 .ty = .u8_type,
569 .big_int = .{
570 .limbs = &.{0},
571 .positive = true,
572 },
573 } },
574
544575 .{ .int = .{
545576 .ty = .comptime_int_type,
546577 .big_int = .{
src/Module.zig+28-22
......@@ -4847,31 +4847,37 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
48474847 decl.owns_tv = false;
48484848 var queue_linker_work = false;
48494849 var is_extern = false;
4850 switch (decl_tv.val.tag()) {
4851 .variable => {
4852 const variable = decl_tv.val.castTag(.variable).?.data;
4853 if (variable.owner_decl == decl_index) {
4854 decl.owns_tv = true;
4855 queue_linker_work = true;
4856
4857 const copied_init = try variable.init.copy(decl_arena_allocator);
4858 variable.init = copied_init;
4859 }
4860 },
4861 .extern_fn => {
4862 const extern_fn = decl_tv.val.castTag(.extern_fn).?.data;
4863 if (extern_fn.owner_decl == decl_index) {
4864 decl.owns_tv = true;
4865 queue_linker_work = true;
4866 is_extern = true;
4867 }
4868 },
4869
4850 switch (decl_tv.val.ip_index) {
48704851 .generic_poison => unreachable,
4871 .unreachable_value => unreachable,
4852 .none => switch (decl_tv.val.tag()) {
4853 .variable => {
4854 const variable = decl_tv.val.castTag(.variable).?.data;
4855 if (variable.owner_decl == decl_index) {
4856 decl.owns_tv = true;
4857 queue_linker_work = true;
4858
4859 const copied_init = try variable.init.copy(decl_arena_allocator);
4860 variable.init = copied_init;
4861 }
4862 },
4863 .extern_fn => {
4864 const extern_fn = decl_tv.val.castTag(.extern_fn).?.data;
4865 if (extern_fn.owner_decl == decl_index) {
4866 decl.owns_tv = true;
4867 queue_linker_work = true;
4868 is_extern = true;
4869 }
4870 },
4871
4872 .unreachable_value => unreachable,
48724873
4873 .function => {},
4874 .function => {},
48744875
4876 else => {
4877 log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name });
4878 queue_linker_work = true;
4879 },
4880 },
48754881 else => {
48764882 log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name });
48774883 queue_linker_work = true;
src/Sema.zig+77-57
......@@ -1569,6 +1569,7 @@ fn analyzeBodyInner(
15691569 },
15701570 .condbr => blk: {
15711571 if (!block.is_comptime) break sema.zirCondbr(block, inst);
1572 const mod = sema.mod;
15721573 // Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220
15731574 const inst_data = datas[inst].pl_node;
15741575 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
......@@ -1579,7 +1580,7 @@ fn analyzeBodyInner(
15791580 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
15801581 return err;
15811582 };
1582 const inline_body = if (cond.val.toBool()) then_body else else_body;
1583 const inline_body = if (cond.val.toBool(mod)) then_body else else_body;
15831584
15841585 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
15851586 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
......@@ -1591,6 +1592,7 @@ fn analyzeBodyInner(
15911592 }
15921593 },
15931594 .condbr_inline => blk: {
1595 const mod = sema.mod;
15941596 const inst_data = datas[inst].pl_node;
15951597 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
15961598 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
......@@ -1600,7 +1602,7 @@ fn analyzeBodyInner(
16001602 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
16011603 return err;
16021604 };
1603 const inline_body = if (cond.val.toBool()) then_body else else_body;
1605 const inline_body = if (cond.val.toBool(mod)) then_body else else_body;
16041606
16051607 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
16061608 const old_runtime_index = block.runtime_index;
......@@ -1634,7 +1636,7 @@ fn analyzeBodyInner(
16341636 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
16351637 return err;
16361638 };
1637 if (is_non_err_val.toBool()) {
1639 if (is_non_err_val.toBool(mod)) {
16381640 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);
16391641 }
16401642 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
......@@ -1647,6 +1649,7 @@ fn analyzeBodyInner(
16471649 },
16481650 .try_ptr => blk: {
16491651 if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst);
1652 const mod = sema.mod;
16501653 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
16511654 const src = inst_data.src();
16521655 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
......@@ -1660,7 +1663,7 @@ fn analyzeBodyInner(
16601663 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
16611664 return err;
16621665 };
1663 if (is_non_err_val.toBool()) {
1666 if (is_non_err_val.toBool(mod)) {
16641667 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
16651668 }
16661669 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
......@@ -1741,11 +1744,12 @@ fn resolveConstBool(
17411744 zir_ref: Zir.Inst.Ref,
17421745 reason: []const u8,
17431746) !bool {
1747 const mod = sema.mod;
17441748 const air_inst = try sema.resolveInst(zir_ref);
17451749 const wanted_type = Type.bool;
17461750 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
17471751 const val = try sema.resolveConstValue(block, src, coerced_inst, reason);
1748 return val.toBool();
1752 return val.toBool(mod);
17491753}
17501754
17511755pub fn resolveConstString(
......@@ -1843,9 +1847,12 @@ fn resolveConstMaybeUndefVal(
18431847 reason: []const u8,
18441848) CompileError!Value {
18451849 if (try sema.resolveMaybeUndefValAllowVariables(inst)) |val| {
1846 switch (val.tag()) {
1847 .variable => return sema.failWithNeededComptime(block, src, reason),
1850 switch (val.ip_index) {
18481851 .generic_poison => return error.GenericPoison,
1852 .none => switch (val.tag()) {
1853 .variable => return sema.failWithNeededComptime(block, src, reason),
1854 else => return val,
1855 },
18491856 else => return val,
18501857 }
18511858 }
......@@ -1862,10 +1869,13 @@ fn resolveConstValue(
18621869 reason: []const u8,
18631870) CompileError!Value {
18641871 if (try sema.resolveMaybeUndefValAllowVariables(air_ref)) |val| {
1865 switch (val.tag()) {
1866 .undef => return sema.failWithUseOfUndef(block, src),
1867 .variable => return sema.failWithNeededComptime(block, src, reason),
1872 switch (val.ip_index) {
18681873 .generic_poison => return error.GenericPoison,
1874 .none => switch (val.tag()) {
1875 .undef => return sema.failWithUseOfUndef(block, src),
1876 .variable => return sema.failWithNeededComptime(block, src, reason),
1877 else => return val,
1878 },
18691879 else => return val,
18701880 }
18711881 }
......@@ -1900,12 +1910,11 @@ fn resolveMaybeUndefVal(
19001910 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
19011911 switch (val.ip_index) {
19021912 .generic_poison => return error.GenericPoison,
1903 else => return val,
19041913 .none => switch (val.tag()) {
19051914 .variable => return null,
1906 .generic_poison => return error.GenericPoison,
19071915 else => return val,
19081916 },
1917 else => return val,
19091918 }
19101919}
19111920
......@@ -1919,12 +1928,18 @@ fn resolveMaybeUndefValIntable(
19191928) CompileError!?Value {
19201929 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
19211930 var check = val;
1922 while (true) switch (check.tag()) {
1923 .variable, .decl_ref, .decl_ref_mut, .comptime_field_ptr => return null,
1924 .field_ptr => check = check.castTag(.field_ptr).?.data.container_ptr,
1925 .elem_ptr => check = check.castTag(.elem_ptr).?.data.array_ptr,
1926 .eu_payload_ptr, .opt_payload_ptr => check = check.cast(Value.Payload.PayloadPtr).?.data.container_ptr,
1931 while (true) switch (check.ip_index) {
19271932 .generic_poison => return error.GenericPoison,
1933 .none => switch (check.tag()) {
1934 .variable, .decl_ref, .decl_ref_mut, .comptime_field_ptr => return null,
1935 .field_ptr => check = check.castTag(.field_ptr).?.data.container_ptr,
1936 .elem_ptr => check = check.castTag(.elem_ptr).?.data.array_ptr,
1937 .eu_payload_ptr, .opt_payload_ptr => check = check.cast(Value.Payload.PayloadPtr).?.data.container_ptr,
1938 else => {
1939 try sema.resolveLazyValue(val);
1940 return val;
1941 },
1942 },
19281943 else => {
19291944 try sema.resolveLazyValue(val);
19301945 return val;
......@@ -6208,12 +6223,13 @@ fn popErrorReturnTrace(
62086223 operand: Air.Inst.Ref,
62096224 saved_error_trace_index: Air.Inst.Ref,
62106225) CompileError!void {
6226 const mod = sema.mod;
62116227 var is_non_error: ?bool = null;
62126228 var is_non_error_inst: Air.Inst.Ref = undefined;
62136229 if (operand != .none) {
62146230 is_non_error_inst = try sema.analyzeIsNonErr(block, src, operand);
62156231 if (try sema.resolveDefinedValue(block, src, is_non_error_inst)) |cond_val|
6216 is_non_error = cond_val.toBool();
6232 is_non_error = cond_val.toBool(mod);
62176233 } else is_non_error = true; // no operand means pop unconditionally
62186234
62196235 if (is_non_error == true) {
......@@ -7222,7 +7238,7 @@ fn analyzeInlineCallArg(
72227238 if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err);
72237239 return err;
72247240 };
7225 switch (arg_val.tag()) {
7241 switch (arg_val.ip_index) {
72267242 .generic_poison, .generic_poison_type => {
72277243 // This function is currently evaluated as part of an as-of-yet unresolvable
72287244 // parameter or return type.
......@@ -7261,7 +7277,7 @@ fn analyzeInlineCallArg(
72617277 if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err);
72627278 return err;
72637279 };
7264 switch (arg_val.tag()) {
7280 switch (arg_val.ip_index) {
72657281 .generic_poison, .generic_poison_type => {
72667282 // This function is currently evaluated as part of an as-of-yet unresolvable
72677283 // parameter or return type.
......@@ -7443,13 +7459,13 @@ fn instantiateGenericCall(
74437459 arg_ty.hashWithHasher(&hasher, mod);
74447460 generic_args[i] = .{
74457461 .ty = arg_ty,
7446 .val = Value.initTag(.generic_poison),
7462 .val = Value.generic_poison,
74477463 .is_anytype = true,
74487464 };
74497465 } else {
74507466 generic_args[i] = .{
74517467 .ty = arg_ty,
7452 .val = Value.initTag(.generic_poison),
7468 .val = Value.generic_poison,
74537469 .is_anytype = false,
74547470 };
74557471 }
......@@ -7815,7 +7831,7 @@ fn resolveGenericInstantiationType(
78157831 } else {
78167832 child_sema.comptime_args[arg_i] = .{
78177833 .ty = copied_arg_ty,
7818 .val = Value.initTag(.generic_poison),
7834 .val = Value.generic_poison,
78197835 };
78207836 }
78217837
......@@ -8780,9 +8796,9 @@ fn resolveGenericBody(
87808796 switch (err) {
87818797 error.GenericPoison => {
87828798 if (dest_ty.ip_index == .type_type) {
8783 return Value.initTag(.generic_poison_type);
8799 return Value.generic_poison_type;
87848800 } else {
8785 return Value.initTag(.generic_poison);
8801 return Value.generic_poison;
87868802 }
87878803 },
87888804 else => |e| return e,
......@@ -9394,7 +9410,7 @@ fn zirParam(
93949410 if (is_comptime) {
93959411 // If this is a comptime parameter we can add a constant generic_poison
93969412 // since this is also a generic parameter.
9397 const result = try sema.addConstant(param_ty, Value.initTag(.generic_poison));
9413 const result = try sema.addConstant(param_ty, Value.generic_poison);
93989414 sema.inst_map.putAssumeCapacityNoClobber(inst, result);
93999415 } else {
94009416 // Otherwise we need a dummy runtime instruction.
......@@ -11819,8 +11835,9 @@ fn validateSwitchItemBool(
1181911835 src_node_offset: i32,
1182011836 switch_prong_src: Module.SwitchProngSrc,
1182111837) CompileError!void {
11838 const mod = sema.mod;
1182211839 const item_val = (try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none)).val;
11823 if (item_val.toBool()) {
11840 if (item_val.toBool(mod)) {
1182411841 true_count.* += 1;
1182511842 } else {
1182611843 false_count.* += 1;
......@@ -15462,7 +15479,7 @@ fn cmpSelf(
1546215479 } else {
1546315480 if (resolved_type.zigTypeTag(mod) == .Bool) {
1546415481 // We can lower bool eq/neq more efficiently.
15465 return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src);
15482 return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(mod), rhs_src);
1546615483 }
1546715484 break :src rhs_src;
1546815485 }
......@@ -15472,7 +15489,7 @@ fn cmpSelf(
1547215489 if (resolved_type.zigTypeTag(mod) == .Bool) {
1547315490 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
1547415491 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
15475 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);
15492 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(mod), lhs_src);
1547615493 }
1547715494 }
1547815495 break :src lhs_src;
......@@ -16815,6 +16832,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1681516832 const tracy = trace(@src());
1681616833 defer tracy.end();
1681716834
16835 const mod = sema.mod;
1681816836 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1681916837 const src = inst_data.src();
1682016838 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
1682416842 if (try sema.resolveMaybeUndefVal(operand)) |val| {
1682516843 return if (val.isUndef())
1682616844 sema.addConstUndef(Type.bool)
16827 else if (val.toBool())
16845 else if (val.toBool(mod))
1682816846 Air.Inst.Ref.bool_false
1682916847 else
1683016848 Air.Inst.Ref.bool_true;
......@@ -16842,6 +16860,7 @@ fn zirBoolBr(
1684216860 const tracy = trace(@src());
1684316861 defer tracy.end();
1684416862
16863 const mod = sema.mod;
1684516864 const datas = sema.code.instructions.items(.data);
1684616865 const inst_data = datas[inst].bool_br;
1684716866 const lhs = try sema.resolveInst(inst_data.lhs);
......@@ -16851,9 +16870,9 @@ fn zirBoolBr(
1685116870 const gpa = sema.gpa;
1685216871
1685316872 if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| {
16854 if (is_bool_or and lhs_val.toBool()) {
16873 if (is_bool_or and lhs_val.toBool(mod)) {
1685516874 return Air.Inst.Ref.bool_true;
16856 } else if (!is_bool_or and !lhs_val.toBool()) {
16875 } else if (!is_bool_or and !lhs_val.toBool(mod)) {
1685716876 return Air.Inst.Ref.bool_false;
1685816877 }
1685916878 // comptime-known left-hand side. No need for a block here; the result
......@@ -16897,9 +16916,9 @@ fn zirBoolBr(
1689716916 const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst);
1689816917 if (!sema.typeOf(rhs_result).isNoReturn()) {
1689916918 if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| {
16900 if (is_bool_or and rhs_val.toBool()) {
16919 if (is_bool_or and rhs_val.toBool(mod)) {
1690116920 return Air.Inst.Ref.bool_true;
16902 } else if (!is_bool_or and !rhs_val.toBool()) {
16921 } else if (!is_bool_or and !rhs_val.toBool(mod)) {
1690316922 return Air.Inst.Ref.bool_false;
1690416923 }
1690516924 }
......@@ -17053,7 +17072,7 @@ fn zirCondbr(
1705317072 const cond = try sema.coerce(parent_block, Type.bool, uncasted_cond, cond_src);
1705417073
1705517074 if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| {
17056 const body = if (cond_val.toBool()) then_body else else_body;
17075 const body = if (cond_val.toBool(mod)) then_body else else_body;
1705717076
1705817077 try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src);
1705917078 // 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!
1712617145 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
1712717146 if (is_non_err != .none) {
1712817147 const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?;
17129 if (is_non_err_val.toBool()) {
17148 if (is_non_err_val.toBool(mod)) {
1713017149 return sema.analyzeErrUnionPayload(parent_block, src, err_union_ty, err_union, operand_src, false);
1713117150 }
1713217151 // 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
1717317192 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
1717417193 if (is_non_err != .none) {
1717517194 const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?;
17176 if (is_non_err_val.toBool()) {
17195 if (is_non_err_val.toBool(mod)) {
1717717196 return sema.analyzeErrUnionPayloadPtr(parent_block, src, operand, false, false);
1717817197 }
1717917198 // 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
1850918528}
1851018529
1851118530fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18531 const mod = sema.mod;
1851218532 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1851318533 const operand = try sema.resolveInst(inst_data.operand);
1851418534 if (try sema.resolveMaybeUndefVal(operand)) |val| {
1851518535 if (val.isUndef()) return sema.addConstUndef(Type.u1);
18516 if (val.toBool()) return sema.addConstant(Type.u1, Value.one);
18536 if (val.toBool(mod)) return sema.addConstant(Type.u1, Value.one);
1851718537 return sema.addConstant(Type.u1, Value.zero);
1851818538 }
1851918539 return block.addUnOp(.bool_to_int, operand);
......@@ -18811,12 +18831,12 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1881118831
1881218832 const ty = try Type.ptr(sema.arena, mod, .{
1881318833 .size = ptr_size,
18814 .mutable = !is_const_val.toBool(),
18815 .@"volatile" = is_volatile_val.toBool(),
18834 .mutable = !is_const_val.toBool(mod),
18835 .@"volatile" = is_volatile_val.toBool(mod),
1881618836 .@"align" = abi_align,
1881718837 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
1881818838 .pointee_type = try elem_ty.copy(sema.arena),
18819 .@"allowzero" = is_allowzero_val.toBool(),
18839 .@"allowzero" = is_allowzero_val.toBool(mod),
1882018840 .sentinel = actual_sentinel,
1882118841 });
1882218842 return sema.addType(ty);
......@@ -18932,7 +18952,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1893218952 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
1893318953 }
1893418954
18935 return try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy, is_tuple_val.toBool());
18955 return try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
1893618956 },
1893718957 .Enum => {
1893818958 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
1896118981 const enum_ty_payload = try new_decl_arena_allocator.create(Type.Payload.EnumFull);
1896218982 enum_ty_payload.* = .{
1896318983 .base = .{
18964 .tag = if (!is_exhaustive_val.toBool())
18984 .tag = if (!is_exhaustive_val.toBool(mod))
1896518985 .enum_nonexhaustive
1896618986 else
1896718987 .enum_full,
......@@ -19295,9 +19315,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1929519315 // alignment: comptime_int,
1929619316 const alignment_val = struct_val[1];
1929719317 // is_generic: bool,
19298 const is_generic = struct_val[2].toBool();
19318 const is_generic = struct_val[2].toBool(mod);
1929919319 // is_var_args: bool,
19300 const is_var_args = struct_val[3].toBool();
19320 const is_var_args = struct_val[3].toBool(mod);
1930119321 // return_type: ?type,
1930219322 const return_type_val = struct_val[4];
1930319323 // args: []const Param,
......@@ -19339,9 +19359,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1933919359 const arg_val = arg.castTag(.aggregate).?.data;
1934019360 // TODO use reflection instead of magic numbers here
1934119361 // is_generic: bool,
19342 const arg_is_generic = arg_val[0].toBool();
19362 const arg_is_generic = arg_val[0].toBool(mod);
1934319363 // is_noalias: bool,
19344 const arg_is_noalias = arg_val[1].toBool();
19364 const arg_is_noalias = arg_val[1].toBool(mod);
1934519365 // type: ?type,
1934619366 const param_type_opt_val = arg_val[2];
1934719367
......@@ -19455,9 +19475,9 @@ fn reifyStruct(
1945519475
1945619476 if (layout == .Packed) {
1945719477 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
19458 if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});
19478 if (is_comptime_val.toBool(mod)) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});
1945919479 }
19460 if (layout == .Extern and is_comptime_val.toBool()) {
19480 if (layout == .Extern and is_comptime_val.toBool(mod)) {
1946119481 return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});
1946219482 }
1946319483
......@@ -19499,7 +19519,7 @@ fn reifyStruct(
1949919519 opt_val;
1950019520 break :blk try payload_val.copy(new_decl_arena_allocator);
1950119521 } else Value.initTag(.unreachable_value);
19502 if (is_comptime_val.toBool() and default_val.tag() == .unreachable_value) {
19522 if (is_comptime_val.toBool(mod) and default_val.tag() == .unreachable_value) {
1950319523 return sema.fail(block, src, "comptime field without default initialization value", .{});
1950419524 }
1950519525
......@@ -19508,7 +19528,7 @@ fn reifyStruct(
1950819528 .ty = field_ty,
1950919529 .abi_align = abi_align,
1951019530 .default_val = default_val,
19511 .is_comptime = is_comptime_val.toBool(),
19531 .is_comptime = is_comptime_val.toBool(mod),
1951219532 .offset = undefined,
1951319533 };
1951419534
......@@ -21446,7 +21466,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2144621466 const elems = try sema.gpa.alloc(Value, vec_len);
2144721467 for (elems, 0..) |*elem, i| {
2144821468 const pred_elem_val = pred_val.elemValueBuffer(sema.mod, i, &buf);
21449 const should_choose_a = pred_elem_val.toBool();
21469 const should_choose_a = pred_elem_val.toBool(mod);
2145021470 if (should_choose_a) {
2145121471 elem.* = a_val.elemValueBuffer(sema.mod, i, &buf);
2145221472 } else {
......@@ -22956,7 +22976,7 @@ fn resolveExternOptions(
2295622976 .name = name,
2295722977 .library_name = library_name,
2295822978 .linkage = linkage,
22959 .is_thread_local = is_thread_local_val.toBool(),
22979 .is_thread_local = is_thread_local_val.toBool(mod),
2296022980 };
2296122981}
2296222982
......@@ -31760,8 +31780,10 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3176031780 .enum_literal_type,
3176131781 .manyptr_u8_type,
3176231782 .manyptr_const_u8_type,
31783 .manyptr_const_u8_sentinel_0_type,
3176331784 .single_const_pointer_to_comptime_int_type,
3176431785 .const_slice_u8_type,
31786 .const_slice_u8_sentinel_0_type,
3176531787 .anyerror_void_error_union_type,
3176631788 .generic_poison_type,
3176731789 .var_args_param_type,
......@@ -31771,6 +31793,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3177131793 .undef => unreachable,
3177231794 .zero => unreachable,
3177331795 .zero_usize => unreachable,
31796 .zero_u8 => unreachable,
3177431797 .one => unreachable,
3177531798 .one_usize => unreachable,
3177631799 .calling_convention_c => unreachable,
......@@ -34225,12 +34248,9 @@ fn intFitsInType(
3422534248 switch (val.tag()) {
3422634249 .zero,
3422734250 .undef,
34228 .bool_false,
3422934251 => return true,
3423034252
34231 .one,
34232 .bool_true,
34233 => switch (ty.zigTypeTag(mod)) {
34253 .one => switch (ty.zigTypeTag(mod)) {
3423434254 .Int => {
3423534255 const info = ty.intInfo(mod);
3423634256 return switch (info.signedness) {
src/TypedValue.zig-57
......@@ -77,66 +77,14 @@ pub fn print(
7777 return writer.writeAll("(variable)");
7878
7979 while (true) switch (val.tag()) {
80 .u1_type => return writer.writeAll("u1"),
81 .u8_type => return writer.writeAll("u8"),
82 .i8_type => return writer.writeAll("i8"),
83 .u16_type => return writer.writeAll("u16"),
84 .i16_type => return writer.writeAll("i16"),
85 .u29_type => return writer.writeAll("u29"),
86 .u32_type => return writer.writeAll("u32"),
87 .i32_type => return writer.writeAll("i32"),
88 .u64_type => return writer.writeAll("u64"),
89 .i64_type => return writer.writeAll("i64"),
90 .u128_type => return writer.writeAll("u128"),
91 .i128_type => return writer.writeAll("i128"),
92 .isize_type => return writer.writeAll("isize"),
93 .usize_type => return writer.writeAll("usize"),
94 .c_char_type => return writer.writeAll("c_char"),
95 .c_short_type => return writer.writeAll("c_short"),
96 .c_ushort_type => return writer.writeAll("c_ushort"),
97 .c_int_type => return writer.writeAll("c_int"),
98 .c_uint_type => return writer.writeAll("c_uint"),
99 .c_long_type => return writer.writeAll("c_long"),
100 .c_ulong_type => return writer.writeAll("c_ulong"),
101 .c_longlong_type => return writer.writeAll("c_longlong"),
102 .c_ulonglong_type => return writer.writeAll("c_ulonglong"),
103 .c_longdouble_type => return writer.writeAll("c_longdouble"),
104 .f16_type => return writer.writeAll("f16"),
105 .f32_type => return writer.writeAll("f32"),
106 .f64_type => return writer.writeAll("f64"),
107 .f80_type => return writer.writeAll("f80"),
108 .f128_type => return writer.writeAll("f128"),
109 .anyopaque_type => return writer.writeAll("anyopaque"),
110 .bool_type => return writer.writeAll("bool"),
111 .void_type => return writer.writeAll("void"),
112 .type_type => return writer.writeAll("type"),
113 .anyerror_type => return writer.writeAll("anyerror"),
114 .comptime_int_type => return writer.writeAll("comptime_int"),
115 .comptime_float_type => return writer.writeAll("comptime_float"),
116 .noreturn_type => return writer.writeAll("noreturn"),
117 .null_type => return writer.writeAll("@Type(.Null)"),
118 .undefined_type => return writer.writeAll("@Type(.Undefined)"),
11980 .single_const_pointer_to_comptime_int_type => return writer.writeAll("*const comptime_int"),
120 .anyframe_type => return writer.writeAll("anyframe"),
12181 .const_slice_u8_type => return writer.writeAll("[]const u8"),
12282 .const_slice_u8_sentinel_0_type => return writer.writeAll("[:0]const u8"),
12383 .anyerror_void_error_union_type => return writer.writeAll("anyerror!void"),
12484
125 .enum_literal_type => return writer.writeAll("@Type(.EnumLiteral)"),
12685 .manyptr_u8_type => return writer.writeAll("[*]u8"),
12786 .manyptr_const_u8_type => return writer.writeAll("[*]const u8"),
12887 .manyptr_const_u8_sentinel_0_type => return writer.writeAll("[*:0]const u8"),
129 .atomic_order_type => return writer.writeAll("std.builtin.AtomicOrder"),
130 .atomic_rmw_op_type => return writer.writeAll("std.builtin.AtomicRmwOp"),
131 .calling_convention_type => return writer.writeAll("std.builtin.CallingConvention"),
132 .address_space_type => return writer.writeAll("std.builtin.AddressSpace"),
133 .float_mode_type => return writer.writeAll("std.builtin.FloatMode"),
134 .reduce_op_type => return writer.writeAll("std.builtin.ReduceOp"),
135 .modifier_type => return writer.writeAll("std.builtin.CallModifier"),
136 .prefetch_options_type => return writer.writeAll("std.builtin.PrefetchOptions"),
137 .export_options_type => return writer.writeAll("std.builtin.ExportOptions"),
138 .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"),
139 .type_info_type => return writer.writeAll("std.builtin.Type"),
14088
14189 .empty_struct_value, .aggregate => {
14290 if (level == 0) {
......@@ -221,11 +169,8 @@ pub fn print(
221169 .undef => return writer.writeAll("undefined"),
222170 .zero => return writer.writeAll("0"),
223171 .one => return writer.writeAll("1"),
224 .void_value => return writer.writeAll("{}"),
225172 .unreachable_value => return writer.writeAll("unreachable"),
226173 .the_only_possible_value => return writer.writeAll("0"),
227 .bool_true => return writer.writeAll("true"),
228 .bool_false => return writer.writeAll("false"),
229174 .ty => return val.castTag(.ty).?.data.print(writer, mod),
230175 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
231176 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
......@@ -487,8 +432,6 @@ pub fn print(
487432 // TODO these should not appear in this function
488433 .inferred_alloc => return writer.writeAll("(inferred allocation value)"),
489434 .inferred_alloc_comptime => return writer.writeAll("(inferred comptime allocation value)"),
490 .generic_poison_type => return writer.writeAll("(generic poison type)"),
491 .generic_poison => return writer.writeAll("(generic poison)"),
492435 .runtime_value => return writer.writeAll("[runtime value]"),
493436 };
494437}
src/Zir.zig+3
......@@ -2106,8 +2106,10 @@ pub const Inst = struct {
21062106 type_info_type = @enumToInt(InternPool.Index.type_info_type),
21072107 manyptr_u8_type = @enumToInt(InternPool.Index.manyptr_u8_type),
21082108 manyptr_const_u8_type = @enumToInt(InternPool.Index.manyptr_const_u8_type),
2109 manyptr_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.manyptr_const_u8_sentinel_0_type),
21092110 single_const_pointer_to_comptime_int_type = @enumToInt(InternPool.Index.single_const_pointer_to_comptime_int_type),
21102111 const_slice_u8_type = @enumToInt(InternPool.Index.const_slice_u8_type),
2112 const_slice_u8_sentinel_0_type = @enumToInt(InternPool.Index.const_slice_u8_sentinel_0_type),
21112113 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
21122114 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
21132115 var_args_param_type = @enumToInt(InternPool.Index.var_args_param_type),
......@@ -2115,6 +2117,7 @@ pub const Inst = struct {
21152117 undef = @enumToInt(InternPool.Index.undef),
21162118 zero = @enumToInt(InternPool.Index.zero),
21172119 zero_usize = @enumToInt(InternPool.Index.zero_usize),
2120 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
21182121 one = @enumToInt(InternPool.Index.one),
21192122 one_usize = @enumToInt(InternPool.Index.one_usize),
21202123 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
src/codegen.zig+2-2
......@@ -494,7 +494,7 @@ pub fn generateSymbol(
494494 return Result.ok;
495495 },
496496 .Bool => {
497 const x: u8 = @boolToInt(typed_value.val.toBool());
497 const x: u8 = @boolToInt(typed_value.val.toBool(mod));
498498 try code.append(x);
499499 return Result.ok;
500500 },
......@@ -1213,7 +1213,7 @@ pub fn genTypedValue(
12131213 }
12141214 },
12151215 .Bool => {
1216 return GenResult.mcv(.{ .immediate = @boolToInt(typed_value.val.toBool()) });
1216 return GenResult.mcv(.{ .immediate = @boolToInt(typed_value.val.toBool(mod)) });
12171217 },
12181218 .Optional => {
12191219 if (typed_value.ty.isPtrLikeOptional(mod)) {
src/codegen/c.zig+1-1
......@@ -1191,7 +1191,7 @@ pub const DeclGen = struct {
11911191 }
11921192 },
11931193 .Bool => {
1194 if (val.toBool()) {
1194 if (val.toBool(mod)) {
11951195 return writer.writeAll("true");
11961196 } else {
11971197 return writer.writeAll("false");
src/codegen/llvm.zig+2-2
......@@ -2793,7 +2793,7 @@ pub const DeclGen = struct {
27932793 if (std.debug.runtime_safety and false) check: {
27942794 if (t.zigTypeTag(mod) == .Opaque) break :check;
27952795 if (!t.hasRuntimeBits(mod)) break :check;
2796 if (!llvm_ty.isSized().toBool()) break :check;
2796 if (!llvm_ty.isSized().toBool(mod)) break :check;
27972797
27982798 const zig_size = t.abiSize(mod);
27992799 const llvm_size = dg.object.target_data.abiSizeOfType(llvm_ty);
......@@ -3272,7 +3272,7 @@ pub const DeclGen = struct {
32723272 switch (tv.ty.zigTypeTag(mod)) {
32733273 .Bool => {
32743274 const llvm_type = try dg.lowerType(tv.ty);
3275 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
3275 return if (tv.val.toBool(mod)) llvm_type.constAllOnes() else llvm_type.constNull();
32763276 },
32773277 // TODO this duplicates code with Pointer but they should share the handling
32783278 // of the tv.val.tag() and then Int should do extra constPtrToInt on top
src/codegen/spirv.zig+3-3
......@@ -621,7 +621,7 @@ pub const DeclGen = struct {
621621 switch (ty.zigTypeTag(mod)) {
622622 .Int => try self.addInt(ty, val),
623623 .Float => try self.addFloat(ty, val),
624 .Bool => try self.addConstBool(val.toBool()),
624 .Bool => try self.addConstBool(val.toBool(mod)),
625625 .Array => switch (val.tag()) {
626626 .aggregate => {
627627 const elem_vals = val.castTag(.aggregate).?.data;
......@@ -989,8 +989,8 @@ pub const DeclGen = struct {
989989 }
990990 },
991991 .Bool => switch (repr) {
992 .direct => return try self.spv.constBool(result_ty_ref, val.toBool()),
993 .indirect => return try self.spv.constInt(result_ty_ref, @boolToInt(val.toBool())),
992 .direct => return try self.spv.constBool(result_ty_ref, val.toBool(mod)),
993 .indirect => return try self.spv.constInt(result_ty_ref, @boolToInt(val.toBool(mod))),
994994 },
995995 .Float => return switch (ty.floatBits(target)) {
996996 16 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float16 = val.toFloat(f16) } } }),
src/type.zig+16-16
......@@ -2054,22 +2054,22 @@ pub const Type = struct {
20542054 pub fn toValue(self: Type, allocator: Allocator) Allocator.Error!Value {
20552055 if (self.ip_index != .none) return self.ip_index.toValue();
20562056 switch (self.tag()) {
2057 .u1 => return Value.initTag(.u1_type),
2058 .u8 => return Value.initTag(.u8_type),
2059 .i8 => return Value.initTag(.i8_type),
2060 .u16 => return Value.initTag(.u16_type),
2061 .u29 => return Value.initTag(.u29_type),
2062 .i16 => return Value.initTag(.i16_type),
2063 .u32 => return Value.initTag(.u32_type),
2064 .i32 => return Value.initTag(.i32_type),
2065 .u64 => return Value.initTag(.u64_type),
2066 .i64 => return Value.initTag(.i64_type),
2067 .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
2068 .const_slice_u8 => return Value.initTag(.const_slice_u8_type),
2069 .const_slice_u8_sentinel_0 => return Value.initTag(.const_slice_u8_sentinel_0_type),
2070 .manyptr_u8 => return Value.initTag(.manyptr_u8_type),
2071 .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type),
2072 .manyptr_const_u8_sentinel_0 => return Value.initTag(.manyptr_const_u8_sentinel_0_type),
2057 .u1 => return Value{ .ip_index = .u1_type, .legacy = undefined },
2058 .u8 => return Value{ .ip_index = .u8_type, .legacy = undefined },
2059 .i8 => return Value{ .ip_index = .i8_type, .legacy = undefined },
2060 .u16 => return Value{ .ip_index = .u16_type, .legacy = undefined },
2061 .u29 => return Value{ .ip_index = .u29_type, .legacy = undefined },
2062 .i16 => return Value{ .ip_index = .i16_type, .legacy = undefined },
2063 .u32 => return Value{ .ip_index = .u32_type, .legacy = undefined },
2064 .i32 => return Value{ .ip_index = .i32_type, .legacy = undefined },
2065 .u64 => return Value{ .ip_index = .u64_type, .legacy = undefined },
2066 .i64 => return Value{ .ip_index = .i64_type, .legacy = undefined },
2067 .single_const_pointer_to_comptime_int => return Value{ .ip_index = .single_const_pointer_to_comptime_int_type, .legacy = undefined },
2068 .const_slice_u8 => return Value{ .ip_index = .const_slice_u8_type, .legacy = undefined },
2069 .const_slice_u8_sentinel_0 => return Value{ .ip_index = .const_slice_u8_sentinel_0_type, .legacy = undefined },
2070 .manyptr_u8 => return Value{ .ip_index = .manyptr_u8_type, .legacy = undefined },
2071 .manyptr_const_u8 => return Value{ .ip_index = .manyptr_const_u8_type, .legacy = undefined },
2072 .manyptr_const_u8_sentinel_0 => return Value{ .ip_index = .manyptr_const_u8_sentinel_0_type, .legacy = undefined },
20732073 .inferred_alloc_const => unreachable,
20742074 .inferred_alloc_mut => unreachable,
20752075 else => return Value.Tag.ty.create(allocator, self),
src/value.zig+355-583
......@@ -33,58 +33,6 @@ pub const Value = struct {
3333 // Keep in sync with tools/stage2_pretty_printers_common.py
3434 pub const Tag = enum(usize) {
3535 // The first section of this enum are tags that require no payload.
36 u1_type,
37 u8_type,
38 i8_type,
39 u16_type,
40 i16_type,
41 u29_type,
42 u32_type,
43 i32_type,
44 u64_type,
45 i64_type,
46 u128_type,
47 i128_type,
48 usize_type,
49 isize_type,
50 c_char_type,
51 c_short_type,
52 c_ushort_type,
53 c_int_type,
54 c_uint_type,
55 c_long_type,
56 c_ulong_type,
57 c_longlong_type,
58 c_ulonglong_type,
59 c_longdouble_type,
60 f16_type,
61 f32_type,
62 f64_type,
63 f80_type,
64 f128_type,
65 anyopaque_type,
66 bool_type,
67 void_type,
68 type_type,
69 anyerror_type,
70 comptime_int_type,
71 comptime_float_type,
72 noreturn_type,
73 anyframe_type,
74 null_type,
75 undefined_type,
76 enum_literal_type,
77 atomic_order_type,
78 atomic_rmw_op_type,
79 calling_convention_type,
80 address_space_type,
81 float_mode_type,
82 reduce_op_type,
83 modifier_type,
84 prefetch_options_type,
85 export_options_type,
86 extern_options_type,
87 type_info_type,
8836 manyptr_u8_type,
8937 manyptr_const_u8_type,
9038 manyptr_const_u8_sentinel_0_type,
......@@ -92,19 +40,14 @@ pub const Value = struct {
9240 const_slice_u8_type,
9341 const_slice_u8_sentinel_0_type,
9442 anyerror_void_error_union_type,
95 generic_poison_type,
9643
9744 undef,
9845 zero,
9946 one,
100 void_value,
10147 unreachable_value,
10248 /// The only possible value for a particular type, which is stored externally.
10349 the_only_possible_value,
10450 null_value,
105 bool_true,
106 bool_false,
107 generic_poison,
10851
10952 empty_struct_value,
11053 empty_array, // See last_no_payload_tag below.
......@@ -197,78 +140,22 @@ pub const Value = struct {
197140
198141 pub fn Type(comptime t: Tag) type {
199142 return switch (t) {
200 .u1_type,
201 .u8_type,
202 .i8_type,
203 .u16_type,
204 .i16_type,
205 .u29_type,
206 .u32_type,
207 .i32_type,
208 .u64_type,
209 .i64_type,
210 .u128_type,
211 .i128_type,
212 .usize_type,
213 .isize_type,
214 .c_char_type,
215 .c_short_type,
216 .c_ushort_type,
217 .c_int_type,
218 .c_uint_type,
219 .c_long_type,
220 .c_ulong_type,
221 .c_longlong_type,
222 .c_ulonglong_type,
223 .c_longdouble_type,
224 .f16_type,
225 .f32_type,
226 .f64_type,
227 .f80_type,
228 .f128_type,
229 .anyopaque_type,
230 .bool_type,
231 .void_type,
232 .type_type,
233 .anyerror_type,
234 .comptime_int_type,
235 .comptime_float_type,
236 .noreturn_type,
237 .null_type,
238 .undefined_type,
239143 .single_const_pointer_to_comptime_int_type,
240 .anyframe_type,
241144 .const_slice_u8_type,
242145 .const_slice_u8_sentinel_0_type,
243146 .anyerror_void_error_union_type,
244 .generic_poison_type,
245 .enum_literal_type,
147
246148 .undef,
247149 .zero,
248150 .one,
249 .void_value,
250151 .unreachable_value,
251152 .the_only_possible_value,
252153 .empty_struct_value,
253154 .empty_array,
254155 .null_value,
255 .bool_true,
256 .bool_false,
257156 .manyptr_u8_type,
258157 .manyptr_const_u8_type,
259158 .manyptr_const_u8_sentinel_0_type,
260 .atomic_order_type,
261 .atomic_rmw_op_type,
262 .calling_convention_type,
263 .address_space_type,
264 .float_mode_type,
265 .reduce_op_type,
266 .modifier_type,
267 .prefetch_options_type,
268 .export_options_type,
269 .extern_options_type,
270 .type_info_type,
271 .generic_poison,
272159 => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),
273160
274161 .int_big_positive,
......@@ -418,78 +305,22 @@ pub const Value = struct {
418305 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
419306 };
420307 } else switch (self.legacy.ptr_otherwise.tag) {
421 .u1_type,
422 .u8_type,
423 .i8_type,
424 .u16_type,
425 .i16_type,
426 .u29_type,
427 .u32_type,
428 .i32_type,
429 .u64_type,
430 .i64_type,
431 .u128_type,
432 .i128_type,
433 .usize_type,
434 .isize_type,
435 .c_char_type,
436 .c_short_type,
437 .c_ushort_type,
438 .c_int_type,
439 .c_uint_type,
440 .c_long_type,
441 .c_ulong_type,
442 .c_longlong_type,
443 .c_ulonglong_type,
444 .c_longdouble_type,
445 .f16_type,
446 .f32_type,
447 .f64_type,
448 .f80_type,
449 .f128_type,
450 .anyopaque_type,
451 .bool_type,
452 .void_type,
453 .type_type,
454 .anyerror_type,
455 .comptime_int_type,
456 .comptime_float_type,
457 .noreturn_type,
458 .null_type,
459 .undefined_type,
460308 .single_const_pointer_to_comptime_int_type,
461 .anyframe_type,
462309 .const_slice_u8_type,
463310 .const_slice_u8_sentinel_0_type,
464311 .anyerror_void_error_union_type,
465 .generic_poison_type,
466 .enum_literal_type,
312
467313 .undef,
468314 .zero,
469315 .one,
470 .void_value,
471316 .unreachable_value,
472317 .the_only_possible_value,
473318 .empty_array,
474319 .null_value,
475 .bool_true,
476 .bool_false,
477320 .empty_struct_value,
478321 .manyptr_u8_type,
479322 .manyptr_const_u8_type,
480323 .manyptr_const_u8_sentinel_0_type,
481 .atomic_order_type,
482 .atomic_rmw_op_type,
483 .calling_convention_type,
484 .address_space_type,
485 .float_mode_type,
486 .reduce_op_type,
487 .modifier_type,
488 .prefetch_options_type,
489 .export_options_type,
490 .extern_options_type,
491 .type_info_type,
492 .generic_poison,
493324 => unreachable,
494325
495326 .ty, .lazy_align, .lazy_size => {
......@@ -722,67 +553,13 @@ pub const Value = struct {
722553 }
723554 var val = start_val;
724555 while (true) switch (val.tag()) {
725 .u1_type => return out_stream.writeAll("u1"),
726 .u8_type => return out_stream.writeAll("u8"),
727 .i8_type => return out_stream.writeAll("i8"),
728 .u16_type => return out_stream.writeAll("u16"),
729 .u29_type => return out_stream.writeAll("u29"),
730 .i16_type => return out_stream.writeAll("i16"),
731 .u32_type => return out_stream.writeAll("u32"),
732 .i32_type => return out_stream.writeAll("i32"),
733 .u64_type => return out_stream.writeAll("u64"),
734 .i64_type => return out_stream.writeAll("i64"),
735 .u128_type => return out_stream.writeAll("u128"),
736 .i128_type => return out_stream.writeAll("i128"),
737 .isize_type => return out_stream.writeAll("isize"),
738 .usize_type => return out_stream.writeAll("usize"),
739 .c_char_type => return out_stream.writeAll("c_char"),
740 .c_short_type => return out_stream.writeAll("c_short"),
741 .c_ushort_type => return out_stream.writeAll("c_ushort"),
742 .c_int_type => return out_stream.writeAll("c_int"),
743 .c_uint_type => return out_stream.writeAll("c_uint"),
744 .c_long_type => return out_stream.writeAll("c_long"),
745 .c_ulong_type => return out_stream.writeAll("c_ulong"),
746 .c_longlong_type => return out_stream.writeAll("c_longlong"),
747 .c_ulonglong_type => return out_stream.writeAll("c_ulonglong"),
748 .c_longdouble_type => return out_stream.writeAll("c_longdouble"),
749 .f16_type => return out_stream.writeAll("f16"),
750 .f32_type => return out_stream.writeAll("f32"),
751 .f64_type => return out_stream.writeAll("f64"),
752 .f80_type => return out_stream.writeAll("f80"),
753 .f128_type => return out_stream.writeAll("f128"),
754 .anyopaque_type => return out_stream.writeAll("anyopaque"),
755 .bool_type => return out_stream.writeAll("bool"),
756 .void_type => return out_stream.writeAll("void"),
757 .type_type => return out_stream.writeAll("type"),
758 .anyerror_type => return out_stream.writeAll("anyerror"),
759 .comptime_int_type => return out_stream.writeAll("comptime_int"),
760 .comptime_float_type => return out_stream.writeAll("comptime_float"),
761 .noreturn_type => return out_stream.writeAll("noreturn"),
762 .null_type => return out_stream.writeAll("@Type(.Null)"),
763 .undefined_type => return out_stream.writeAll("@Type(.Undefined)"),
764556 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
765 .anyframe_type => return out_stream.writeAll("anyframe"),
766557 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),
767558 .const_slice_u8_sentinel_0_type => return out_stream.writeAll("[:0]const u8"),
768559 .anyerror_void_error_union_type => return out_stream.writeAll("anyerror!void"),
769 .generic_poison_type => return out_stream.writeAll("(generic poison type)"),
770 .generic_poison => return out_stream.writeAll("(generic poison)"),
771 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
772560 .manyptr_u8_type => return out_stream.writeAll("[*]u8"),
773561 .manyptr_const_u8_type => return out_stream.writeAll("[*]const u8"),
774562 .manyptr_const_u8_sentinel_0_type => return out_stream.writeAll("[*:0]const u8"),
775 .atomic_order_type => return out_stream.writeAll("std.builtin.AtomicOrder"),
776 .atomic_rmw_op_type => return out_stream.writeAll("std.builtin.AtomicRmwOp"),
777 .calling_convention_type => return out_stream.writeAll("std.builtin.CallingConvention"),
778 .address_space_type => return out_stream.writeAll("std.builtin.AddressSpace"),
779 .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),
780 .reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"),
781 .modifier_type => return out_stream.writeAll("std.builtin.CallModifier"),
782 .prefetch_options_type => return out_stream.writeAll("std.builtin.PrefetchOptions"),
783 .export_options_type => return out_stream.writeAll("std.builtin.ExportOptions"),
784 .extern_options_type => return out_stream.writeAll("std.builtin.ExternOptions"),
785 .type_info_type => return out_stream.writeAll("std.builtin.Type"),
786563
787564 .empty_struct_value => return out_stream.writeAll("struct {}{}"),
788565 .aggregate => {
......@@ -795,11 +572,8 @@ pub const Value = struct {
795572 .undef => return out_stream.writeAll("undefined"),
796573 .zero => return out_stream.writeAll("0"),
797574 .one => return out_stream.writeAll("1"),
798 .void_value => return out_stream.writeAll("{}"),
799575 .unreachable_value => return out_stream.writeAll("unreachable"),
800576 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),
801 .bool_true => return out_stream.writeAll("true"),
802 .bool_false => return out_stream.writeAll("false"),
803577 .ty => return val.castTag(.ty).?.data.dump("", options, out_stream),
804578 .lazy_align => {
805579 try out_stream.writeAll("@alignOf(");
......@@ -943,74 +717,16 @@ pub const Value = struct {
943717
944718 /// Asserts that the value is representable as a type.
945719 pub fn toType(self: Value) Type {
946 if (self.ip_index != .none) {
947 return .{
948 .ip_index = self.ip_index,
949 .legacy = undefined,
950 };
951 }
720 if (self.ip_index != .none) return self.ip_index.toType();
952721 return switch (self.tag()) {
953722 .ty => self.castTag(.ty).?.data,
954 .u1_type => Type.u1,
955 .u8_type => Type.u8,
956 .i8_type => Type.i8,
957 .u16_type => Type.u16,
958 .i16_type => Type.i16,
959 .u29_type => Type.u29,
960 .u32_type => Type.u32,
961 .i32_type => Type.i32,
962 .u64_type => Type.u64,
963 .i64_type => Type.i64,
964 .u128_type => Type.u128,
965 .i128_type => Type.i128,
966 .usize_type => Type.usize,
967 .isize_type => Type.isize,
968 .c_char_type => Type.c_char,
969 .c_short_type => Type.c_short,
970 .c_ushort_type => Type.c_ushort,
971 .c_int_type => Type.c_int,
972 .c_uint_type => Type.c_uint,
973 .c_long_type => Type.c_long,
974 .c_ulong_type => Type.c_ulong,
975 .c_longlong_type => Type.c_longlong,
976 .c_ulonglong_type => Type.c_ulonglong,
977 .c_longdouble_type => Type.c_longdouble,
978 .f16_type => Type.f16,
979 .f32_type => Type.f32,
980 .f64_type => Type.f64,
981 .f80_type => Type.f80,
982 .f128_type => Type.f128,
983 .anyopaque_type => Type.anyopaque,
984 .bool_type => Type.bool,
985 .void_type => Type.void,
986 .type_type => Type.type,
987 .anyerror_type => Type.anyerror,
988 .comptime_int_type => Type.comptime_int,
989 .comptime_float_type => Type.comptime_float,
990 .noreturn_type => Type.noreturn,
991 .null_type => Type.null,
992 .undefined_type => Type.undefined,
993723 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
994 .anyframe_type => Type.@"anyframe",
995724 .const_slice_u8_type => Type.initTag(.const_slice_u8),
996725 .const_slice_u8_sentinel_0_type => Type.initTag(.const_slice_u8_sentinel_0),
997726 .anyerror_void_error_union_type => Type.initTag(.anyerror_void_error_union),
998 .generic_poison_type => .{ .ip_index = .generic_poison_type, .legacy = undefined },
999 .enum_literal_type => .{ .ip_index = .enum_literal_type, .legacy = undefined },
1000727 .manyptr_u8_type => Type.initTag(.manyptr_u8),
1001728 .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8),
1002729 .manyptr_const_u8_sentinel_0_type => Type.initTag(.manyptr_const_u8_sentinel_0),
1003 .atomic_order_type => .{ .ip_index = .atomic_order_type, .legacy = undefined },
1004 .atomic_rmw_op_type => .{ .ip_index = .atomic_rmw_op_type, .legacy = undefined },
1005 .calling_convention_type => .{ .ip_index = .calling_convention_type, .legacy = undefined },
1006 .address_space_type => .{ .ip_index = .address_space_type, .legacy = undefined },
1007 .float_mode_type => .{ .ip_index = .float_mode_type, .legacy = undefined },
1008 .reduce_op_type => .{ .ip_index = .reduce_op_type, .legacy = undefined },
1009 .modifier_type => .{ .ip_index = .call_modifier_type, .legacy = undefined },
1010 .prefetch_options_type => .{ .ip_index = .prefetch_options_type, .legacy = undefined },
1011 .export_options_type => .{ .ip_index = .export_options_type, .legacy = undefined },
1012 .extern_options_type => .{ .ip_index = .extern_options_type, .legacy = undefined },
1013 .type_info_type => .{ .ip_index = .type_info_type, .legacy = undefined },
1014730
1015731 else => unreachable,
1016732 };
......@@ -1133,58 +849,63 @@ pub const Value = struct {
1133849 mod: *const Module,
1134850 opt_sema: ?*Sema,
1135851 ) Module.CompileError!BigIntConst {
1136 switch (val.tag()) {
1137 .null_value,
1138 .zero,
1139 .bool_false,
1140 .the_only_possible_value, // i0, u0
1141 => return BigIntMutable.init(&space.limbs, 0).toConst(),
852 switch (val.ip_index) {
853 .bool_false => return BigIntMutable.init(&space.limbs, 0).toConst(),
854 .bool_true => return BigIntMutable.init(&space.limbs, 1).toConst(),
855 .none => switch (val.tag()) {
856 .null_value,
857 .zero,
858 .the_only_possible_value, // i0, u0
859 => return BigIntMutable.init(&space.limbs, 0).toConst(),
1142860
1143 .one,
1144 .bool_true,
1145 => return BigIntMutable.init(&space.limbs, 1).toConst(),
861 .one => return BigIntMutable.init(&space.limbs, 1).toConst(),
1146862
1147 .enum_field_index => {
1148 const index = val.castTag(.enum_field_index).?.data;
1149 return BigIntMutable.init(&space.limbs, index).toConst();
1150 },
1151 .runtime_value => {
1152 const sub_val = val.castTag(.runtime_value).?.data;
1153 return sub_val.toBigIntAdvanced(space, mod, opt_sema);
1154 },
1155 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
1156 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
1157 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
1158 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
863 .enum_field_index => {
864 const index = val.castTag(.enum_field_index).?.data;
865 return BigIntMutable.init(&space.limbs, index).toConst();
866 },
867 .runtime_value => {
868 const sub_val = val.castTag(.runtime_value).?.data;
869 return sub_val.toBigIntAdvanced(space, mod, opt_sema);
870 },
871 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
872 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
873 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
874 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
1159875
1160 .undef => unreachable,
876 .undef => unreachable,
1161877
1162 .lazy_align => {
1163 const ty = val.castTag(.lazy_align).?.data;
1164 if (opt_sema) |sema| {
1165 try sema.resolveTypeLayout(ty);
1166 }
1167 const x = ty.abiAlignment(mod);
1168 return BigIntMutable.init(&space.limbs, x).toConst();
1169 },
1170 .lazy_size => {
1171 const ty = val.castTag(.lazy_size).?.data;
1172 if (opt_sema) |sema| {
1173 try sema.resolveTypeLayout(ty);
1174 }
1175 const x = ty.abiSize(mod);
1176 return BigIntMutable.init(&space.limbs, x).toConst();
1177 },
878 .lazy_align => {
879 const ty = val.castTag(.lazy_align).?.data;
880 if (opt_sema) |sema| {
881 try sema.resolveTypeLayout(ty);
882 }
883 const x = ty.abiAlignment(mod);
884 return BigIntMutable.init(&space.limbs, x).toConst();
885 },
886 .lazy_size => {
887 const ty = val.castTag(.lazy_size).?.data;
888 if (opt_sema) |sema| {
889 try sema.resolveTypeLayout(ty);
890 }
891 const x = ty.abiSize(mod);
892 return BigIntMutable.init(&space.limbs, x).toConst();
893 },
1178894
1179 .elem_ptr => {
1180 const elem_ptr = val.castTag(.elem_ptr).?.data;
1181 const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(mod, opt_sema)).?;
1182 const elem_size = elem_ptr.elem_ty.abiSize(mod);
1183 const new_addr = array_addr + elem_size * elem_ptr.index;
1184 return BigIntMutable.init(&space.limbs, new_addr).toConst();
1185 },
895 .elem_ptr => {
896 const elem_ptr = val.castTag(.elem_ptr).?.data;
897 const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(mod, opt_sema)).?;
898 const elem_size = elem_ptr.elem_ty.abiSize(mod);
899 const new_addr = array_addr + elem_size * elem_ptr.index;
900 return BigIntMutable.init(&space.limbs, new_addr).toConst();
901 },
1186902
1187 else => unreachable,
903 else => unreachable,
904 },
905 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
906 .int => |int| return int.big_int,
907 else => unreachable,
908 },
1188909 }
1189910 }
1190911
......@@ -1197,41 +918,46 @@ pub const Value = struct {
1197918 /// If the value fits in a u64, return it, otherwise null.
1198919 /// Asserts not undefined.
1199920 pub fn getUnsignedIntAdvanced(val: Value, mod: *const Module, opt_sema: ?*Sema) !?u64 {
1200 switch (val.tag()) {
1201 .zero,
1202 .bool_false,
1203 .the_only_possible_value, // i0, u0
1204 => return 0,
921 switch (val.ip_index) {
922 .bool_false => return 0,
923 .bool_true => return 1,
924 .none => switch (val.tag()) {
925 .zero,
926 .the_only_possible_value, // i0, u0
927 => return 0,
1205928
1206 .one,
1207 .bool_true,
1208 => return 1,
929 .one => return 1,
1209930
1210 .int_u64 => return val.castTag(.int_u64).?.data,
1211 .int_i64 => return @intCast(u64, val.castTag(.int_i64).?.data),
1212 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null,
1213 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
931 .int_u64 => return val.castTag(.int_u64).?.data,
932 .int_i64 => return @intCast(u64, val.castTag(.int_i64).?.data),
933 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null,
934 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
1214935
1215 .undef => unreachable,
936 .undef => unreachable,
1216937
1217 .lazy_align => {
1218 const ty = val.castTag(.lazy_align).?.data;
1219 if (opt_sema) |sema| {
1220 return (try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
1221 } else {
1222 return ty.abiAlignment(mod);
1223 }
938 .lazy_align => {
939 const ty = val.castTag(.lazy_align).?.data;
940 if (opt_sema) |sema| {
941 return (try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
942 } else {
943 return ty.abiAlignment(mod);
944 }
945 },
946 .lazy_size => {
947 const ty = val.castTag(.lazy_size).?.data;
948 if (opt_sema) |sema| {
949 return (try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
950 } else {
951 return ty.abiSize(mod);
952 }
953 },
954
955 else => return null,
1224956 },
1225 .lazy_size => {
1226 const ty = val.castTag(.lazy_size).?.data;
1227 if (opt_sema) |sema| {
1228 return (try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
1229 } else {
1230 return ty.abiSize(mod);
1231 }
957 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
958 .int => |int| return int.big_int.to(u64) catch null,
959 else => unreachable,
1232960 },
1233
1234 else => return null,
1235961 }
1236962 }
1237963
......@@ -1242,51 +968,65 @@ pub const Value = struct {
1242968
1243969 /// Asserts the value is an integer and it fits in a i64
1244970 pub fn toSignedInt(val: Value, mod: *const Module) i64 {
1245 switch (val.tag()) {
1246 .zero,
1247 .bool_false,
1248 .the_only_possible_value, // i0, u0
1249 => return 0,
971 switch (val.ip_index) {
972 .bool_false => return 0,
973 .bool_true => return 1,
974 .none => switch (val.tag()) {
975 .zero,
976 .the_only_possible_value, // i0, u0
977 => return 0,
1250978
1251 .one,
1252 .bool_true,
1253 => return 1,
979 .one => return 1,
1254980
1255 .int_u64 => return @intCast(i64, val.castTag(.int_u64).?.data),
1256 .int_i64 => return val.castTag(.int_i64).?.data,
1257 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
1258 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
981 .int_u64 => return @intCast(i64, val.castTag(.int_u64).?.data),
982 .int_i64 => return val.castTag(.int_i64).?.data,
983 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
984 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
1259985
1260 .lazy_align => {
1261 const ty = val.castTag(.lazy_align).?.data;
1262 return @intCast(i64, ty.abiAlignment(mod));
986 .lazy_align => {
987 const ty = val.castTag(.lazy_align).?.data;
988 return @intCast(i64, ty.abiAlignment(mod));
989 },
990 .lazy_size => {
991 const ty = val.castTag(.lazy_size).?.data;
992 return @intCast(i64, ty.abiSize(mod));
993 },
994
995 .undef => unreachable,
996 else => unreachable,
1263997 },
1264 .lazy_size => {
1265 const ty = val.castTag(.lazy_size).?.data;
1266 return @intCast(i64, ty.abiSize(mod));
998 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
999 .int => |int| return int.big_int.to(i64) catch unreachable,
1000 else => unreachable,
12671001 },
1268
1269 .undef => unreachable,
1270 else => unreachable,
12711002 }
12721003 }
12731004
1274 pub fn toBool(self: Value) bool {
1275 return switch (self.tag()) {
1276 .bool_true, .one => true,
1277 .bool_false, .zero => false,
1278 .int_u64 => switch (self.castTag(.int_u64).?.data) {
1279 0 => false,
1280 1 => true,
1005 pub fn toBool(val: Value, mod: *const Module) bool {
1006 switch (val.ip_index) {
1007 .bool_true => return true,
1008 .bool_false => return false,
1009 .none => return switch (val.tag()) {
1010 .one => true,
1011 .zero => false,
1012
1013 .int_u64 => switch (val.castTag(.int_u64).?.data) {
1014 0 => false,
1015 1 => true,
1016 else => unreachable,
1017 },
1018 .int_i64 => switch (val.castTag(.int_i64).?.data) {
1019 0 => false,
1020 1 => true,
1021 else => unreachable,
1022 },
12811023 else => unreachable,
12821024 },
1283 .int_i64 => switch (self.castTag(.int_i64).?.data) {
1284 0 => false,
1285 1 => true,
1025 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1026 .int => |int| return !int.big_int.eqZero(),
12861027 else => unreachable,
12871028 },
1288 else => unreachable,
1289 };
1029 }
12901030 }
12911031
12921032 fn isDeclRef(val: Value) bool {
......@@ -1319,7 +1059,7 @@ pub const Value = struct {
13191059 switch (ty.zigTypeTag(mod)) {
13201060 .Void => {},
13211061 .Bool => {
1322 buffer[0] = @boolToInt(val.toBool());
1062 buffer[0] = @boolToInt(val.toBool(mod));
13231063 },
13241064 .Int, .Enum => {
13251065 const int_info = ty.intInfo(mod);
......@@ -1442,7 +1182,7 @@ pub const Value = struct {
14421182 .Little => bit_offset / 8,
14431183 .Big => buffer.len - bit_offset / 8 - 1,
14441184 };
1445 if (val.toBool()) {
1185 if (val.toBool(mod)) {
14461186 buffer[byte_index] |= (@as(u8, 1) << @intCast(u3, bit_offset % 8));
14471187 } else {
14481188 buffer[byte_index] &= ~(@as(u8, 1) << @intCast(u3, bit_offset % 8));
......@@ -1802,90 +1542,117 @@ pub const Value = struct {
18021542
18031543 pub fn clz(val: Value, ty: Type, mod: *const Module) u64 {
18041544 const ty_bits = ty.intInfo(mod).bits;
1805 switch (val.tag()) {
1806 .zero, .bool_false => return ty_bits,
1807 .one, .bool_true => return ty_bits - 1,
1545 switch (val.ip_index) {
1546 .bool_false => return ty_bits,
1547 .bool_true => return ty_bits - 1,
1548 .none => switch (val.tag()) {
1549 .zero => return ty_bits,
1550 .one => return ty_bits - 1,
1551
1552 .int_u64 => {
1553 const big = @clz(val.castTag(.int_u64).?.data);
1554 return big + ty_bits - 64;
1555 },
1556 .int_i64 => {
1557 @panic("TODO implement i64 Value clz");
1558 },
1559 .int_big_positive => {
1560 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1561 return bigint.clz(ty_bits);
1562 },
1563 .int_big_negative => {
1564 @panic("TODO implement int_big_negative Value clz");
1565 },
18081566
1809 .int_u64 => {
1810 const big = @clz(val.castTag(.int_u64).?.data);
1811 return big + ty_bits - 64;
1812 },
1813 .int_i64 => {
1814 @panic("TODO implement i64 Value clz");
1815 },
1816 .int_big_positive => {
1817 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1818 return bigint.clz(ty_bits);
1819 },
1820 .int_big_negative => {
1821 @panic("TODO implement int_big_negative Value clz");
1822 },
1567 .the_only_possible_value => {
1568 assert(ty_bits == 0);
1569 return ty_bits;
1570 },
18231571
1824 .the_only_possible_value => {
1825 assert(ty_bits == 0);
1826 return ty_bits;
1827 },
1572 .lazy_align, .lazy_size => {
1573 var bigint_buf: BigIntSpace = undefined;
1574 const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
1575 return bigint.clz(ty_bits);
1576 },
18281577
1829 .lazy_align, .lazy_size => {
1830 var bigint_buf: BigIntSpace = undefined;
1831 const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
1832 return bigint.clz(ty_bits);
1578 else => unreachable,
1579 },
1580 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1581 .int => |int| return int.big_int.clz(ty_bits),
1582 else => unreachable,
18331583 },
1834
1835 else => unreachable,
18361584 }
18371585 }
18381586
18391587 pub fn ctz(val: Value, ty: Type, mod: *const Module) u64 {
18401588 const ty_bits = ty.intInfo(mod).bits;
1841 switch (val.tag()) {
1842 .zero, .bool_false => return ty_bits,
1843 .one, .bool_true => return 0,
1589 switch (val.ip_index) {
1590 .bool_false => return ty_bits,
1591 .bool_true => return 0,
1592 .none => switch (val.tag()) {
1593 .zero => return ty_bits,
1594 .one => return 0,
1595
1596 .int_u64 => {
1597 const big = @ctz(val.castTag(.int_u64).?.data);
1598 return if (big == 64) ty_bits else big;
1599 },
1600 .int_i64 => {
1601 @panic("TODO implement i64 Value ctz");
1602 },
1603 .int_big_positive => {
1604 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1605 return bigint.ctz();
1606 },
1607 .int_big_negative => {
1608 @panic("TODO implement int_big_negative Value ctz");
1609 },
18441610
1845 .int_u64 => {
1846 const big = @ctz(val.castTag(.int_u64).?.data);
1847 return if (big == 64) ty_bits else big;
1848 },
1849 .int_i64 => {
1850 @panic("TODO implement i64 Value ctz");
1851 },
1852 .int_big_positive => {
1853 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1854 return bigint.ctz();
1855 },
1856 .int_big_negative => {
1857 @panic("TODO implement int_big_negative Value ctz");
1858 },
1611 .the_only_possible_value => {
1612 assert(ty_bits == 0);
1613 return ty_bits;
1614 },
18591615
1860 .the_only_possible_value => {
1861 assert(ty_bits == 0);
1862 return ty_bits;
1863 },
1616 .lazy_align, .lazy_size => {
1617 var bigint_buf: BigIntSpace = undefined;
1618 const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
1619 return bigint.ctz();
1620 },
18641621
1865 .lazy_align, .lazy_size => {
1866 var bigint_buf: BigIntSpace = undefined;
1867 const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
1868 return bigint.ctz();
1622 else => unreachable,
1623 },
1624 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1625 .int => |int| return int.big_int.ctz(),
1626 else => unreachable,
18691627 },
1870
1871 else => unreachable,
18721628 }
18731629 }
18741630
18751631 pub fn popCount(val: Value, ty: Type, mod: *const Module) u64 {
18761632 assert(!val.isUndef());
1877 switch (val.tag()) {
1878 .zero, .bool_false => return 0,
1879 .one, .bool_true => return 1,
1633 switch (val.ip_index) {
1634 .bool_false => return 0,
1635 .bool_true => return 1,
1636 .none => switch (val.tag()) {
1637 .zero => return 0,
1638 .one => return 1,
18801639
1881 .int_u64 => return @popCount(val.castTag(.int_u64).?.data),
1640 .int_u64 => return @popCount(val.castTag(.int_u64).?.data),
18821641
1883 else => {
1884 const info = ty.intInfo(mod);
1642 else => {
1643 const info = ty.intInfo(mod);
18851644
1886 var buffer: Value.BigIntSpace = undefined;
1887 const int = val.toBigInt(&buffer, mod);
1888 return @intCast(u64, int.popCount(info.bits));
1645 var buffer: Value.BigIntSpace = undefined;
1646 const int = val.toBigInt(&buffer, mod);
1647 return @intCast(u64, int.popCount(info.bits));
1648 },
1649 },
1650 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1651 .int => |int| {
1652 const info = ty.intInfo(mod);
1653 return int.big_int.popCount(info.bits);
1654 },
1655 else => unreachable,
18891656 },
18901657 }
18911658 }
......@@ -1933,37 +1700,42 @@ pub const Value = struct {
19331700 /// Returns the number of bits the value requires to represent stored in twos complement form.
19341701 pub fn intBitCountTwosComp(self: Value, mod: *const Module) usize {
19351702 const target = mod.getTarget();
1936 switch (self.tag()) {
1937 .zero,
1938 .bool_false,
1939 .the_only_possible_value,
1940 => return 0,
1941
1942 .one,
1943 .bool_true,
1944 => return 1,
1703 switch (self.ip_index) {
1704 .bool_false => return 0,
1705 .bool_true => return 1,
1706 .none => switch (self.tag()) {
1707 .zero,
1708 .the_only_possible_value,
1709 => return 0,
19451710
1946 .int_u64 => {
1947 const x = self.castTag(.int_u64).?.data;
1948 if (x == 0) return 0;
1949 return @intCast(usize, std.math.log2(x) + 1);
1950 },
1951 .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().bitCountTwosComp(),
1952 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
1711 .one => return 1,
19531712
1954 .decl_ref_mut,
1955 .comptime_field_ptr,
1956 .extern_fn,
1957 .decl_ref,
1958 .function,
1959 .variable,
1960 .eu_payload_ptr,
1961 .opt_payload_ptr,
1962 => return target.ptrBitWidth(),
1713 .int_u64 => {
1714 const x = self.castTag(.int_u64).?.data;
1715 if (x == 0) return 0;
1716 return @intCast(usize, std.math.log2(x) + 1);
1717 },
1718 .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().bitCountTwosComp(),
1719 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
1720
1721 .decl_ref_mut,
1722 .comptime_field_ptr,
1723 .extern_fn,
1724 .decl_ref,
1725 .function,
1726 .variable,
1727 .eu_payload_ptr,
1728 .opt_payload_ptr,
1729 => return target.ptrBitWidth(),
19631730
1964 else => {
1965 var buffer: BigIntSpace = undefined;
1966 return self.toBigInt(&buffer, mod).bitCountTwosComp();
1731 else => {
1732 var buffer: BigIntSpace = undefined;
1733 return self.toBigInt(&buffer, mod).bitCountTwosComp();
1734 },
1735 },
1736 else => switch (mod.intern_pool.indexToKey(self.ip_index)) {
1737 .int => |int| return int.big_int.bitCountTwosComp(),
1738 else => unreachable,
19671739 },
19681740 }
19691741 }
......@@ -2008,82 +1780,88 @@ pub const Value = struct {
20081780 mod: *const Module,
20091781 opt_sema: ?*Sema,
20101782 ) Module.CompileError!std.math.Order {
2011 return switch (lhs.tag()) {
2012 .zero,
2013 .bool_false,
2014 .the_only_possible_value,
2015 => .eq,
1783 switch (lhs.ip_index) {
1784 .bool_false => return .eq,
1785 .bool_true => return .gt,
1786 .none => return switch (lhs.tag()) {
1787 .zero,
1788 .the_only_possible_value,
1789 => .eq,
20161790
2017 .one,
2018 .bool_true,
2019 .decl_ref,
2020 .decl_ref_mut,
2021 .comptime_field_ptr,
2022 .extern_fn,
2023 .function,
2024 .variable,
2025 => .gt,
1791 .one,
1792 .decl_ref,
1793 .decl_ref_mut,
1794 .comptime_field_ptr,
1795 .extern_fn,
1796 .function,
1797 .variable,
1798 => .gt,
1799
1800 .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0),
1801 .runtime_value => {
1802 // This is needed to correctly handle hashing the value.
1803 // Checks in Sema should prevent direct comparisons from reaching here.
1804 const val = lhs.castTag(.runtime_value).?.data;
1805 return val.orderAgainstZeroAdvanced(mod, opt_sema);
1806 },
1807 .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),
1808 .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),
1809 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
1810 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
1811
1812 .lazy_align => {
1813 const ty = lhs.castTag(.lazy_align).?.data;
1814 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
1815 if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1816 error.NeedLazy => unreachable,
1817 else => |e| return e,
1818 }) {
1819 return .gt;
1820 } else {
1821 return .eq;
1822 }
1823 },
1824 .lazy_size => {
1825 const ty = lhs.castTag(.lazy_size).?.data;
1826 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
1827 if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1828 error.NeedLazy => unreachable,
1829 else => |e| return e,
1830 }) {
1831 return .gt;
1832 } else {
1833 return .eq;
1834 }
1835 },
20261836
2027 .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0),
2028 .runtime_value => {
2029 // This is needed to correctly handle hashing the value.
2030 // Checks in Sema should prevent direct comparisons from reaching here.
2031 const val = lhs.castTag(.runtime_value).?.data;
2032 return val.orderAgainstZeroAdvanced(mod, opt_sema);
2033 },
2034 .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),
2035 .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),
2036 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
2037 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
1837 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
1838 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
1839 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
1840 .float_80 => std.math.order(lhs.castTag(.float_80).?.data, 0),
1841 .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0),
1842
1843 .elem_ptr => {
1844 const elem_ptr = lhs.castTag(.elem_ptr).?.data;
1845 switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) {
1846 .lt => unreachable,
1847 .gt => return .gt,
1848 .eq => {
1849 if (elem_ptr.index == 0) {
1850 return .eq;
1851 } else {
1852 return .gt;
1853 }
1854 },
1855 }
1856 },
20381857
2039 .lazy_align => {
2040 const ty = lhs.castTag(.lazy_align).?.data;
2041 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
2042 if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2043 error.NeedLazy => unreachable,
2044 else => |e| return e,
2045 }) {
2046 return .gt;
2047 } else {
2048 return .eq;
2049 }
2050 },
2051 .lazy_size => {
2052 const ty = lhs.castTag(.lazy_size).?.data;
2053 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
2054 if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2055 error.NeedLazy => unreachable,
2056 else => |e| return e,
2057 }) {
2058 return .gt;
2059 } else {
2060 return .eq;
2061 }
1858 else => unreachable,
20621859 },
2063
2064 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
2065 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
2066 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
2067 .float_80 => std.math.order(lhs.castTag(.float_80).?.data, 0),
2068 .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0),
2069
2070 .elem_ptr => {
2071 const elem_ptr = lhs.castTag(.elem_ptr).?.data;
2072 switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) {
2073 .lt => unreachable,
2074 .gt => return .gt,
2075 .eq => {
2076 if (elem_ptr.index == 0) {
2077 return .eq;
2078 } else {
2079 return .gt;
2080 }
2081 },
2082 }
1860 else => switch (mod.intern_pool.indexToKey(lhs.ip_index)) {
1861 .int => |int| return int.big_int.orderAgainstScalar(0),
1862 else => unreachable,
20831863 },
2084
2085 else => unreachable,
2086 };
1864 }
20871865 }
20881866
20891867 /// Asserts the value is comparable.
......@@ -2293,12 +2071,14 @@ pub const Value = struct {
22932071 mod: *Module,
22942072 opt_sema: ?*Sema,
22952073 ) Module.CompileError!bool {
2074 if (a.ip_index != .none or b.ip_index != .none) return a.ip_index == b.ip_index;
2075
22962076 const target = mod.getTarget();
22972077 const a_tag = a.tag();
22982078 const b_tag = b.tag();
22992079 if (a_tag == b_tag) switch (a_tag) {
23002080 .undef => return true,
2301 .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,
2081 .null_value, .the_only_possible_value, .empty_struct_value => return true,
23022082 .enum_literal => {
23032083 const a_name = a.castTag(.enum_literal).?.data;
23042084 const b_name = b.castTag(.enum_literal).?.data;
......@@ -2574,6 +2354,13 @@ pub const Value = struct {
25742354 /// This function is used by hash maps and so treats floating-point NaNs as equal
25752355 /// to each other, and not equal to other floating-point values.
25762356 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
2357 if (val.ip_index != .none) {
2358 // The InternPool data structure hashes based on Key to make interned objects
2359 // unique. An Index can be treated simply as u32 value for the
2360 // purpose of Type/Value hashing and equality.
2361 std.hash.autoHash(hasher, val.ip_index);
2362 return;
2363 }
25772364 const zig_ty_tag = ty.zigTypeTag(mod);
25782365 std.hash.autoHash(hasher, zig_ty_tag);
25792366 if (val.isUndef()) return;
......@@ -2908,8 +2695,6 @@ pub const Value = struct {
29082695 .int_i64,
29092696 .int_big_positive,
29102697 .int_big_negative,
2911 .bool_false,
2912 .bool_true,
29132698 .the_only_possible_value,
29142699 .lazy_align,
29152700 .lazy_size,
......@@ -3051,15 +2836,6 @@ pub const Value = struct {
30512836 .opt_payload => return val.castTag(.opt_payload).?.data.elemValueAdvanced(mod, index, arena, buffer),
30522837 .eu_payload => return val.castTag(.eu_payload).?.data.elemValueAdvanced(mod, index, arena, buffer),
30532838
3054 // These values will implicitly be treated as `repeated`.
3055 .zero,
3056 .one,
3057 .bool_false,
3058 .bool_true,
3059 .int_i64,
3060 .int_u64,
3061 => return val,
3062
30632839 else => unreachable,
30642840 }
30652841 }
......@@ -3272,13 +3048,10 @@ pub const Value = struct {
32723048 // in which case the value 0 is null and other values are non-null.
32733049
32743050 .zero,
3275 .bool_false,
32763051 .the_only_possible_value,
32773052 => true,
32783053
3279 .one,
3280 .bool_true,
3281 => false,
3054 .one => false,
32823055
32833056 .int_u64,
32843057 .int_i64,
......@@ -5419,11 +5192,7 @@ pub const Value = struct {
54195192 }
54205193
54215194 pub fn isGenericPoison(val: Value) bool {
5422 return switch (val.ip_index) {
5423 .generic_poison => true,
5424 .none => val.tag() == .generic_poison,
5425 else => false,
5426 };
5195 return val.ip_index == .generic_poison;
54275196 }
54285197
54295198 /// This type is not copyable since it may contain pointers to its inner data.
......@@ -5673,10 +5442,13 @@ pub const Value = struct {
56735442 .legacy = .{ .ptr_otherwise = &negative_one_payload.base },
56745443 };
56755444 pub const undef = initTag(.undef);
5676 pub const @"void" = initTag(.void_value);
5445 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };
56775446 pub const @"null" = initTag(.null_value);
5678 pub const @"false" = initTag(.bool_false);
5679 pub const @"true" = initTag(.bool_true);
5447 pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined };
5448 pub const @"true": Value = .{ .ip_index = .bool_true, .legacy = undefined };
5449
5450 pub const generic_poison: Value = .{ .ip_index = .generic_poison, .legacy = undefined };
5451 pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined };
56805452
56815453 pub fn makeBool(x: bool) Value {
56825454 return if (x) Value.true else Value.false;