aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-10-05 15:06:14 +0300
committerVeikka Tuominen <git@vexu.eu>2022-10-06 20:09:45 +0300
commit94039d66ed4fecb7defc5deeeedd7afa3b773f0c (patch)
tree59e0c2a2033972bdf2ba22a76db7b1236a82dcc5 /src
parentcc89908e826882065eeaa23bb8827fb7d7cd6219 (diff)
downloadzig-94039d66ed4fecb7defc5deeeedd7afa3b773f0c.tar.gz
zig-94039d66ed4fecb7defc5deeeedd7afa3b773f0c.zip
Sema: disallow fieldParentPtr and offsetOf on comptime fields
Comptime fields are tied to the type and behave more like declarations so these operations cannot return anything useful for them.
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig8
-rw-r--r--src/type.zig22
2 files changed, 30 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 7b9f7da769..f2b3cee3e3 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -18749,6 +18749,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src);
} else try sema.structFieldIndex(block, ty, field_name, rhs_src);
+ if (ty.structFieldIsComptime(field_index)) {
+ return sema.fail(block, src, "no offset available for comptime field", .{});
+ }
+
switch (ty.containerLayout()) {
.Packed => {
var bit_sum: u64 = 0;
@@ -20132,6 +20136,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
break :blk try sema.tupleFieldIndex(block, struct_ty, field_name, name_src);
} else try sema.structFieldIndex(block, struct_ty, field_name, name_src);
+ if (struct_ty.structFieldIsComptime(field_index)) {
+ return sema.fail(block, src, "cannot get @fieldParentPtr of a comptime field", .{});
+ }
+
try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);
const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
diff --git a/src/type.zig b/src/type.zig
index 1fef525062..7c35eccbe6 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -5664,6 +5664,28 @@ pub const Type = extern union {
}
}
+ pub fn structFieldIsComptime(ty: Type, index: usize) bool {
+ switch (ty.tag()) {
+ .@"struct" => {
+ const struct_obj = ty.castTag(.@"struct").?.data;
+ if (struct_obj.layout == .Packed) return false;
+ const field = struct_obj.fields.values()[index];
+ return field.is_comptime;
+ },
+ .tuple => {
+ const tuple = ty.castTag(.tuple).?.data;
+ const val = tuple.values[index];
+ return val.tag() != .unreachable_value;
+ },
+ .anon_struct => {
+ const anon_struct = ty.castTag(.anon_struct).?.data;
+ const val = anon_struct.values[index];
+ return val.tag() != .unreachable_value;
+ },
+ else => unreachable,
+ }
+ }
+
pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, target: Target) u32 {
const struct_obj = ty.castTag(.@"struct").?.data;
assert(struct_obj.layout == .Packed);