100%

break-continue-validation

Goal

Reject break value (E0860) and continue value (E0861) inside while via the form-agnostic typeck LoopContext break_value_allowed: false / continue_value_allowed: false flags, with exact-code negative tests.

Implementation Sketch

Verification-only: confirm typeck LoopForm::While loop-context tracking (LoopForm::While push at compiler_repo/compiler/ori_types/src/infer/expr/control_flow/loops.rs:217; enum def compiler_repo/compiler/ori_types/src/infer/scope.rs:43) sets break-value/continue-value disallowed (break_value_allowed: false, continue_value_allowed: false) and emits E0860/E0861 via structured ori_diagnostic Diagnostics with the proposal’s messages + help lines. No parse-level while-derived marker exists — the typeck loop-context owns the check.

Delivered State Note — verify, do not re-execute

E0860/E0861 enforcement already exists at HEAD (compiler_repo commit b9939de7d): typeck LoopForm::While loop-context push (compiler_repo/compiler/ori_types/src/infer/expr/control_flow/loops.rs:211-217 pushes the LoopContext with form: LoopForm::While, break_value_allowed: false, continue_value_allowed: false BEFORE the condition is inferred; enum def compiler_repo/compiler/ori_types/src/infer/scope.rs:43). The two error codes are declared at HEAD in compiler_repo/compiler/ori_diagnostic/src/error_code/mod.rs:87-88 via the define_error_codes! macro (E0860, "break with value in a void-typed loop"; E0861, "continue with value in a non-collecting loop"), with reader-facing error docs at compiler_repo/compiler/ori_diagnostic/src/errors/E0860.md + E0861.md. #compile_fail(E0860/E0861) pins live in tests/spec/expressions/while.ori at lines 135/141/213. Execute the work items as verification against these artifacts (cite the verified declaration site error_code/mod.rs:87-88 for the codes themselves); fix any gap surfaced.

Section-boundary note — scope partition across the shared LoopForm::While typeck path

  • Three sections of this plan touch the same LoopForm::While LoopContext typeck path (compiler_repo/compiler/ori_types/src/infer/expr/control_flow/loops.rs:211-217): this section, parser-desugar (s-410a0ed6), and the walking-skeleton (s-114d5c42) open finding HYG-01-004. Each owns a disjoint slice; reference the shared path, do NOT re-derive it.
  • THIS section owns the E0860/E0861 diagnostic-code verification (codes declared at error_code/mod.rs:87-88), the negative #compile_fail("E0860") / #compile_fail("E0861") pins, and the positive no-value break / continue spec-test matrix for the UNLABELED while...do form.
  • parser-desugar w-42fab897 owns the typeck-ownership / no-parse-marker architectural reconciliation (confirming the LoopContext IS the load-bearing detail and no parse-level while-derived marker exists), plus the while expression void-typing check. This section references that reconciliation rather than re-verifying it.
  • walking-skeleton open HYG-01-004 owns the labeled-while value-rejection matrix cells: break:w value (E0860) / continue:w value (E0861) inside while:w, plus break:outer / continue:outer from nested while/for/loop forms. This section defers those cells to HYG-01-004 and does NOT duplicate its matrix; the codes + push site are shared, so the cells reuse this section’s verified declaration site without re-enumeration here.

Spec References

while-loop-proposal.md Type + Error Messages (E0860/E0861); tests.md Negative Testing Protocol.

Work Items

  • E0860: break value inside while...do is a compile-time error (while...do is void) — enforced by the form-agnostic LoopContext break_value_allowed: false flag set at the LoopForm::While push (compiler_repo/compiler/ori_types/src/infer/expr/control_flow/loops.rs:211-217), the same flag mechanism for...do uses (the proposal states this is ‘just as in for…do’; the shared detail is the permission flag, not a for-specific code path). Emit via structured ori_diagnostic Diagnostic (code declared at error_code/mod.rs:87), not format! strings; message + help per proposal Error Messages.
  • E0861: continue value inside while is a compile-time error (while does not collect values) — same for-do-derived validation, keyed off typeck LoopForm::While loop-context (LoopForm::While push at compiler_repo/compiler/ori_types/src/infer/expr/control_flow/loops.rs:217; enum def compiler_repo/compiler/ori_types/src/infer/scope.rs:43); no parse-level marker exists.
  • Negative #compile_fail("E0860") + #compile_fail("E0861") spec tests pin exact error codes (per tests.md Negative Testing Protocol); positive break / continue (no value) inside while must NOT error.