| author | |
| committer | |
| log | 61fe307d0f05eea901577900f4ab2bdaf0ffb35f |
| tree | 540a47aad6da00421777f121c6b9e568f541918f |
| parent | 941677e08318c2baaabc9d0fc87892d1b63487ae |
| parent | e864c38cc38095a1496229803465fdd0d079f9c3 |
| signature |
compiler: a few fixes7 files changed, 78 insertions(+), 15 deletions(-)
lib/std/debug.zig-7| ... | @@ -413,16 +413,9 @@ pub fn assertReadable(slice: []const volatile u8) void { | ... | @@ -413,16 +413,9 @@ pub fn assertReadable(slice: []const volatile u8) void { |
| 413 | for (slice) |*byte| _ = byte.*; | 413 | for (slice) |*byte| _ = byte.*; |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 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. | ||
| 420 | pub fn errorReturnTraceHelper() anyerror!void {} | ||
| 421 | |||
| 422 | /// Equivalent to `@panic` but with a formatted message. | 416 | /// Equivalent to `@panic` but with a formatted message. |
| 423 | pub fn panic(comptime format: []const u8, args: anytype) noreturn { | 417 | pub fn panic(comptime format: []const u8, args: anytype) noreturn { |
| 424 | @branchHint(.cold); | 418 | @branchHint(.cold); |
| 425 | errorReturnTraceHelper() catch unreachable; | ||
| 426 | panicExtra(@errorReturnTrace(), @returnAddress(), format, args); | 419 | panicExtra(@errorReturnTrace(), @returnAddress(), format, args); |
| 427 | } | 420 | } |
| 428 | 421 |
lib/std/mem/Allocator.zig+3-5| ... | @@ -282,11 +282,9 @@ pub fn reallocAdvanced( | ... | @@ -282,11 +282,9 @@ pub fn reallocAdvanced( |
| 282 | const old_byte_slice = mem.sliceAsBytes(old_mem); | 282 | const old_byte_slice = mem.sliceAsBytes(old_mem); |
| 283 | const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory; | 283 | const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory; |
| 284 | // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure | 284 | // 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)) { | 285 | if (self.rawResize(old_byte_slice, log2a(Slice.alignment), byte_count, return_address)) { |
| 286 | 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 | const new_bytes: []align(Slice.alignment) u8 = @alignCast(old_byte_slice.ptr[0..byte_count]); | 287 | return mem.bytesAsSlice(T, new_bytes); |
| 288 | return mem.bytesAsSlice(T, new_bytes); | ||
| 289 | } | ||
| 290 | } | 288 | } |
| 291 | 289 | ||
| 292 | const new_mem = self.rawAlloc(byte_count, log2a(Slice.alignment), return_address) orelse | 290 | 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) { | ... | @@ -788,6 +788,7 @@ pub const SimpleComptimeReason = enum(u32) { |
| 788 | // Miscellaneous reasons. | 788 | // Miscellaneous reasons. |
| 789 | comptime_keyword, | 789 | comptime_keyword, |
| 790 | comptime_call_modifier, | 790 | comptime_call_modifier, |
| 791 | inline_loop_operand, | ||
| 791 | switch_item, | 792 | switch_item, |
| 792 | tuple_field_default_value, | 793 | tuple_field_default_value, |
| 793 | struct_field_default_value, | 794 | struct_field_default_value, |
| ... | @@ -863,6 +864,7 @@ pub const SimpleComptimeReason = enum(u32) { | ... | @@ -863,6 +864,7 @@ pub const SimpleComptimeReason = enum(u32) { |
| 863 | 864 | ||
| 864 | .comptime_keyword => "'comptime' keyword forces comptime evaluation", | 865 | .comptime_keyword => "'comptime' keyword forces comptime evaluation", |
| 865 | .comptime_call_modifier => "'.compile_time' call modifier forces comptime evaluation", | 866 | .comptime_call_modifier => "'.compile_time' call modifier forces comptime evaluation", |
| 867 | .inline_loop_operand => "inline loop condition must be comptime-known", | ||
| 866 | .switch_item => "switch prong values must be comptime-known", | 868 | .switch_item => "switch prong values must be comptime-known", |
| 867 | .tuple_field_default_value => "tuple field default value must be comptime-known", | 869 | .tuple_field_default_value => "tuple field default value must be comptime-known", |
| 868 | .struct_field_default_value => "struct field default value must be comptime-known", | 870 | .struct_field_default_value => "struct field default value must be comptime-known", |
src/Sema.zig+8-1| ... | @@ -1824,7 +1824,14 @@ fn analyzeBodyInner( | ... | @@ -1824,7 +1824,14 @@ fn analyzeBodyInner( |
| 1824 | ); | 1824 | ); |
| 1825 | const uncasted_cond = try sema.resolveInst(extra.data.condition); | 1825 | const uncasted_cond = try sema.resolveInst(extra.data.condition); |
| 1826 | const cond = try sema.coerce(block, Type.bool, uncasted_cond, cond_src); | 1826 | 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 | ); | ||
| 1828 | const inline_body = if (cond_val.toBool()) then_body else else_body; | 1835 | const inline_body = if (cond_val.toBool()) then_body else else_body; |
| 1829 | 1836 | ||
| 1830 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1837 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
src/Zcu.zig+3-2| ... | @@ -1864,15 +1864,16 @@ pub const SrcLoc = struct { | ... | @@ -1864,15 +1864,16 @@ pub const SrcLoc = struct { |
| 1864 | if (want_case_idx.isSpecial()) { | 1864 | if (want_case_idx.isSpecial()) { |
| 1865 | break case; | 1865 | break case; |
| 1866 | } | 1866 | } |
| 1867 | continue; | ||
| 1867 | } | 1868 | } |
| 1868 | 1869 | ||
| 1869 | const is_multi = case.ast.values.len != 1 or | 1870 | const is_multi = case.ast.values.len != 1 or |
| 1870 | node_tags[case.ast.values[0]] == .switch_range; | 1871 | node_tags[case.ast.values[0]] == .switch_range; |
| 1871 | 1872 | ||
| 1872 | if (!want_case_idx.isSpecial()) switch (want_case_idx.kind) { | 1873 | switch (want_case_idx.kind) { |
| 1873 | .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case, | 1874 | .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case, |
| 1874 | .multi => if (is_multi and want_case_idx.index == multi_i) break case, | 1875 | .multi => if (is_multi and want_case_idx.index == multi_i) break case, |
| 1875 | }; | 1876 | } |
| 1876 | 1877 | ||
| 1877 | if (is_multi) { | 1878 | if (is_multi) { |
| 1878 | multi_i += 1; | 1879 | multi_i += 1; |
test/cases/compile_errors/invalid_switch_item.zig created+46| ... | @@ -0,0 +1,46 @@ | ||
| 1 | const E = enum { a, b, c }; | ||
| 2 | var my_e: E = .a; | ||
| 3 | |||
| 4 | export fn f0() void { | ||
| 5 | switch (my_e) { | ||
| 6 | .a => {}, | ||
| 7 | .b => {}, | ||
| 8 | .x => {}, | ||
| 9 | .c => {}, | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | export fn f1() void { | ||
| 14 | switch (my_e) { | ||
| 15 | else => {}, | ||
| 16 | .x, .y => {}, | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | export fn f2() void { | ||
| 21 | switch (my_e) { | ||
| 22 | else => {}, | ||
| 23 | .a => {}, | ||
| 24 | .x, .y => {}, | ||
| 25 | .b => {}, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | export 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 @@ | ||
| 1 | var rt_slice: []const u8 = &.{ 1, 2, 3 }; | ||
| 2 | |||
| 3 | export fn foo() void { | ||
| 4 | inline for (rt_slice) |_| {} | ||
| 5 | } | ||
| 6 | |||
| 7 | export 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 | ||