| ... | @@ -348,8 +348,9 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpr | ... | @@ -348,8 +348,9 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpr |
| 348 | | 348 | |
| 349 | const block_inst = blk: { | 349 | const block_inst = blk: { |
| 350 | if (node.getLabel()) |break_label| { | 350 | if (node.getLabel()) |break_label| { |
| 351 | if (gen_zir.label) |label| { | 351 | if (gen_zir.label) |*label| { |
| 352 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { | 352 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { |
| | 353 | label.used = true; |
| 353 | break :blk label.block_inst; | 354 | break :blk label.block_inst; |
| 354 | } | 355 | } |
| 355 | } | 356 | } |
| ... | @@ -407,8 +408,9 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE | ... | @@ -407,8 +408,9 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 407 | continue; | 408 | continue; |
| 408 | }; | 409 | }; |
| 409 | if (node.getLabel()) |break_label| blk: { | 410 | if (node.getLabel()) |break_label| blk: { |
| 410 | if (gen_zir.label) |label| { | 411 | if (gen_zir.label) |*label| { |
| 411 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { | 412 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { |
| | 413 | label.used = true; |
| 412 | break :blk; | 414 | break :blk; |
| 413 | } | 415 | } |
| 414 | } | 416 | } |
| ... | @@ -485,6 +487,9 @@ fn labeledBlockExpr( | ... | @@ -485,6 +487,9 @@ fn labeledBlockExpr( |
| 485 | defer block_scope.instructions.deinit(mod.gpa); | 487 | defer block_scope.instructions.deinit(mod.gpa); |
| 486 | | 488 | |
| 487 | try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements()); | 489 | try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements()); |
| | 490 | if (!block_scope.label.?.used) { |
| | 491 | return mod.fail(parent_scope, tree.token_locs[block_node.label].start, "unused block label", .{}); |
| | 492 | } |
| 488 | | 493 | |
| 489 | block_inst.positionals.body.instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items); | 494 | block_inst.positionals.body.instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items); |
| 490 | try gen_zir.instructions.append(mod.gpa, &block_inst.base); | 495 | try gen_zir.instructions.append(mod.gpa, &block_inst.base); |
| ... | @@ -1398,7 +1403,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W | ... | @@ -1398,7 +1403,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W |
| 1398 | loop_scope.break_block = while_block; | 1403 | loop_scope.break_block = while_block; |
| 1399 | loop_scope.continue_block = cond_block; | 1404 | loop_scope.continue_block = cond_block; |
| 1400 | if (while_node.label) |some| { | 1405 | if (while_node.label) |some| { |
| 1401 | loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{ | 1406 | loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{ |
| 1402 | .token = some, | 1407 | .token = some, |
| 1403 | .block_inst = while_block, | 1408 | .block_inst = while_block, |
| 1404 | }); | 1409 | }); |
| ... | @@ -1465,6 +1470,11 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W | ... | @@ -1465,6 +1470,11 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W |
| 1465 | condbr.positionals.else_body = .{ | 1470 | condbr.positionals.else_body = .{ |
| 1466 | .instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items), | 1471 | .instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items), |
| 1467 | }; | 1472 | }; |
| | 1473 | if (loop_scope.label) |some| { |
| | 1474 | if (!some.used) { |
| | 1475 | return mod.fail(scope, tree.token_locs[some.token].start, "unused while label", .{}); |
| | 1476 | } |
| | 1477 | } |
| 1468 | return &while_block.base; | 1478 | return &while_block.base; |
| 1469 | } | 1479 | } |
| 1470 | | 1480 | |
| ... | @@ -1555,7 +1565,7 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) | ... | @@ -1555,7 +1565,7 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) |
| 1555 | loop_scope.break_block = for_block; | 1565 | loop_scope.break_block = for_block; |
| 1556 | loop_scope.continue_block = cond_block; | 1566 | loop_scope.continue_block = cond_block; |
| 1557 | if (for_node.label) |some| { | 1567 | if (for_node.label) |some| { |
| 1558 | loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{ | 1568 | loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{ |
| 1559 | .token = some, | 1569 | .token = some, |
| 1560 | .block_inst = for_block, | 1570 | .block_inst = for_block, |
| 1561 | }); | 1571 | }); |
| ... | @@ -1646,6 +1656,11 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) | ... | @@ -1646,6 +1656,11 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) |
| 1646 | condbr.positionals.else_body = .{ | 1656 | condbr.positionals.else_body = .{ |
| 1647 | .instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items), | 1657 | .instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items), |
| 1648 | }; | 1658 | }; |
| | 1659 | if (loop_scope.label) |some| { |
| | 1660 | if (!some.used) { |
| | 1661 | return mod.fail(scope, tree.token_locs[some.token].start, "unused for label", .{}); |
| | 1662 | } |
| | 1663 | } |
| 1649 | return &for_block.base; | 1664 | return &for_block.base; |
| 1650 | } | 1665 | } |
| 1651 | | 1666 | |