Commit c51b871c45

LemonBoy <thatlemon@gmail.com>
2020-09-01 17:29:10
ir: Typecheck the sentinel value in *[N:S1]T to [S2]T casts
Closes #6054
1 parent 2614067
Changed files (2)
src/ir.cpp
@@ -15341,9 +15341,14 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
         ZigType *array_type = actual_type->data.pointer.child_type;
         bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
                 || !actual_type->data.pointer.is_const);
+
         if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
             array_type->data.array.child_type, source_node,
-            !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
+            !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk &&
+            (slice_ptr_type->data.pointer.sentinel == nullptr ||
+             (array_type->data.array.sentinel != nullptr &&
+              const_values_equal(ira->codegen, array_type->data.array.sentinel,
+                  slice_ptr_type->data.pointer.sentinel))))
         {
             // If the pointers both have ABI align, it works.
             // Or if the array length is 0, alignment doesn't matter.
test/compile_errors.zig
@@ -2,6 +2,14 @@ const tests = @import("tests.zig");
 const std = @import("std");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add("slice sentinel mismatch",
+        \\export fn entry() void {
+        \\    const y: [:1]const u8 = &[_:2]u8{ 1, 2 };
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",
+    });
+
     cases.add("@Type with undefined",
         \\comptime {
         \\    _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });