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:
30
src/Sema.zig
30
src/Sema.zig
@@ -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 => {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
10
test/cases/compile_errors/len_access_on_array_many_ptr.zig
Normal file
10
test/cases/compile_errors/len_access_on_array_many_ptr.zig
Normal 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
|
||||
Reference in New Issue
Block a user