authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-04-20 00:55:52+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-20 09:05:22-07:00
logd5f1a8823eb964c6149fc1d627ea6936d70ea7f1
tree163967d4c1bac8455b0d3e66734d5788a3f1e6d4
parent31b6d14bf76fa6b78013a6a32d3066e882d64043

Sema: allow ptr field access on pointer-to-array

Also remove an incorrect piece of logic which allowed fetching the 'len' property on non-single-ptrs (e.g. many-ptrs) and add a corresponding compile error test case. Resolves: #4765

3 files changed, 36 insertions(+), 14 deletions(-)

src/Sema.zig+16-14
......@@ -23279,6 +23279,22 @@ fn fieldVal(
2327923279 Type.usize,
2328023280 try Value.Tag.int_u64.create(arena, inner_ty.arrayLen()),
2328123281 );
23282 } else if (mem.eql(u8, field_name, "ptr") and is_pointer_to) {
23283 const ptr_info = object_ty.ptrInfo().data;
23284 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
23285 .pointee_type = ptr_info.pointee_type.childType(),
23286 .sentinel = ptr_info.sentinel,
23287 .@"align" = ptr_info.@"align",
23288 .@"addrspace" = ptr_info.@"addrspace",
23289 .bit_offset = ptr_info.bit_offset,
23290 .host_size = ptr_info.host_size,
23291 .vector_index = ptr_info.vector_index,
23292 .@"allowzero" = ptr_info.@"allowzero",
23293 .mutable = ptr_info.mutable,
23294 .@"volatile" = ptr_info.@"volatile",
23295 .size = .Many,
23296 });
23297 return sema.coerce(block, result_ty, object, src);
2328223298 } else {
2328323299 return sema.fail(
2328423300 block,
......@@ -23311,20 +23327,6 @@ fn fieldVal(
2331123327 .{ field_name, object_ty.fmt(sema.mod) },
2331223328 );
2331323329 }
23314 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
23315 if (mem.eql(u8, field_name, "len")) {
23316 return sema.addConstant(
23317 Type.usize,
23318 try Value.Tag.int_u64.create(arena, ptr_info.pointee_type.arrayLen()),
23319 );
23320 } else {
23321 return sema.fail(
23322 block,
23323 field_name_src,
23324 "no member named '{s}' in '{}'",
23325 .{ field_name, ptr_info.pointee_type.fmt(sema.mod) },
23326 );
23327 }
2332823330 }
2332923331 },
2333023332 .Type => {
test/behavior/array.zig+10
......@@ -677,3 +677,13 @@ test "array of array agregate init" {
677677 var b = [1][10]u32{a} ** 2;
678678 try std.testing.expect(b[1][1] == 11);
679679}
680
681test "pointer to array has ptr field" {
682 const arr: *const [5]u32 = &.{ 10, 20, 30, 40, 50 };
683 try std.testing.expect(arr.ptr == @as([*]const u32, arr));
684 try std.testing.expect(arr.ptr[0] == 10);
685 try std.testing.expect(arr.ptr[1] == 20);
686 try std.testing.expect(arr.ptr[2] == 30);
687 try std.testing.expect(arr.ptr[3] == 40);
688 try std.testing.expect(arr.ptr[4] == 50);
689}
test/cases/compile_errors/len_access_on_array_many_ptr.zig created+10
......@@ -0,0 +1,10 @@
1export fn foo() void {
2 const x: [*][5]u8 = undefined;
3 _ = x.len;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :3:10: error: type '[*][5]u8' does not support field access