authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-05 14:14:04+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-06 15:39:06+03:00
logb626977f45f5175ae26e212b20adbd514649d6e5
tree49704d5dc325437a325e038bbac280957b4545eb
parentba4aa12098a0a9def52582cecd5b0b664ded14d8

Sema: create sub block for inline loops

Closes #13038

2 files changed, 30 insertions(+), 5 deletions(-)

src/Sema.zig+16-5
......@@ -1302,17 +1302,28 @@ fn analyzeBodyInner(
13021302 // current list of parameters and restore it later.
13031303 // Note: this probably needs to be resolved in a more general manner.
13041304 const prev_params = block.params;
1305 const prev_inline_block = block.inline_block;
1306 if (tags[inline_body[inline_body.len - 1]] == .repeat_inline) {
1307 block.inline_block = inline_body[0];
1305 const need_sub_block = tags[inline_body[inline_body.len - 1]] == .repeat_inline;
1306 var sub_block = block;
1307 var block_space: Block = undefined;
1308 // NOTE: this has to be done like this because branching in
1309 // defers here breaks stage1.
1310 block_space.instructions = .{};
1311 if (need_sub_block) {
1312 block_space = block.makeSubBlock();
1313 block_space.inline_block = inline_body[0];
1314 sub_block = &block_space;
13081315 }
13091316 block.params = .{};
13101317 defer {
13111318 block.params.deinit(gpa);
13121319 block.params = prev_params;
1313 block.inline_block = prev_inline_block;
1320 block_space.instructions.deinit(gpa);
13141321 }
1315 const opt_break_data = try sema.analyzeBodyBreak(block, inline_body);
1322 const opt_break_data = try sema.analyzeBodyBreak(sub_block, inline_body);
1323 if (need_sub_block) {
1324 try block.instructions.appendSlice(gpa, block_space.instructions.items);
1325 }
1326
13161327 // A runtime conditional branch that needs a post-hoc block to be
13171328 // emitted communicates this by mapping the block index into the inst map.
13181329 if (map.get(inst)) |new_block_ref| ph: {
test/behavior/eval.zig+14
......@@ -1398,3 +1398,17 @@ test "continue in inline for inside a comptime switch" {
13981398 }
13991399 try expect(count == 4);
14001400}
1401
1402test "continue nested inline for loop" {
1403 var a: u8 = 0;
1404 loop: inline for ([_]u8{ 1, 2 }) |x| {
1405 inline for ([_]u8{1}) |y| {
1406 if (x == y) {
1407 continue :loop;
1408 }
1409 }
1410 a = x;
1411 try expect(x == 2);
1412 }
1413 try expect(a == 2);
1414}