| author | |
| committer | |
| log | 94039d66ed4fecb7defc5deeeedd7afa3b773f0c |
| tree | 59e0c2a2033972bdf2ba22a76db7b1236a82dcc5 |
| parent | cc89908e826882065eeaa23bb8827fb7d7cd6219 |
Comptime fields are tied to the type and behave more like declarations
so these operations cannot return anything useful for them.3 files changed, 46 insertions(+), 0 deletions(-)
src/Sema.zig+8| ... | ... | @@ -18749,6 +18749,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 18749 | 18749 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); |
| 18750 | 18750 | } else try sema.structFieldIndex(block, ty, field_name, rhs_src); |
| 18751 | 18751 | |
| 18752 | if (ty.structFieldIsComptime(field_index)) { | |
| 18753 | return sema.fail(block, src, "no offset available for comptime field", .{}); | |
| 18754 | } | |
| 18755 | ||
| 18752 | 18756 | switch (ty.containerLayout()) { |
| 18753 | 18757 | .Packed => { |
| 18754 | 18758 | var bit_sum: u64 = 0; |
| ... | ... | @@ -20132,6 +20136,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 20132 | 20136 | break :blk try sema.tupleFieldIndex(block, struct_ty, field_name, name_src); |
| 20133 | 20137 | } else try sema.structFieldIndex(block, struct_ty, field_name, name_src); |
| 20134 | 20138 | |
| 20139 | if (struct_ty.structFieldIsComptime(field_index)) { | |
| 20140 | return sema.fail(block, src, "cannot get @fieldParentPtr of a comptime field", .{}); | |
| 20141 | } | |
| 20142 | ||
| 20135 | 20143 | try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); |
| 20136 | 20144 | const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; |
| 20137 | 20145 |
src/type.zig+22| ... | ... | @@ -5664,6 +5664,28 @@ pub const Type = extern union { |
| 5664 | 5664 | } |
| 5665 | 5665 | } |
| 5666 | 5666 | |
| 5667 | pub fn structFieldIsComptime(ty: Type, index: usize) bool { | |
| 5668 | switch (ty.tag()) { | |
| 5669 | .@"struct" => { | |
| 5670 | const struct_obj = ty.castTag(.@"struct").?.data; | |
| 5671 | if (struct_obj.layout == .Packed) return false; | |
| 5672 | const field = struct_obj.fields.values()[index]; | |
| 5673 | return field.is_comptime; | |
| 5674 | }, | |
| 5675 | .tuple => { | |
| 5676 | const tuple = ty.castTag(.tuple).?.data; | |
| 5677 | const val = tuple.values[index]; | |
| 5678 | return val.tag() != .unreachable_value; | |
| 5679 | }, | |
| 5680 | .anon_struct => { | |
| 5681 | const anon_struct = ty.castTag(.anon_struct).?.data; | |
| 5682 | const val = anon_struct.values[index]; | |
| 5683 | return val.tag() != .unreachable_value; | |
| 5684 | }, | |
| 5685 | else => unreachable, | |
| 5686 | } | |
| 5687 | } | |
| 5688 | ||
| 5667 | 5689 | pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, target: Target) u32 { |
| 5668 | 5690 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 5669 | 5691 | assert(struct_obj.layout == .Packed); |
test/cases/compile_errors/fieldParentPtr_on_comptime_field.zig created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | const T = struct { | |
| 2 | comptime a: u32 = 2, | |
| 3 | }; | |
| 4 | pub export fn entry1() void { | |
| 5 | @offsetOf(T, "a"); | |
| 6 | } | |
| 7 | pub export fn entry2() void { | |
| 8 | @fieldParentPtr(T, "a", undefined); | |
| 9 | } | |
| 10 | ||
| 11 | // error | |
| 12 | // backend=stage2 | |
| 13 | // target=native | |
| 14 | // | |
| 15 | // :5:5: error: no offset available for comptime field | |
| 16 | // :8:5: error: cannot get @fieldParentPtr of a comptime field |