authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-05-07 15:23:12+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:29-07:00
logc1ca16d779a3f3201a5a35a88eff188290b2091a
treef6af6b5ac4da7bb28c1b2821c835e51e5b797be4
parent9d9e1a29911c0ecf92eb9db10027cf691cd4b07e

wip: progress towards compiling tests


5 files changed, 213 insertions(+), 134 deletions(-)

src/Module.zig+14-3
......@@ -934,9 +934,12 @@ pub const Decl = struct {
934934
935935 pub fn isExtern(decl: Decl) bool {
936936 assert(decl.has_tv);
937 return switch (decl.val.tag()) {
938 .extern_fn => true,
939 .variable => decl.val.castTag(.variable).?.data.init.ip_index == .unreachable_value,
937 return switch (decl.val.ip_index) {
938 .none => switch (decl.val.tag()) {
939 .extern_fn => true,
940 .variable => decl.val.castTag(.variable).?.data.init.ip_index == .unreachable_value,
941 else => false,
942 },
940943 else => false,
941944 };
942945 }
......@@ -6833,6 +6836,10 @@ pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allo
68336836}
68346837
68356838pub fn arrayType(mod: *Module, info: InternPool.Key.ArrayType) Allocator.Error!Type {
6839 if (std.debug.runtime_safety and info.sentinel != .none) {
6840 const sent_ty = mod.intern_pool.indexToKey(info.sentinel).typeOf();
6841 assert(sent_ty == info.child);
6842 }
68366843 const i = try intern(mod, .{ .array_type = info });
68376844 return i.toType();
68386845}
......@@ -6848,6 +6855,10 @@ pub fn optionalType(mod: *Module, child_type: InternPool.Index) Allocator.Error!
68486855}
68496856
68506857pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type {
6858 if (std.debug.runtime_safety and info.sentinel != .none) {
6859 const sent_ty = mod.intern_pool.indexToKey(info.sentinel).typeOf();
6860 assert(sent_ty == info.elem_type);
6861 }
68516862 const i = try intern(mod, .{ .ptr_type = info });
68526863 return i.toType();
68536864}
src/Sema.zig+58-41
......@@ -5146,7 +5146,7 @@ fn addStrLit(sema: *Sema, block: *Block, zir_bytes: []const u8) CompileError!Air
51465146 defer anon_decl.deinit();
51475147
51485148 const decl_index = try anon_decl.finish(
5149 try Type.array(anon_decl.arena(), gop.key_ptr.len, Value.zero, Type.u8, mod),
5149 try Type.array(anon_decl.arena(), gop.key_ptr.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
51505150 try Value.Tag.str_lit.create(anon_decl.arena(), gop.key_ptr.*),
51515151 0, // default alignment
51525152 );
......@@ -15567,7 +15567,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1556715567 => {},
1556815568 }
1556915569 const val = try ty.lazyAbiSize(mod, sema.arena);
15570 if (val.tag() == .lazy_size) {
15570 if (val.ip_index == .none and val.tag() == .lazy_size) {
1557115571 try sema.queueFullTypeResolution(ty);
1557215572 }
1557315573 return sema.addConstant(Type.comptime_int, val);
......@@ -16006,8 +16006,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1600616006 sema.arena,
1600716007 @enumToInt(info.signedness),
1600816008 );
16009 // bits: comptime_int,
16010 field_values[1] = try mod.intValue(Type.comptime_int, info.bits);
16009 // bits: u16,
16010 field_values[1] = try mod.intValue(Type.u16, info.bits);
1601116011
1601216012 return sema.addConstant(
1601316013 type_info_ty,
......@@ -16019,8 +16019,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1601916019 },
1602016020 .Float => {
1602116021 const field_values = try sema.arena.alloc(Value, 1);
16022 // bits: comptime_int,
16023 field_values[0] = try mod.intValue(Type.comptime_int, ty.bitSize(mod));
16022 // bits: u16,
16023 field_values[0] = try mod.intValue(Type.u16, ty.bitSize(mod));
1602416024
1602516025 return sema.addConstant(
1602616026 type_info_ty,
......@@ -25957,7 +25957,21 @@ fn coerceExtra(
2595725957 if (!opts.report_err) return error.NotCoercible;
2595825958 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) });
2595925959 }
25960 return try sema.addConstant(dest_ty, val);
25960 const key = mod.intern_pool.indexToKey(val.ip_index);
25961 // If the int is represented as a bigint, copy it so we can safely pass it to `mod.intern`
25962 const int_storage: InternPool.Key.Int.Storage = switch (key.int.storage) {
25963 .u64 => |x| .{ .u64 = x },
25964 .i64 => |x| .{ .i64 = x },
25965 .big_int => |big_int| .{ .big_int = .{
25966 .limbs = try sema.arena.dupe(std.math.big.Limb, big_int.limbs),
25967 .positive = big_int.positive,
25968 } },
25969 };
25970 const new_val = try mod.intern(.{ .int = .{
25971 .ty = dest_ty.ip_index,
25972 .storage = int_storage,
25973 } });
25974 return try sema.addConstant(dest_ty, new_val.toValue());
2596125975 }
2596225976 if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
2596325977 if (!opts.report_err) return error.NotCoercible;
......@@ -31061,39 +31075,42 @@ pub fn resolveFnTypes(sema: *Sema, fn_info: Type.Payload.Function.Data) CompileE
3106131075/// Make it so that calling hash() and eql() on `val` will not assert due
3106231076/// to a type not having its layout resolved.
3106331077fn resolveLazyValue(sema: *Sema, val: Value) CompileError!void {
31064 switch (val.tag()) {
31065 .lazy_align => {
31066 const ty = val.castTag(.lazy_align).?.data;
31067 return sema.resolveTypeLayout(ty);
31068 },
31069 .lazy_size => {
31070 const ty = val.castTag(.lazy_size).?.data;
31071 return sema.resolveTypeLayout(ty);
31072 },
31073 .comptime_field_ptr => {
31074 const field_ptr = val.castTag(.comptime_field_ptr).?.data;
31075 return sema.resolveLazyValue(field_ptr.field_val);
31076 },
31077 .eu_payload,
31078 .opt_payload,
31079 => {
31080 const sub_val = val.cast(Value.Payload.SubValue).?.data;
31081 return sema.resolveLazyValue(sub_val);
31082 },
31083 .@"union" => {
31084 const union_val = val.castTag(.@"union").?.data;
31085 return sema.resolveLazyValue(union_val.val);
31086 },
31087 .aggregate => {
31088 const aggregate = val.castTag(.aggregate).?.data;
31089 for (aggregate) |elem_val| {
31090 try sema.resolveLazyValue(elem_val);
31091 }
31092 },
31093 .slice => {
31094 const slice = val.castTag(.slice).?.data;
31095 try sema.resolveLazyValue(slice.ptr);
31096 return sema.resolveLazyValue(slice.len);
31078 switch (val.ip_index) {
31079 .none => switch (val.tag()) {
31080 .lazy_align => {
31081 const ty = val.castTag(.lazy_align).?.data;
31082 return sema.resolveTypeLayout(ty);
31083 },
31084 .lazy_size => {
31085 const ty = val.castTag(.lazy_size).?.data;
31086 return sema.resolveTypeLayout(ty);
31087 },
31088 .comptime_field_ptr => {
31089 const field_ptr = val.castTag(.comptime_field_ptr).?.data;
31090 return sema.resolveLazyValue(field_ptr.field_val);
31091 },
31092 .eu_payload,
31093 .opt_payload,
31094 => {
31095 const sub_val = val.cast(Value.Payload.SubValue).?.data;
31096 return sema.resolveLazyValue(sub_val);
31097 },
31098 .@"union" => {
31099 const union_val = val.castTag(.@"union").?.data;
31100 return sema.resolveLazyValue(union_val.val);
31101 },
31102 .aggregate => {
31103 const aggregate = val.castTag(.aggregate).?.data;
31104 for (aggregate) |elem_val| {
31105 try sema.resolveLazyValue(elem_val);
31106 }
31107 },
31108 .slice => {
31109 const slice = val.castTag(.slice).?.data;
31110 try sema.resolveLazyValue(slice.ptr);
31111 return sema.resolveLazyValue(slice.len);
31112 },
31113 else => return,
3109731114 },
3109831115 else => return,
3109931116 }
......@@ -31200,7 +31217,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3120031217 };
3120131218
3120231219 for (struct_obj.fields.values(), 0..) |field, i| {
31203 optimized_order[i] = if (!(try sema.typeHasRuntimeBits(field.ty)))
31220 optimized_order[i] = if (try sema.typeHasRuntimeBits(field.ty))
3120431221 @intCast(u32, i)
3120531222 else
3120631223 Module.Struct.omitted_field;
src/codegen/llvm.zig+1-1
......@@ -2481,7 +2481,7 @@ pub const DeclGen = struct {
24812481 log.debug("gen: {s} type: {}, value: {}", .{
24822482 decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(),
24832483 });
2484 assert(decl.val.tag() != .function);
2484 assert(decl.val.ip_index != .none or decl.val.tag() != .function);
24852485 if (decl.val.castTag(.extern_fn)) |extern_fn| {
24862486 _ = try dg.resolveLlvmFunction(extern_fn.data.owner_decl);
24872487 } else {
src/type.zig+82-39
......@@ -2471,7 +2471,7 @@ pub const Type = struct {
24712471 pub fn lazyAbiSize(ty: Type, mod: *Module, arena: Allocator) !Value {
24722472 switch (try ty.abiSizeAdvanced(mod, .{ .lazy = arena })) {
24732473 .val => |val| return val,
2474 .scalar => |x| return mod.intValue(ty, x),
2474 .scalar => |x| return mod.intValue(Type.comptime_int, x),
24752475 }
24762476 }
24772477
......@@ -2504,8 +2504,20 @@ pub const Type = struct {
25042504 if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 };
25052505 return AbiSizeAdvanced{ .scalar = intAbiSize(int_type.bits, target) };
25062506 },
2507 .ptr_type => @panic("TODO"),
2508 .array_type => @panic("TODO"),
2507 .ptr_type => |ptr_type| switch (ptr_type.size) {
2508 .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },
2509 else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },
2510 },
2511 .array_type => |array_type| {
2512 const len = array_type.len + @boolToInt(array_type.sentinel != .none);
2513 switch (try array_type.child.toType().abiSizeAdvanced(mod, strat)) {
2514 .scalar => |elem_size| return .{ .scalar = len * elem_size },
2515 .val => switch (strat) {
2516 .sema, .eager => unreachable,
2517 .lazy => |arena| return .{ .val = try Value.Tag.lazy_size.create(arena, ty) },
2518 },
2519 }
2520 },
25092521 .vector_type => |vector_type| {
25102522 const opt_sema = switch (strat) {
25112523 .sema => |sema| sema,
......@@ -2528,7 +2540,7 @@ pub const Type = struct {
25282540 return AbiSizeAdvanced{ .scalar = result };
25292541 },
25302542
2531 .opt_type => @panic("TODO"),
2543 .opt_type => return ty.abiSizeAdvancedOptional(mod, strat),
25322544 .error_union_type => @panic("TODO"),
25332545 .simple_type => |t| switch (t) {
25342546 .bool,
......@@ -2698,39 +2710,7 @@ pub const Type = struct {
26982710 .error_set_single,
26992711 => return AbiSizeAdvanced{ .scalar = 2 },
27002712
2701 .optional => {
2702 const child_type = ty.optionalChild(mod);
2703
2704 if (child_type.isNoReturn()) {
2705 return AbiSizeAdvanced{ .scalar = 0 };
2706 }
2707
2708 if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2709 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
2710 else => |e| return e,
2711 })) return AbiSizeAdvanced{ .scalar = 1 };
2712
2713 if (ty.optionalReprIsPayload(mod)) {
2714 return abiSizeAdvanced(child_type, mod, strat);
2715 }
2716
2717 const payload_size = switch (try child_type.abiSizeAdvanced(mod, strat)) {
2718 .scalar => |elem_size| elem_size,
2719 .val => switch (strat) {
2720 .sema => unreachable,
2721 .eager => unreachable,
2722 .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
2723 },
2724 };
2725
2726 // Optional types are represented as a struct with the child type as the first
2727 // field and a boolean as the second. Since the child type's abi alignment is
2728 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
2729 // to the child type's ABI alignment.
2730 return AbiSizeAdvanced{
2731 .scalar = child_type.abiAlignment(mod) + payload_size,
2732 };
2733 },
2713 .optional => return ty.abiSizeAdvancedOptional(mod, strat),
27342714
27352715 .error_union => {
27362716 // This code needs to be kept in sync with the equivalent switch prong
......@@ -2791,6 +2771,44 @@ pub const Type = struct {
27912771 return AbiSizeAdvanced{ .scalar = union_obj.abiSize(mod, have_tag) };
27922772 }
27932773
2774 fn abiSizeAdvancedOptional(
2775 ty: Type,
2776 mod: *const Module,
2777 strat: AbiAlignmentAdvancedStrat,
2778 ) Module.CompileError!AbiSizeAdvanced {
2779 const child_ty = ty.optionalChild(mod);
2780
2781 if (child_ty.isNoReturn()) {
2782 return AbiSizeAdvanced{ .scalar = 0 };
2783 }
2784
2785 if (!(child_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2786 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
2787 else => |e| return e,
2788 })) return AbiSizeAdvanced{ .scalar = 1 };
2789
2790 if (ty.optionalReprIsPayload(mod)) {
2791 return abiSizeAdvanced(child_ty, mod, strat);
2792 }
2793
2794 const payload_size = switch (try child_ty.abiSizeAdvanced(mod, strat)) {
2795 .scalar => |elem_size| elem_size,
2796 .val => switch (strat) {
2797 .sema => unreachable,
2798 .eager => unreachable,
2799 .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
2800 },
2801 };
2802
2803 // Optional types are represented as a struct with the child type as the first
2804 // field and a boolean as the second. Since the child type's abi alignment is
2805 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
2806 // to the child type's ABI alignment.
2807 return AbiSizeAdvanced{
2808 .scalar = child_ty.abiAlignment(mod) + payload_size,
2809 };
2810 }
2811
27942812 fn intAbiSize(bits: u16, target: Target) u64 {
27952813 const alignment = intAbiAlignment(bits, target);
27962814 return std.mem.alignForwardGeneric(u64, @intCast(u16, (@as(u17, bits) + 7) / 8), alignment);
......@@ -2819,8 +2837,19 @@ pub const Type = struct {
28192837
28202838 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
28212839 .int_type => |int_type| return int_type.bits,
2822 .ptr_type => @panic("TODO"),
2823 .array_type => @panic("TODO"),
2840 .ptr_type => |ptr_type| switch (ptr_type.size) {
2841 .Slice => return target.ptrBitWidth() * 2,
2842 else => return target.ptrBitWidth() * 2,
2843 },
2844 .array_type => |array_type| {
2845 const len = array_type.len + @boolToInt(array_type.sentinel != .none);
2846 if (len == 0) return 0;
2847 const elem_ty = array_type.child.toType();
2848 const elem_size = std.math.max(elem_ty.abiAlignment(mod), elem_ty.abiSize(mod));
2849 if (elem_size == 0) return 0;
2850 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, opt_sema);
2851 return (len - 1) * 8 * elem_size + elem_bit_size;
2852 },
28242853 .vector_type => |vector_type| {
28252854 const child_ty = vector_type.child.toType();
28262855 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);
......@@ -3208,6 +3237,20 @@ pub const Type = struct {
32083237
32093238 /// See also `isPtrLikeOptional`.
32103239 pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {
3240 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3241 .opt_type => |child| switch (child.toType().zigTypeTag(mod)) {
3242 .Pointer => {
3243 const info = child.toType().ptrInfo(mod);
3244 switch (info.size) {
3245 .C => return false,
3246 else => return !info.@"allowzero",
3247 }
3248 },
3249 .ErrorSet => true,
3250 else => false,
3251 },
3252 else => false,
3253 };
32113254 switch (ty.tag()) {
32123255 .optional => {
32133256 const child_ty = ty.castTag(.optional).?.data;
src/value.zig+58-50
......@@ -1832,35 +1832,37 @@ pub const Value = struct {
18321832 }
18331833 }
18341834
1835 switch (lhs.tag()) {
1836 .repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvancedExtra(op, mod, opt_sema),
1837 .aggregate => {
1838 for (lhs.castTag(.aggregate).?.data) |elem_val| {
1839 if (!(try elem_val.compareAllWithZeroAdvancedExtra(op, mod, opt_sema))) return false;
1840 }
1841 return true;
1842 },
1843 .empty_array => return true,
1844 .str_lit => {
1845 const str_lit = lhs.castTag(.str_lit).?.data;
1846 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
1847 for (bytes) |byte| {
1848 if (!std.math.compare(byte, op, 0)) return false;
1849 }
1850 return true;
1851 },
1852 .bytes => {
1853 const bytes = lhs.castTag(.bytes).?.data;
1854 for (bytes) |byte| {
1855 if (!std.math.compare(byte, op, 0)) return false;
1856 }
1857 return true;
1835 switch (lhs.ip_index) {
1836 .none => switch (lhs.tag()) {
1837 .repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvancedExtra(op, mod, opt_sema),
1838 .aggregate => {
1839 for (lhs.castTag(.aggregate).?.data) |elem_val| {
1840 if (!(try elem_val.compareAllWithZeroAdvancedExtra(op, mod, opt_sema))) return false;
1841 }
1842 return true;
1843 },
1844 .str_lit => {
1845 const str_lit = lhs.castTag(.str_lit).?.data;
1846 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
1847 for (bytes) |byte| {
1848 if (!std.math.compare(byte, op, 0)) return false;
1849 }
1850 return true;
1851 },
1852 .bytes => {
1853 const bytes = lhs.castTag(.bytes).?.data;
1854 for (bytes) |byte| {
1855 if (!std.math.compare(byte, op, 0)) return false;
1856 }
1857 return true;
1858 },
1859 .float_16 => if (std.math.isNan(lhs.castTag(.float_16).?.data)) return op == .neq,
1860 .float_32 => if (std.math.isNan(lhs.castTag(.float_32).?.data)) return op == .neq,
1861 .float_64 => if (std.math.isNan(lhs.castTag(.float_64).?.data)) return op == .neq,
1862 .float_80 => if (std.math.isNan(lhs.castTag(.float_80).?.data)) return op == .neq,
1863 .float_128 => if (std.math.isNan(lhs.castTag(.float_128).?.data)) return op == .neq,
1864 else => {},
18581865 },
1859 .float_16 => if (std.math.isNan(lhs.castTag(.float_16).?.data)) return op == .neq,
1860 .float_32 => if (std.math.isNan(lhs.castTag(.float_32).?.data)) return op == .neq,
1861 .float_64 => if (std.math.isNan(lhs.castTag(.float_64).?.data)) return op == .neq,
1862 .float_80 => if (std.math.isNan(lhs.castTag(.float_80).?.data)) return op == .neq,
1863 .float_128 => if (std.math.isNan(lhs.castTag(.float_128).?.data)) return op == .neq,
18641866 else => {},
18651867 }
18661868 return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op);
......@@ -2404,37 +2406,43 @@ pub const Value = struct {
24042406 };
24052407
24062408 pub fn isComptimeMutablePtr(val: Value) bool {
2407 return switch (val.tag()) {
2408 .decl_ref_mut, .comptime_field_ptr => true,
2409 .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),
2410 .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),
2411 .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),
2412 .opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data.container_ptr),
2413 .slice => isComptimeMutablePtr(val.castTag(.slice).?.data.ptr),
2409 return switch (val.ip_index) {
2410 .none => switch (val.tag()) {
2411 .decl_ref_mut, .comptime_field_ptr => true,
2412 .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),
2413 .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),
2414 .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),
2415 .opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data.container_ptr),
2416 .slice => isComptimeMutablePtr(val.castTag(.slice).?.data.ptr),
24142417
2418 else => false,
2419 },
24152420 else => false,
24162421 };
24172422 }
24182423
24192424 pub fn canMutateComptimeVarState(val: Value) bool {
24202425 if (val.isComptimeMutablePtr()) return true;
2421 switch (val.tag()) {
2422 .repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(),
2423 .eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(),
2424 .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
2425 .opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(),
2426 .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
2427 .aggregate => {
2428 const fields = val.castTag(.aggregate).?.data;
2429 for (fields) |field| {
2430 if (field.canMutateComptimeVarState()) return true;
2431 }
2432 return false;
2426 return switch (val.ip_index) {
2427 .none => switch (val.tag()) {
2428 .repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(),
2429 .eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(),
2430 .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
2431 .opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(),
2432 .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
2433 .aggregate => {
2434 const fields = val.castTag(.aggregate).?.data;
2435 for (fields) |field| {
2436 if (field.canMutateComptimeVarState()) return true;
2437 }
2438 return false;
2439 },
2440 .@"union" => return val.cast(Payload.Union).?.data.val.canMutateComptimeVarState(),
2441 .slice => return val.castTag(.slice).?.data.ptr.canMutateComptimeVarState(),
2442 else => return false,
24332443 },
2434 .@"union" => return val.cast(Payload.Union).?.data.val.canMutateComptimeVarState(),
2435 .slice => return val.castTag(.slice).?.data.ptr.canMutateComptimeVarState(),
24362444 else => return false,
2437 }
2445 };
24382446 }
24392447
24402448 /// Gets the decl referenced by this pointer. If the pointer does not point