mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
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.
This commit is contained in:
parent
cc89908e82
commit
94039d66ed
@ -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;
|
||||
|
||||
|
||||
22
src/type.zig
22
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);
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
const T = struct {
|
||||
comptime a: u32 = 2,
|
||||
};
|
||||
pub export fn entry1() void {
|
||||
@offsetOf(T, "a");
|
||||
}
|
||||
pub export fn entry2() void {
|
||||
@fieldParentPtr(T, "a", undefined);
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :5:5: error: no offset available for comptime field
|
||||
// :8:5: error: cannot get @fieldParentPtr of a comptime field
|
||||
Loading…
x
Reference in New Issue
Block a user