authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-22 16:47:45+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-01-22 16:47:45+00:00
log61fe307d0f05eea901577900f4ab2bdaf0ffb35f
tree540a47aad6da00421777f121c6b9e568f541918f
parent941677e08318c2baaabc9d0fc87892d1b63487ae
parente864c38cc38095a1496229803465fdd0d079f9c3
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22571 from mlugg/various-fixes-again

compiler: a few fixes

7 files changed, 78 insertions(+), 15 deletions(-)

lib/std/debug.zig-7
......@@ -413,16 +413,9 @@ pub fn assertReadable(slice: []const volatile u8) void {
413413 for (slice) |*byte| _ = byte.*;
414414}
415415
416/// By including a call to this function, the caller gains an error return trace
417/// secret parameter, making `@errorReturnTrace()` more useful. This is not
418/// necessary if the function already contains a call to an errorable function
419/// elsewhere.
420pub fn errorReturnTraceHelper() anyerror!void {}
421
422416/// Equivalent to `@panic` but with a formatted message.
423417pub fn panic(comptime format: []const u8, args: anytype) noreturn {
424418 @branchHint(.cold);
425 errorReturnTraceHelper() catch unreachable;
426419 panicExtra(@errorReturnTrace(), @returnAddress(), format, args);
427420}
428421
lib/std/mem/Allocator.zig+3-5
......@@ -282,11 +282,9 @@ pub fn reallocAdvanced(
282282 const old_byte_slice = mem.sliceAsBytes(old_mem);
283283 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;
284284 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
285 if (mem.isAligned(@intFromPtr(old_byte_slice.ptr), Slice.alignment)) {
286 if (self.rawResize(old_byte_slice, log2a(Slice.alignment), byte_count, return_address)) {
287 const new_bytes: []align(Slice.alignment) u8 = @alignCast(old_byte_slice.ptr[0..byte_count]);
288 return mem.bytesAsSlice(T, new_bytes);
289 }
285 if (self.rawResize(old_byte_slice, log2a(Slice.alignment), byte_count, return_address)) {
286 const new_bytes: []align(Slice.alignment) u8 = @alignCast(old_byte_slice.ptr[0..byte_count]);
287 return mem.bytesAsSlice(T, new_bytes);
290288 }
291289
292290 const new_mem = self.rawAlloc(byte_count, log2a(Slice.alignment), return_address) orelse
lib/std/zig.zig+2
......@@ -788,6 +788,7 @@ pub const SimpleComptimeReason = enum(u32) {
788788 // Miscellaneous reasons.
789789 comptime_keyword,
790790 comptime_call_modifier,
791 inline_loop_operand,
791792 switch_item,
792793 tuple_field_default_value,
793794 struct_field_default_value,
......@@ -863,6 +864,7 @@ pub const SimpleComptimeReason = enum(u32) {
863864
864865 .comptime_keyword => "'comptime' keyword forces comptime evaluation",
865866 .comptime_call_modifier => "'.compile_time' call modifier forces comptime evaluation",
867 .inline_loop_operand => "inline loop condition must be comptime-known",
866868 .switch_item => "switch prong values must be comptime-known",
867869 .tuple_field_default_value => "tuple field default value must be comptime-known",
868870 .struct_field_default_value => "struct field default value must be comptime-known",
src/Sema.zig+8-1
......@@ -1824,7 +1824,14 @@ fn analyzeBodyInner(
18241824 );
18251825 const uncasted_cond = try sema.resolveInst(extra.data.condition);
18261826 const cond = try sema.coerce(block, Type.bool, uncasted_cond, cond_src);
1827 const cond_val = try sema.resolveConstDefinedValue(block, cond_src, cond, null);
1827 const cond_val = try sema.resolveConstDefinedValue(
1828 block,
1829 cond_src,
1830 cond,
1831 // If this block is comptime, it's more helpful to just give the outer message.
1832 // This is particularly true if this came from a comptime `condbr` above.
1833 if (block.isComptime()) null else .{ .simple = .inline_loop_operand },
1834 );
18281835 const inline_body = if (cond_val.toBool()) then_body else else_body;
18291836
18301837 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
src/Zcu.zig+3-2
......@@ -1864,15 +1864,16 @@ pub const SrcLoc = struct {
18641864 if (want_case_idx.isSpecial()) {
18651865 break case;
18661866 }
1867 continue;
18671868 }
18681869
18691870 const is_multi = case.ast.values.len != 1 or
18701871 node_tags[case.ast.values[0]] == .switch_range;
18711872
1872 if (!want_case_idx.isSpecial()) switch (want_case_idx.kind) {
1873 switch (want_case_idx.kind) {
18731874 .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case,
18741875 .multi => if (is_multi and want_case_idx.index == multi_i) break case,
1875 };
1876 }
18761877
18771878 if (is_multi) {
18781879 multi_i += 1;
test/cases/compile_errors/invalid_switch_item.zig created+46
......@@ -0,0 +1,46 @@
1const E = enum { a, b, c };
2var my_e: E = .a;
3
4export fn f0() void {
5 switch (my_e) {
6 .a => {},
7 .b => {},
8 .x => {},
9 .c => {},
10 }
11}
12
13export fn f1() void {
14 switch (my_e) {
15 else => {},
16 .x, .y => {},
17 }
18}
19
20export fn f2() void {
21 switch (my_e) {
22 else => {},
23 .a => {},
24 .x, .y => {},
25 .b => {},
26 }
27}
28
29export fn f3() void {
30 switch (my_e) {
31 .a, .b => {},
32 .x, .y => {},
33 else => {},
34 }
35}
36
37// error
38//
39// :8:10: error: no field named 'x' in enum 'tmp.E'
40// :1:11: note: enum declared here
41// :16:10: error: no field named 'x' in enum 'tmp.E'
42// :1:11: note: enum declared here
43// :24:10: error: no field named 'x' in enum 'tmp.E'
44// :1:11: note: enum declared here
45// :32:10: error: no field named 'x' in enum 'tmp.E'
46// :1:11: note: enum declared here
test/cases/compile_errors/runtime_condition_in_inline_loop.zig created+16
......@@ -0,0 +1,16 @@
1var rt_slice: []const u8 = &.{ 1, 2, 3 };
2
3export fn foo() void {
4 inline for (rt_slice) |_| {}
5}
6
7export fn bar() void {
8 inline while (rt_slice.len == 0) {}
9}
10
11// error
12//
13// :4:17: error: unable to resolve comptime value
14// :4:17: note: inline loop condition must be comptime-known
15// :8:32: error: unable to resolve comptime value
16// :8:32: note: inline loop condition must be comptime-known