Improve error when break/continue label is in the same function but not enclosing - #64501
Musfiqur Rahman Saimon (britsync07-prog) wants to merge 2 commits into
Conversation
…ot enclosing When a break/continue targets a label declared in the same function that does not enclose the statement (e.g. a label placed after the loop), the checker reported 'Jump target cannot cross function boundary', which is misleading since no function boundary is crossed. Detect this case and report the specific 'can only jump to a label of an enclosing ...' diagnostic instead. Labels declared outside the function still produce the original error. Fixes microsoft#30408
|
This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Repeated full-function scans risk quadratic checking time, and newly added branches lack regression coverage.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
Improves diagnostics for non-enclosing labels declared within the same function.
Changes:
- Detects same-function labels without crossing nested function boundaries.
- Reports label-specific diagnostics instead of function-boundary errors.
- Adds a regression test and baselines.
| File | Description |
|---|---|
tsc/internal/checker/grammarchecks.go |
Adds label discovery and diagnostic selection. |
tsc/testdata/tests/cases/compiler/continueTargetSameFunctionLabel.ts |
Adds the regression case. |
tsc/testdata/baselines/reference/compiler/continueTargetSameFunctionLabel.errors.txt |
Captures the corrected diagnostic. |
tsc/testdata/baselines/reference/compiler/continueTargetSameFunctionLabel.js |
Captures emitted JavaScript. |
tsc/testdata/baselines/reference/compiler/continueTargetSameFunctionLabel.symbols |
Captures symbol output. |
tsc/testdata/baselines/reference/compiler/continueTargetSameFunctionLabel.types |
Captures type output. |
| // "cannot cross function boundary" is misleading, so report the | ||
| // more specific message instead. | ||
| // See https://github.com/microsoft/TypeScript/issues/30408 | ||
| if targetLabel != nil && functionContainsLabel(current, targetLabel.Text()) { |
| if targetLabel != nil && functionContainsLabel(current, targetLabel.Text()) { | ||
| if node.Kind == ast.KindBreakStatement { | ||
| return c.grammarErrorOnNode(node, diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement) | ||
| } | ||
| return c.grammarErrorOnNode(node, diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement) |
|
@microsoft-github-policy-service agree |
Cache per-function label sets on the checker so bodies are walked at most once. Add breakTargetSameFunctionLabel test covering break in a function and in a class static block.
|
Addressed both findings: label sets are now collected once per function and cached on the checker (no repeated subtree scans), and added �reakTargetSameFunctionLabel covering �reak in a function plus a class static block. CLA signed. Full break/continue/label sweep green; �reakTarget5/continueTarget5 baselines unchanged. |


Fixes #30408.
When a �reak/continue targets a label declared in the same function that does not enclose the statement (e.g. a label placed after the loop), the checker reported Jump target cannot cross function boundary, which is misleading since no function boundary is crossed. checkGrammarBreakOrContinueStatement now detects this case (via a same-function label search that does not cross nested functions) and reports the specific A 'continue'/'break' statement can only jump to a label of an enclosing ... diagnostic instead. Labels declared outside the function still produce the original error (�reakTarget5/continueTarget5 baselines unchanged).
Verified with the tsgo test runner: new continueTargetSameFunctionLabel test plus the full break/continue/label sweep green.