Commit fb43e91b22

xdBronch <51252236+xdBronch@users.noreply.github.com>
2025-01-13 06:28:53
Sema: disallow non scalar sentinels in array types and reified types (#22473)
1 parent 5de880c
src/Sema.zig
@@ -8423,6 +8423,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
         .sentinel = sentinel_val.toIntern(),
         .child = elem_type.toIntern(),
     });
+    try sema.checkSentinelType(block, sentinel_src, elem_type);
 
     return Air.internedToRef(array_ty.toIntern());
 }
@@ -21650,6 +21651,7 @@ fn zirReify(
                     const sentinel_ptr_val = sentinel_val.optionalValue(zcu).?;
                     const ptr_ty = try pt.singleMutPtrType(elem_ty);
                     const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
+                    try sema.checkSentinelType(block, src, elem_ty);
                     break :s sent_val.toIntern();
                 }
                 break :s .none;
@@ -21714,6 +21716,7 @@ fn zirReify(
             const child_ty = child_val.toType();
             const sentinel = if (sentinel_val.optionalValue(zcu)) |p| blk: {
                 const ptr_ty = try pt.singleMutPtrType(child_ty);
+                try sema.checkSentinelType(block, src, child_ty);
                 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;
             } else null;
 
test/cases/compile_errors/array slice sentinel mismatch non-scalar.zig
@@ -1,14 +0,0 @@
-export fn foo() void {
-    const S = struct { a: u32 };
-    const sentinel: S = .{ .a = 1 };
-    var arr = [_]S{ .{ .a = 1 }, .{ .a = 2 } };
-    const s = arr[0..1 :sentinel];
-    _ = s;
-}
-
-// error
-// backend=stage2
-// target=native
-//
-// :5:25: error: non-scalar sentinel type 'tmp.foo.S'
-// :2:15: note: struct declared here
test/cases/compile_errors/non_scalar_sentinel.zig
@@ -0,0 +1,55 @@
+const S = struct {};
+const sentinel: S = .{};
+
+comptime {
+    _ = [0:sentinel]S;
+}
+comptime {
+    _ = [:sentinel]S;
+}
+comptime {
+    _ = [*:sentinel]S;
+}
+
+comptime {
+    _ = @Type(.{ .array = .{ .child = S, .len = 0, .sentinel = &sentinel } });
+}
+comptime {
+    _ = @Type(.{ .pointer = .{
+        .size = .Many,
+        .is_const = false,
+        .is_volatile = false,
+        .alignment = @alignOf(S),
+        .address_space = .generic,
+        .child = S,
+        .is_allowzero = false,
+        .sentinel = &sentinel,
+    } });
+}
+comptime {
+    _ = @Type(.{ .pointer = .{
+        .size = .Many,
+        .is_const = false,
+        .is_volatile = false,
+        .alignment = @alignOf(S),
+        .address_space = .generic,
+        .child = S,
+        .is_allowzero = false,
+        .sentinel = &sentinel,
+    } });
+}
+
+// error
+//
+// :5:12: error: non-scalar sentinel type 'tmp.S'
+// :1:11: note: struct declared here
+// :8:11: error: non-scalar sentinel type 'tmp.S'
+// :1:11: note: struct declared here
+// :11:12: error: non-scalar sentinel type 'tmp.S'
+// :1:11: note: struct declared here
+// :15:9: error: non-scalar sentinel type 'tmp.S'
+// :1:11: note: struct declared here
+// :18:9: error: non-scalar sentinel type 'tmp.S'
+// :1:11: note: struct declared here
+// :30:9: error: non-scalar sentinel type 'tmp.S'
+// :1:11: note: struct declared here