aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig11
-rw-r--r--src/Module.zig2
-rw-r--r--src/Sema.zig73
-rw-r--r--src/TypedValue.zig11
-rw-r--r--src/Zir.zig5
-rw-r--r--src/type.zig20
-rw-r--r--src/value.zig54
7 files changed, 152 insertions, 24 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index ab5befa4ba..3566610bb6 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -291,8 +291,8 @@ pub const ResultLoc = union(enum) {
}
};
-pub const align_rl: ResultLoc = .{ .ty = .u16_type };
-pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u16_type };
+pub const align_rl: ResultLoc = .{ .ty = .u29_type };
+pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u29_type };
pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
pub const type_rl: ResultLoc = .{ .ty = .type_type };
pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };
@@ -8077,6 +8077,7 @@ const primitives = std.ComptimeStringMap(Zir.Inst.Ref, .{
.{ "true", .bool_true },
.{ "type", .type_type },
.{ "u16", .u16_type },
+ .{ "u29", .u29_type },
.{ "u32", .u32_type },
.{ "u64", .u64_type },
.{ "u128", .u128_type },
@@ -8749,6 +8750,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In
.isize_type,
.type_type,
.u16_type,
+ .u29_type,
.u32_type,
.u64_type,
.u128_type,
@@ -8988,6 +8990,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
.i8_type,
.isize_type,
.u16_type,
+ .u29_type,
.u32_type,
.u64_type,
.u128_type,
@@ -9063,6 +9066,7 @@ fn rvalue(
as_ty | @enumToInt(Zir.Inst.Ref.u8_type),
as_ty | @enumToInt(Zir.Inst.Ref.i8_type),
as_ty | @enumToInt(Zir.Inst.Ref.u16_type),
+ as_ty | @enumToInt(Zir.Inst.Ref.u29_type),
as_ty | @enumToInt(Zir.Inst.Ref.i16_type),
as_ty | @enumToInt(Zir.Inst.Ref.u32_type),
as_ty | @enumToInt(Zir.Inst.Ref.i32_type),
@@ -9875,6 +9879,9 @@ const GenZir = struct {
errdefer as_scope.unstack();
as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);
+ // `rl_ty_inst` needs to be set in case the stores to `rl_ptr` are eliminated.
+ as_scope.rl_ty_inst = dest_type;
+
return as_scope;
}
diff --git a/src/Module.zig b/src/Module.zig
index f8d662ae1f..12d311046a 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -4016,7 +4016,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
try wip_captures.finalize();
const src: LazySrcLoc = .{ .node_offset = 0 };
const decl_tv = try sema.resolveInstValue(&block_scope, src, result_ref);
- const decl_align: u16 = blk: {
+ const decl_align: u32 = blk: {
const align_ref = decl.zirAlignRef();
if (align_ref == .none) break :blk 0;
break :blk try sema.resolveAlign(&block_scope, src, align_ref);
diff --git a/src/Sema.zig b/src/Sema.zig
index 593b299833..381f922093 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -1739,9 +1739,9 @@ pub fn resolveAlign(
block: *Block,
src: LazySrcLoc,
zir_ref: Zir.Inst.Ref,
-) !u16 {
- const alignment_big = try sema.resolveInt(block, src, zir_ref, Type.initTag(.u16));
- const alignment = @intCast(u16, alignment_big); // We coerce to u16 in the prev line.
+) !u32 {
+ const alignment_big = try sema.resolveInt(block, src, zir_ref, Type.initTag(.u29));
+ const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line.
if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{});
if (!std.math.isPowerOfTwo(alignment)) {
return sema.fail(block, src, "alignment value {d} is not a power of two", .{
@@ -1875,7 +1875,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));
const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value);
- try sema.storePtr(&trash_block, src, dummy_ptr, dummy_operand);
+ try sema.storePtr2(&trash_block, src, dummy_ptr, src, dummy_operand, src, .bitcast);
{
const air_tags = sema.air_instructions.items(.tag);
@@ -2526,7 +2526,7 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
const src: LazySrcLoc = .{ .node_offset = inst_data };
try sema.requireFunctionBlock(block, src);
- if (block.is_comptime) {
+ if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {
const fn_ret_ty = try sema.resolveTypeFields(block, src, sema.fn_ret_ty);
return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0, src);
}
@@ -2663,7 +2663,7 @@ fn zirAllocExtended(
break :blk try sema.resolveType(block, ty_src, type_ref);
} else undefined;
- const alignment: u16 = if (small.has_align) blk: {
+ const alignment: u32 = if (small.has_align) blk: {
const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
const alignment = try sema.resolveAlign(block, align_src, align_ref);
@@ -3616,7 +3616,7 @@ fn zirValidateArrayInit(
const air_tags = sema.air_instructions.items(.tag);
const air_datas = sema.air_instructions.items(.data);
- for (instrs) |elem_ptr, i| {
+ outer: for (instrs) |elem_ptr, i| {
const elem_ptr_data = sema.code.instructions.items(.data)[elem_ptr].pl_node;
const elem_src: LazySrcLoc = .{ .node_offset = elem_ptr_data.src_node };
@@ -3630,6 +3630,10 @@ fn zirValidateArrayInit(
// of the for loop.
var block_index = block.instructions.items.len - 1;
while (block.instructions.items[block_index] != elem_ptr_air_inst) {
+ if (block_index == 0) {
+ array_is_comptime = true;
+ continue :outer;
+ }
block_index -= 1;
}
first_block_index = @minimum(first_block_index, block_index);
@@ -3672,6 +3676,13 @@ fn zirValidateArrayInit(
}
if (array_is_comptime) {
+ if (try sema.resolveDefinedValue(block, init_src, array_ptr)) |ptr_val| {
+ if (ptr_val.tag() == .comptime_field_ptr) {
+ // This store was validated by the individual elem ptrs.
+ return;
+ }
+ }
+
// Our task is to delete all the `elem_ptr` and `store` instructions, and insert
// instead a single `store` to the array_ptr with a comptime struct value.
// Also to populate the sentinel value, if any.
@@ -14199,7 +14210,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
.size = ptr_size,
.mutable = !is_const_val.toBool(),
.@"volatile" = is_volatile_val.toBool(),
- .@"align" = @intCast(u16, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
+ .@"align" = @intCast(u29, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
.@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
.pointee_type = try child_ty.copy(sema.arena),
.@"allowzero" = is_allowzero_val.toBool(),
@@ -16973,7 +16984,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const body = sema.code.extra[extra_index..][0..body_len];
extra_index += body.len;
- const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u16);
+ const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29);
if (val.tag() == .generic_poison) {
break :blk null;
}
@@ -18462,14 +18473,11 @@ fn structFieldPtrByIndex(
const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
if (field.is_comptime) {
- var anon_decl = try block.startAnonDecl(field_src);
- defer anon_decl.deinit();
- const decl = try anon_decl.finish(
- try field.ty.copy(anon_decl.arena()),
- try field.default_val.copy(anon_decl.arena()),
- ptr_ty_data.@"align",
- );
- return sema.analyzeDeclRef(decl);
+ const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
+ .field_ty = try field.ty.copy(sema.arena),
+ .field_val = try field.default_val.copy(sema.arena),
+ });
+ return sema.addConstant(ptr_field_ty, val);
}
if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
@@ -20187,6 +20195,13 @@ fn storePtr2(
// TODO handle if the element type requires comptime
+ if (air_tag == .bitcast) {
+ // `air_tag == .bitcast` is used as a special case for `zirCoerceResultPtr`
+ // to avoid calling `requireRuntimeBlock` for the dummy block.
+ _ = try block.addBinOp(.store, ptr, operand);
+ return;
+ }
+
try sema.requireRuntimeBlock(block, runtime_src);
try sema.queueFullTypeResolution(elem_ty);
_ = try block.addBinOp(air_tag, ptr, operand);
@@ -20240,6 +20255,14 @@ fn storePtrVal(
const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);
+ if (mut_kit.decl_ref_mut.runtime_index == std.math.maxInt(u32)) {
+ // Special case for comptime field ptr.
+ if (!mut_kit.val.eql(bitcasted_val, mut_kit.ty, sema.mod)) {
+ return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{});
+ }
+ return;
+ }
+
const arena = mut_kit.beginArena(sema.mod);
defer mut_kit.finishArena(sema.mod);
@@ -20289,6 +20312,19 @@ fn beginComptimePtrMutation(
.ty = decl.ty,
};
},
+ .comptime_field_ptr => {
+ const payload = ptr_val.castTag(.comptime_field_ptr).?.data;
+ const duped = try sema.arena.create(Value);
+ duped.* = payload.field_val;
+ return ComptimePtrMutationKit{
+ .decl_ref_mut = .{
+ .decl_index = @intToEnum(Module.Decl.Index, 0),
+ .runtime_index = std.math.maxInt(u32),
+ },
+ .val = duped,
+ .ty = payload.field_ty,
+ };
+ },
.elem_ptr => {
const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
var parent = try beginComptimePtrMutation(sema, block, src, elem_ptr.array_ptr);
@@ -23850,6 +23886,7 @@ pub fn typeHasOnePossibleValue(
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -24143,6 +24180,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
.u8 => return .u8_type,
.i8 => return .i8_type,
.u16 => return .u16_type,
+ .u29 => return .u29_type,
.i16 => return .i16_type,
.u32 => return .u32_type,
.i32 => return .i32_type,
@@ -24513,6 +24551,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
diff --git a/src/TypedValue.zig b/src/TypedValue.zig
index 9f69e4c8bd..4b3bc23231 100644
--- a/src/TypedValue.zig
+++ b/src/TypedValue.zig
@@ -79,6 +79,7 @@ pub fn print(
.i8_type => return writer.writeAll("i8"),
.u16_type => return writer.writeAll("u16"),
.i16_type => return writer.writeAll("i16"),
+ .u29_type => return writer.writeAll("u29"),
.u32_type => return writer.writeAll("u32"),
.i32_type => return writer.writeAll("i32"),
.u64_type => return writer.writeAll("u64"),
@@ -264,6 +265,16 @@ pub fn print(
.val = decl.val,
}, writer, level - 1, mod);
},
+ .comptime_field_ptr => {
+ const payload = val.castTag(.comptime_field_ptr).?.data;
+ if (level == 0) {
+ return writer.writeAll("(comptime field ptr)");
+ }
+ return print(.{
+ .ty = payload.field_ty,
+ .val = payload.field_val,
+ }, writer, level - 1, mod);
+ },
.elem_ptr => {
const elem_ptr = val.castTag(.elem_ptr).?.data;
try writer.writeAll("&");
diff --git a/src/Zir.zig b/src/Zir.zig
index f09f2015e0..9f1737d19d 100644
--- a/src/Zir.zig
+++ b/src/Zir.zig
@@ -1961,6 +1961,7 @@ pub const Inst = struct {
i8_type,
u16_type,
i16_type,
+ u29_type,
u32_type,
i32_type,
u64_type,
@@ -2072,6 +2073,10 @@ pub const Inst = struct {
.ty = Type.initTag(.type),
.val = Value.initTag(.i16_type),
},
+ .u29_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.u29_type),
+ },
.u32_type = .{
.ty = Type.initTag(.type),
.val = Value.initTag(.u32_type),
diff --git a/src/type.zig b/src/type.zig
index ee669df620..14c613a947 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -36,6 +36,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -568,6 +569,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -979,6 +981,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -1261,6 +1264,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -1551,6 +1555,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -1935,6 +1940,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -2235,6 +2241,7 @@ pub const Type = extern union {
.u8 => return Value.initTag(.u8_type),
.i8 => return Value.initTag(.i8_type),
.u16 => return Value.initTag(.u16_type),
+ .u29 => return Value.initTag(.u29_type),
.i16 => return Value.initTag(.i16_type),
.u32 => return Value.initTag(.u32_type),
.i32 => return Value.initTag(.i32_type),
@@ -2312,6 +2319,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -2560,6 +2568,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -2953,6 +2962,7 @@ pub const Type = extern union {
.vector => return AbiAlignmentAdvanced{ .scalar = 16 },
.i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) },
+ .u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) },
.i32, .u32 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(32, target) },
.i64, .u64 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(64, target) },
.u128, .i128 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(128, target) },
@@ -3416,6 +3426,7 @@ pub const Type = extern union {
},
.i16, .u16 => return AbiSizeAdvanced{ .scalar = intAbiSize(16, target) },
+ .u29 => return AbiSizeAdvanced{ .scalar = intAbiSize(29, target) },
.i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },
.i64, .u64 => return AbiSizeAdvanced{ .scalar = intAbiSize(64, target) },
.u128, .i128 => return AbiSizeAdvanced{ .scalar = intAbiSize(128, target) },
@@ -3569,6 +3580,7 @@ pub const Type = extern union {
.bool, .u1 => 1,
.u8, .i8 => 8,
.i16, .u16, .f16 => 16,
+ .u29 => 29,
.i32, .u32, .f32 => 32,
.i64, .u64, .f64 => 64,
.f80 => 80,
@@ -4524,6 +4536,7 @@ pub const Type = extern union {
.u1,
.u8,
.u16,
+ .u29,
.u32,
.u64,
.u128,
@@ -4550,6 +4563,7 @@ pub const Type = extern union {
.i8 => return .{ .signedness = .signed, .bits = 8 },
.u16 => return .{ .signedness = .unsigned, .bits = 16 },
.i16 => return .{ .signedness = .signed, .bits = 16 },
+ .u29 => return .{ .signedness = .unsigned, .bits = 29 },
.u32 => return .{ .signedness = .unsigned, .bits = 32 },
.i32 => return .{ .signedness = .signed, .bits = 32 },
.u64 => return .{ .signedness = .unsigned, .bits = 64 },
@@ -4814,6 +4828,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -4856,6 +4871,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -5072,6 +5088,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -5816,6 +5833,7 @@ pub const Type = extern union {
i8,
u16,
i16,
+ u29,
u32,
i32,
u64,
@@ -5939,6 +5957,7 @@ pub const Type = extern union {
.i8,
.u16,
.i16,
+ .u29,
.u32,
.i32,
.u64,
@@ -6302,6 +6321,7 @@ pub const Type = extern union {
pub const @"u1" = initTag(.u1);
pub const @"u8" = initTag(.u8);
pub const @"u16" = initTag(.u16);
+ pub const @"u29" = initTag(.u29);
pub const @"u32" = initTag(.u32);
pub const @"u64" = initTag(.u64);
diff --git a/src/value.zig b/src/value.zig
index a80d788894..21fe52e706 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -30,6 +30,7 @@ pub const Value = extern union {
i8_type,
u16_type,
i16_type,
+ u29_type,
u32_type,
i32_type,
u64_type,
@@ -120,6 +121,8 @@ pub const Value = extern union {
/// This Tag will never be seen by machine codegen backends. It is changed into a
/// `decl_ref` when a comptime variable goes out of scope.
decl_ref_mut,
+ /// Behaves like `decl_ref_mut` but validates that the stored value matches the field value.
+ comptime_field_ptr,
/// Pointer to a specific element of an array, vector or slice.
elem_ptr,
/// Pointer to a specific field of a struct or union.
@@ -194,6 +197,7 @@ pub const Value = extern union {
.i8_type,
.u16_type,
.i16_type,
+ .u29_type,
.u32_type,
.i32_type,
.u64_type,
@@ -316,6 +320,7 @@ pub const Value = extern union {
.aggregate => Payload.Aggregate,
.@"union" => Payload.Union,
.bound_fn => Payload.BoundFn,
+ .comptime_field_ptr => Payload.ComptimeFieldPtr,
};
}
@@ -394,6 +399,7 @@ pub const Value = extern union {
.i8_type,
.u16_type,
.i16_type,
+ .u29_type,
.u32_type,
.i32_type,
.u64_type,
@@ -506,6 +512,18 @@ pub const Value = extern union {
};
return Value{ .ptr_otherwise = &new_payload.base };
},
+ .comptime_field_ptr => {
+ const payload = self.cast(Payload.ComptimeFieldPtr).?;
+ const new_payload = try arena.create(Payload.ComptimeFieldPtr);
+ new_payload.* = .{
+ .base = payload.base,
+ .data = .{
+ .field_val = try payload.data.field_val.copy(arena),
+ .field_ty = try payload.data.field_ty.copy(arena),
+ },
+ };
+ return Value{ .ptr_otherwise = &new_payload.base };
+ },
.elem_ptr => {
const payload = self.castTag(.elem_ptr).?;
const new_payload = try arena.create(Payload.ElemPtr);
@@ -645,6 +663,7 @@ pub const Value = extern union {
.u8_type => return out_stream.writeAll("u8"),
.i8_type => return out_stream.writeAll("i8"),
.u16_type => return out_stream.writeAll("u16"),
+ .u29_type => return out_stream.writeAll("u29"),
.i16_type => return out_stream.writeAll("i16"),
.u32_type => return out_stream.writeAll("u32"),
.i32_type => return out_stream.writeAll("i32"),
@@ -754,6 +773,9 @@ pub const Value = extern union {
const decl_index = val.castTag(.decl_ref).?.data;
return out_stream.print("(decl_ref {d})", .{decl_index});
},
+ .comptime_field_ptr => {
+ return out_stream.writeAll("(comptime_field_ptr)");
+ },
.elem_ptr => {
const elem_ptr = val.castTag(.elem_ptr).?.data;
try out_stream.print("&[{}] ", .{elem_ptr.index});
@@ -882,6 +904,7 @@ pub const Value = extern union {
.i8_type => Type.initTag(.i8),
.u16_type => Type.initTag(.u16),
.i16_type => Type.initTag(.i16),
+ .u29_type => Type.initTag(.u29),
.u32_type => Type.initTag(.u32),
.i32_type => Type.initTag(.i32),
.u64_type => Type.initTag(.u64),
@@ -1706,6 +1729,7 @@ pub const Value = extern union {
.int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
.decl_ref_mut,
+ .comptime_field_ptr,
.extern_fn,
.decl_ref,
.function,
@@ -1770,6 +1794,7 @@ pub const Value = extern union {
.bool_true,
.decl_ref,
.decl_ref_mut,
+ .comptime_field_ptr,
.extern_fn,
.function,
.variable,
@@ -2362,7 +2387,7 @@ pub const Value = extern union {
pub fn isComptimeMutablePtr(val: Value) bool {
return switch (val.tag()) {
- .decl_ref_mut => true,
+ .decl_ref_mut, .comptime_field_ptr => true,
.elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),
.field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),
.eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),
@@ -2426,6 +2451,9 @@ pub const Value = extern union {
const decl: Module.Decl.Index = ptr_val.pointerDecl().?;
std.hash.autoHash(hasher, decl);
},
+ .comptime_field_ptr => {
+ std.hash.autoHash(hasher, Value.Tag.comptime_field_ptr);
+ },
.elem_ptr => {
const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
@@ -2471,7 +2499,7 @@ pub const Value = extern union {
return switch (val.tag()) {
.slice => val.castTag(.slice).?.data.ptr,
// TODO this should require being a slice tag, and not allow decl_ref, field_ptr, etc.
- .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr => val,
+ .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr, .comptime_field_ptr => val,
else => unreachable,
};
}
@@ -2497,6 +2525,14 @@ pub const Value = extern union {
return 1;
}
},
+ .comptime_field_ptr => {
+ const payload = val.castTag(.comptime_field_ptr).?.data;
+ if (payload.field_ty.zigTypeTag() == .Array) {
+ return payload.field_ty.arrayLen();
+ } else {
+ return 1;
+ }
+ },
else => unreachable,
};
}
@@ -2587,6 +2623,7 @@ pub const Value = extern union {
.decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer),
.decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer),
+ .comptime_field_ptr => return val.castTag(.comptime_field_ptr).?.data.field_val.elemValueAdvanced(mod, index, arena, buffer),
.elem_ptr => {
const data = val.castTag(.elem_ptr).?.data;
return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer);
@@ -2623,6 +2660,7 @@ pub const Value = extern union {
.decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end),
.decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end),
+ .comptime_field_ptr => sliceArray(val.castTag(.comptime_field_ptr).?.data.field_val, mod, arena, start, end),
.elem_ptr => blk: {
const elem_ptr = val.castTag(.elem_ptr).?.data;
break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index);
@@ -4742,6 +4780,14 @@ pub const Value = extern union {
},
};
+ pub const ComptimeFieldPtr = struct {
+ base: Payload,
+ data: struct {
+ field_val: Value,
+ field_ty: Type,
+ },
+ };
+
pub const ElemPtr = struct {
pub const base_tag = Tag.elem_ptr;
@@ -4864,7 +4910,7 @@ pub const Value = extern union {
/// `Module.resolvePeerTypes`.
stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},
/// 0 means ABI-aligned.
- alignment: u16,
+ alignment: u32,
},
};
@@ -4875,7 +4921,7 @@ pub const Value = extern union {
data: struct {
decl_index: Module.Decl.Index,
/// 0 means ABI-aligned.
- alignment: u16,
+ alignment: u32,
},
};