| author | |
| committer | |
| log | fad95741db7529bbad873fb330c25d64ac765340 |
| tree | 22ca663d66d22bccc6ffe9ac0d2c676ed8bb0636 |
| parent | 1fee9eac8bb5d2e3e78c098b9cebe2cda332e7cf |
In the case of 'continue' or 'break' inside the 'else' block of a
'while' or 'for' loop.
Closes #121095 files changed, 35 insertions(+), 4 deletions(-)
lib/std/net/test.zig-1| ... | ... | @@ -104,7 +104,6 @@ test "parse and render UNIX addresses" { |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | 106 | test "resolve DNS" { |
| 107 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 108 | 107 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 109 | 108 | |
| 110 | 109 | if (builtin.os.tag == .windows) { |
lib/std/os.zig+3-3| ... | ... | @@ -6476,7 +6476,7 @@ pub fn dn_expand( |
| 6476 | 6476 | p = msg.ptr + j; |
| 6477 | 6477 | } else if (p[0] != 0) { |
| 6478 | 6478 | if (dest != exp_dn.ptr) { |
| 6479 | dest.* = '.'; | |
| 6479 | dest[0] = '.'; | |
| 6480 | 6480 | dest += 1; |
| 6481 | 6481 | } |
| 6482 | 6482 | var j = p[0]; |
| ... | ... | @@ -6486,12 +6486,12 @@ pub fn dn_expand( |
| 6486 | 6486 | } |
| 6487 | 6487 | while (j != 0) { |
| 6488 | 6488 | j -= 1; |
| 6489 | dest.* = p[0]; | |
| 6489 | dest[0] = p[0]; | |
| 6490 | 6490 | dest += 1; |
| 6491 | 6491 | p += 1; |
| 6492 | 6492 | } |
| 6493 | 6493 | } else { |
| 6494 | dest.* = 0; | |
| 6494 | dest[0] = 0; | |
| 6495 | 6495 | if (len == std.math.maxInt(usize)) len = @ptrToInt(p) + 1 - @ptrToInt(comp_dn.ptr); |
| 6496 | 6496 | return len; |
| 6497 | 6497 | } |
src/AstGen.zig+8| ... | ... | @@ -5795,6 +5795,10 @@ fn whileExpr( |
| 5795 | 5795 | break :s &else_scope.base; |
| 5796 | 5796 | } |
| 5797 | 5797 | }; |
| 5798 | // Remove the continue block and break block so that `continue` and `break` | |
| 5799 | // control flow apply to outer loops; not this one. | |
| 5800 | loop_scope.continue_block = 0; | |
| 5801 | loop_scope.break_block = 0; | |
| 5798 | 5802 | const e = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node); |
| 5799 | 5803 | if (!else_scope.endsWithNoReturn()) { |
| 5800 | 5804 | loop_scope.break_count += 1; |
| ... | ... | @@ -5994,6 +5998,10 @@ fn forExpr( |
| 5994 | 5998 | result: Zir.Inst.Ref, |
| 5995 | 5999 | } = if (else_node != 0) blk: { |
| 5996 | 6000 | const sub_scope = &else_scope.base; |
| 6001 | // Remove the continue block and break block so that `continue` and `break` | |
| 6002 | // control flow apply to outer loops; not this one. | |
| 6003 | loop_scope.continue_block = 0; | |
| 6004 | loop_scope.break_block = 0; | |
| 5997 | 6005 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node); |
| 5998 | 6006 | if (!else_scope.endsWithNoReturn()) { |
| 5999 | 6007 | loop_scope.break_count += 1; |
test/behavior/for.zig+14| ... | ... | @@ -210,3 +210,17 @@ test "for on slice with allowzero ptr" { |
| 210 | 210 | try S.doTheTest(&[_]u8{ 1, 2, 3, 4 }); |
| 211 | 211 | comptime try S.doTheTest(&[_]u8{ 1, 2, 3, 4 }); |
| 212 | 212 | } |
| 213 | ||
| 214 | test "else continue outer for" { | |
| 215 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 216 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 217 | ||
| 218 | var i: usize = 6; | |
| 219 | var buf: [5]u8 = undefined; | |
| 220 | while (true) { | |
| 221 | i -= 1; | |
| 222 | for (buf[i..5]) |_| { | |
| 223 | return; | |
| 224 | } else continue; | |
| 225 | } | |
| 226 | } |
test/behavior/while.zig+10| ... | ... | @@ -334,3 +334,13 @@ test "continue inline while loop" { |
| 334 | 334 | } |
| 335 | 335 | comptime assert(i == 5); |
| 336 | 336 | } |
| 337 | ||
| 338 | test "else continue outer while" { | |
| 339 | var i: usize = 0; | |
| 340 | while (true) { | |
| 341 | i += 1; | |
| 342 | while (i > 5) { | |
| 343 | return; | |
| 344 | } else continue; | |
| 345 | } | |
| 346 | } |