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(...@@ -1302,17 +1302,28 @@ fn analyzeBodyInner(
1302 // current list of parameters and restore it later.1302 // current list of parameters and restore it later.
1303 // Note: this probably needs to be resolved in a more general manner.1303 // Note: this probably needs to be resolved in a more general manner.
1304 const prev_params = block.params;1304 const prev_params = block.params;
1305 const prev_inline_block = block.inline_block;1305 const need_sub_block = tags[inline_body[inline_body.len - 1]] == .repeat_inline;
1306 if (tags[inline_body[inline_body.len - 1]] == .repeat_inline) {1306 var sub_block = block;
1307 block.inline_block = inline_body[0];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;
1308 }1315 }
1309 block.params = .{};1316 block.params = .{};
1310 defer {1317 defer {
1311 block.params.deinit(gpa);1318 block.params.deinit(gpa);
1312 block.params = prev_params;1319 block.params = prev_params;
1313 block.inline_block = prev_inline_block;1320 block_space.instructions.deinit(gpa);
1314 }1321 }
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
1316 // A runtime conditional branch that needs a post-hoc block to be1327 // A runtime conditional branch that needs a post-hoc block to be
1317 // emitted communicates this by mapping the block index into the inst map.1328 // emitted communicates this by mapping the block index into the inst map.
1318 if (map.get(inst)) |new_block_ref| ph: {1329 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" {...@@ -1398,3 +1398,17 @@ test "continue in inline for inside a comptime switch" {
1398 }1398 }
1399 try expect(count == 4);1399 try expect(count == 4);
1400}1400}
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}