Commit 2d443cdabf

Veikka Tuominen <git@vexu.eu>
2024-03-19 15:14:49
Sema: allow .ptr on pointer to array
1 parent fda9a32
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -27256,6 +27256,37 @@ fn fieldPtr(
             if (ip.stringEqlSlice(field_name, "len")) {
                 const int_val = try mod.intValue(Type.usize, inner_ty.arrayLen(mod));
                 return anonDeclRef(sema, int_val.toIntern());
+            } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {
+                const ptr_info = object_ty.ptrInfo(mod);
+                const new_ptr_ty = try sema.ptrType(.{
+                    .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
+                    .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,
+                    .flags = .{
+                        .size = .Many,
+                        .alignment = ptr_info.flags.alignment,
+                        .is_const = ptr_info.flags.is_const,
+                        .is_volatile = ptr_info.flags.is_volatile,
+                        .is_allowzero = ptr_info.flags.is_allowzero,
+                        .address_space = ptr_info.flags.address_space,
+                        .vector_index = ptr_info.flags.vector_index,
+                    },
+                    .packed_offset = ptr_info.packed_offset,
+                });
+                const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);
+                const result_ty = try sema.ptrType(.{
+                    .child = new_ptr_ty.toIntern(),
+                    .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
+                    .flags = .{
+                        .alignment = ptr_ptr_info.flags.alignment,
+                        .is_const = ptr_ptr_info.flags.is_const,
+                        .is_volatile = ptr_ptr_info.flags.is_volatile,
+                        .is_allowzero = ptr_ptr_info.flags.is_allowzero,
+                        .address_space = ptr_ptr_info.flags.address_space,
+                        .vector_index = ptr_ptr_info.flags.vector_index,
+                    },
+                    .packed_offset = ptr_ptr_info.packed_offset,
+                });
+                return sema.bitCast(block, result_ty, object_ptr, src, null);
             } else {
                 return sema.fail(
                     block,
test/behavior/array.zig
@@ -709,7 +709,7 @@ test "pointer to array has ptr field" {
     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);
+    try std.testing.expect((&arr.ptr).*[4] == 50);
 }
 
 test "discarded array init preserves result location" {