Commit 92f64899c1

xdBronch <51252236+xdBronch@users.noreply.github.com>
2025-10-28 00:41:32
sema: disallow slices of opaque types
1 parent 19af9fa
src/Sema.zig
@@ -19168,8 +19168,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
         if (inst_data.size != .one) {
             return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});
         }
-    } else if (inst_data.size == .many and elem_ty.zigTypeTag(zcu) == .@"opaque") {
-        return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});
+    } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") {
+        return sema.fail(block, elem_ty_src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)});
     } else if (inst_data.size == .c) {
         if (!try sema.validateExternType(elem_ty, .other)) {
             const msg = msg: {
@@ -19183,9 +19183,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
             };
             return sema.failWithOwnedErrorMsg(block, msg);
         }
-        if (elem_ty.zigTypeTag(zcu) == .@"opaque") {
-            return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});
-        }
     }
 
     if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {
@@ -20674,8 +20671,8 @@ fn zirReify(
                 if (ptr_size != .one) {
                     return sema.fail(block, src, "function pointers must be single pointers", .{});
                 }
-            } else if (ptr_size == .many and elem_ty.zigTypeTag(zcu) == .@"opaque") {
-                return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{});
+            } else if (ptr_size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") {
+                return sema.fail(block, src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)});
             } else if (ptr_size == .c) {
                 if (!try sema.validateExternType(elem_ty, .other)) {
                     const msg = msg: {
@@ -20689,9 +20686,6 @@ fn zirReify(
                     };
                     return sema.failWithOwnedErrorMsg(block, msg);
                 }
-                if (elem_ty.zigTypeTag(zcu) == .@"opaque") {
-                    return sema.fail(block, src, "C pointers cannot point to opaque types", .{});
-                }
             }
 
             const ty = try pt.ptrTypeSema(.{
test/cases/compile_errors/C_pointer_to_anyopaque.zig
@@ -1,9 +0,0 @@
-export fn a() void {
-    var x: *anyopaque = undefined;
-    var y: [*c]anyopaque = x;
-    _ = .{ &x, &y };
-}
-
-// error
-//
-// :3:16: error: C pointers cannot point to opaque types
test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig
@@ -15,12 +15,6 @@ pub export fn entry3() void {
     const ptr: *const anyopaque = x;
     _ = ptr;
 }
-export fn entry4() void {
-    var a: []*u32 = undefined;
-    _ = &a;
-    var b: []anyopaque = undefined;
-    b = a;
-}
 
 // error
 //
@@ -31,5 +25,3 @@ export fn entry4() void {
 // :11:12: note: parameter type declared here
 // :15:35: error: expected type '*const anyopaque', found '*?*usize'
 // :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque'
-// :22:9: error: expected type '[]anyopaque', found '[]*u32'
-// :22:9: note: cannot implicitly cast double pointer '[]*u32' to anyopaque pointer '[]anyopaque'
test/cases/compile_errors/invalid_pointer_to_opaque.zig
@@ -0,0 +1,55 @@
+export fn a() void {
+    _ = []anyopaque;
+}
+export fn b() void {
+    _ = [*]anyopaque;
+}
+export fn c() void {
+    _ = [*c]anyopaque;
+}
+
+export fn d() void {
+    _ = @Type(.{ .pointer = .{
+        .size = .slice,
+        .is_const = false,
+        .is_volatile = false,
+        .alignment = 1,
+        .address_space = .generic,
+        .child = anyopaque,
+        .is_allowzero = false,
+        .sentinel_ptr = null,
+    } });
+}
+export fn e() void {
+    _ = @Type(.{ .pointer = .{
+        .size = .many,
+        .is_const = false,
+        .is_volatile = false,
+        .alignment = 1,
+        .address_space = .generic,
+        .child = anyopaque,
+        .is_allowzero = false,
+        .sentinel_ptr = null,
+    } });
+}
+export fn f() void {
+    _ = @Type(.{ .pointer = .{
+        .size = .c,
+        .is_const = false,
+        .is_volatile = false,
+        .alignment = 1,
+        .address_space = .generic,
+        .child = anyopaque,
+        .is_allowzero = false,
+        .sentinel_ptr = null,
+    } });
+}
+
+// error
+//
+// :2:11: error: indexable pointer to opaque type 'anyopaque' not allowed
+// :5:12: error: indexable pointer to opaque type 'anyopaque' not allowed
+// :8:13: error: indexable pointer to opaque type 'anyopaque' not allowed
+// :12:9: error: indexable pointer to opaque type 'anyopaque' not allowed
+// :24:9: error: indexable pointer to opaque type 'anyopaque' not allowed
+// :36:9: error: indexable pointer to opaque type 'anyopaque' not allowed
test/cases/compile_errors/pointer_to_anyopaque_slice.zig
@@ -1,10 +0,0 @@
-export fn x() void {
-    var a: *u32 = undefined;
-    var b: []anyopaque = undefined;
-    b = a;
-    _ = &a;
-}
-
-// error
-//
-// :4:9: error: expected type '[]anyopaque', found '*u32'
test/cases/compile_errors/unknown_length_pointer_to_opaque.zig
@@ -1,5 +0,0 @@
-export const T = [*]opaque {};
-
-// error
-//
-// :1:21: error: unknown-length pointer to opaque not allowed
test/cases/error_in_nested_declaration.zig
@@ -27,4 +27,4 @@ pub export fn entry2() void {
 //
 // :6:20: error: cannot @bitCast to '[]i32'
 // :6:20: note: use @ptrCast to cast from '[]u32'
-// :17:12: error: C pointers cannot point to opaque types
+// :17:12: error: indexable pointer to opaque type 'anyopaque' not allowed