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
This commit is contained in:
mlugg
2023-04-20 00:55:52 +01:00
committed by Andrew Kelley
parent 31b6d14bf7
commit d5f1a8823e
3 changed files with 36 additions and 14 deletions

View File

@@ -23279,6 +23279,22 @@ fn fieldVal(
Type.usize,
try Value.Tag.int_u64.create(arena, inner_ty.arrayLen()),
);
} else if (mem.eql(u8, field_name, "ptr") and is_pointer_to) {
const ptr_info = object_ty.ptrInfo().data;
const result_ty = try Type.ptr(sema.arena, sema.mod, .{
.pointee_type = ptr_info.pointee_type.childType(),
.sentinel = ptr_info.sentinel,
.@"align" = ptr_info.@"align",
.@"addrspace" = ptr_info.@"addrspace",
.bit_offset = ptr_info.bit_offset,
.host_size = ptr_info.host_size,
.vector_index = ptr_info.vector_index,
.@"allowzero" = ptr_info.@"allowzero",
.mutable = ptr_info.mutable,
.@"volatile" = ptr_info.@"volatile",
.size = .Many,
});
return sema.coerce(block, result_ty, object, src);
} else {
return sema.fail(
block,
@@ -23311,20 +23327,6 @@ fn fieldVal(
.{ field_name, object_ty.fmt(sema.mod) },
);
}
} else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
if (mem.eql(u8, field_name, "len")) {
return sema.addConstant(
Type.usize,
try Value.Tag.int_u64.create(arena, ptr_info.pointee_type.arrayLen()),
);
} else {
return sema.fail(
block,
field_name_src,
"no member named '{s}' in '{}'",
.{ field_name, ptr_info.pointee_type.fmt(sema.mod) },
);
}
}
},
.Type => {

View File

@@ -677,3 +677,13 @@ test "array of array agregate init" {
var b = [1][10]u32{a} ** 2;
try std.testing.expect(b[1][1] == 11);
}
test "pointer to array has ptr field" {
const arr: *const [5]u32 = &.{ 10, 20, 30, 40, 50 };
try std.testing.expect(arr.ptr == @as([*]const u32, arr));
try std.testing.expect(arr.ptr[0] == 10);
try std.testing.expect(arr.ptr[1] == 20);
try std.testing.expect(arr.ptr[2] == 30);
try std.testing.expect(arr.ptr[3] == 40);
try std.testing.expect(arr.ptr[4] == 50);
}

View File

@@ -0,0 +1,10 @@
export fn foo() void {
const x: [*][5]u8 = undefined;
_ = x.len;
}
// error
// backend=stage2
// target=native
//
// :3:10: error: type '[*][5]u8' does not support field access