aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authordweiller <4678790+dweiller@users.noreply.github.com>2024-12-31 16:07:08 +1100
committerMatthew Lugg <mlugg@mlugg.co.uk>2025-07-31 12:02:19 +0100
commit19fc5f4fb29a525252b2eaf3f6388d07f97bd32f (patch)
tree2ef144edec2325d943ab8601c686aaab4ebacae5 /src/Sema.zig
parentbce6a7c21529e9b294a641b5d7472c000204aaef (diff)
downloadzig-19fc5f4fb29a525252b2eaf3f6388d07f97bd32f.tar.gz
zig-19fc5f4fb29a525252b2eaf3f6388d07f97bd32f.zip
Sema: disallow slicing many-item pointer with different sentinel
This change prevents adding or changing the sentinel in the type of a many-item pointer via the slicing syntax `ptr[a.. :S]`.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 94bf21e03b..9345c4bcac 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -31876,6 +31876,38 @@ fn analyzeSlice(
break :e try sema.coerce(block, .usize, uncasted_end, end_src);
} else break :e try sema.coerce(block, .usize, uncasted_end_opt, end_src);
}
+
+ // when slicing a many-item pointer, if a sentinel `S` is provided as in `ptr[a.. :S]`, it
+ // must match the sentinel of `@TypeOf(ptr)`.
+ sentinel_check: {
+ if (sentinel_opt == .none) break :sentinel_check;
+ const provided = provided: {
+ const casted = try sema.coerce(block, elem_ty, sentinel_opt, sentinel_src);
+ try checkSentinelType(sema, block, sentinel_src, elem_ty);
+ break :provided try sema.resolveConstDefinedValue(
+ block,
+ sentinel_src,
+ casted,
+ .{ .simple = .slice_sentinel },
+ );
+ };
+
+ if (ptr_sentinel) |current| {
+ if (provided.toIntern() == current.toIntern()) break :sentinel_check;
+ }
+
+ return sema.failWithOwnedErrorMsg(block, msg: {
+ const msg = try sema.errMsg(sentinel_src, "sentinel-terminated slicing of many-item pointer must match existing sentinel", .{});
+ errdefer msg.destroy(sema.gpa);
+ if (ptr_sentinel) |current| {
+ try sema.errNote(sentinel_src, msg, "expected sentinel '{f}', found '{f}'", .{ current.fmtValue(pt), provided.fmtValue(pt) });
+ } else {
+ try sema.errNote(ptr_src, msg, "type '{f}' does not have a sentinel", .{slice_ty.fmt(pt)});
+ }
+ try sema.errNote(src, msg, "use @ptrCast to cast pointer sentinel", .{});
+ break :msg msg;
+ });
+ }
return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
};