Skip to content

chore: remove repeat/while macro_rules bootstrap from Init.While#13479

Merged
sgraf812 merged 1 commit into
masterfrom
sg/remove-init-while-macros
Apr 19, 2026
Merged

chore: remove repeat/while macro_rules bootstrap from Init.While#13479
sgraf812 merged 1 commit into
masterfrom
sg/remove-init-while-macros

Conversation

@sgraf812
Copy link
Copy Markdown
Contributor

This PR removes the transitional macro_rules for repeat, while, and repeat ... until from Init.While. After the latest stage0 update, the @[builtin_macro] and @[builtin_doElem_elab] definitions in Lean.Elab.BuiltinDo.Repeat are picked up directly, so the bootstrap duplicates in Init.While are no longer needed. Init.While now only provides the Loop type and its ForIn instance.

This PR also adjusts repeat's ControlInfo to match for ... in: its numRegularExits is now unconditionally 1 rather than if info.breaks then 1 else 0. Reporting 0 when the body has no break causes inferControlInfoSeq (in any enclosing sequence whose ControlInfo is inferred — e.g. a surrounding for/if/match/try body) to stop aggregating after the repeat and miss any return/break/continue that follows. The corresponding elaborator then sees the actual control flow disagree with the inferred info and throws errors like Early returning ... but the info said there is no early return. The new test in tests/elab/newdo.lean pins down the regression. See #13437 for further discussion.

This PR removes the transitional `macro_rules` for `repeat`, `while`, and
`repeat ... until` from `Init.While`. After the latest stage0 update, the
`@[builtin_macro]` and `@[builtin_doElem_elab]` definitions in
`Lean.Elab.BuiltinDo.Repeat` are picked up directly, so the bootstrap
duplicates in `Init.While` are no longer needed. `Init.While` now only
provides the `Loop` type and its `ForIn` instance.

This PR also adjusts `repeat`'s `ControlInfo` to match `for ... in`:
its `numRegularExits` is now unconditionally `1` rather than
`if info.breaks then 1 else 0`. Reporting `0` when the body has no
`break` made callers treat the continuation as dead code, which broke
common patterns where the continuation has a non-`Unit` result type
(see discussion on #13437).
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Apr 19, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 91aa82da7f7c0d923ab0c0a76c5c2627d3fb70e5 --onto 80cbab16420b90104647a795a18f9890fd8150e8. You can force Mathlib CI using the force-mathlib-ci label. (2026-04-19 17:25:00)

@leanprover-bot
Copy link
Copy Markdown
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 91aa82da7f7c0d923ab0c0a76c5c2627d3fb70e5 --onto 3fc99eef102549c743c6c63547983319bfae6f01. You can force reference manual CI using the force-manual-ci label. (2026-04-19 17:25:02)

@sgraf812 sgraf812 added this pull request to the merge queue Apr 19, 2026
Merged via the queue into master with commit 81f559b Apr 19, 2026
19 checks passed
sgraf812 added a commit that referenced this pull request Apr 20, 2026
This PR fixes `inferControlInfoSeq` and `ControlInfo.sequence` to keep
aggregating `breaks`/`continues`/`returnsEarly`/`reassigns` past
elements whose `ControlInfo` reports `numRegularExits := 0`. Previously
the analysis short-circuited at such elements, causing the inferred
info to drop any `return`/`break`/`continue` that followed. The
elaboration framework only skips subsequent doElems syntactically for
top-level `return`/`break`/`continue` (via
`elabAsSyntacticallyDeadCode`); for every other `numRegularExits == 0`
case (e.g. a `match`/`if`/`try` whose branches all terminate, or a
`repeat` without `break`) the elaborator keeps visiting the
continuation, and the for/match elaborator then tripped its invariant
check with "Early returning ... but the info said there is no early
return". With this change the inferred info matches what the
elaborator actually sees, which also removes the need for the
`numRegularExits := 1` workaround on `repeat` introduced in #13479.
sgraf812 added a commit that referenced this pull request Apr 20, 2026
This PR fixes `inferControlInfoSeq` and `ControlInfo.sequence` to keep
aggregating `breaks`/`continues`/`returnsEarly`/`reassigns` past
elements whose `ControlInfo` reports `numRegularExits := 0`. Previously
the analysis short-circuited at such elements, causing the inferred
info to drop any `return`/`break`/`continue` that followed. The
elaboration framework only skips subsequent doElems syntactically for
top-level `return`/`break`/`continue` (via
`elabAsSyntacticallyDeadCode`); for every other `numRegularExits == 0`
case (e.g. a `match`/`if`/`try` whose branches all terminate, or a
`repeat` without `break`) the elaborator keeps visiting the
continuation, and the for/match elaborator then tripped its invariant
check with "Early returning ... but the info said there is no early
return". With this change the inferred info matches what the
elaborator actually sees, which also removes the need for the
`numRegularExits := 1` workaround on `repeat` introduced in #13479.
github-merge-queue Bot pushed a commit that referenced this pull request Apr 20, 2026
…3486)

This PR fixes `inferControlInfoSeq` and `ControlInfo.sequence` to keep
aggregating `breaks`/`continues`/`returnsEarly`/`reassigns` past
elements whose `ControlInfo` reports `numRegularExits := 0`. Previously
the analysis short-circuited at such elements, so any trailing
`return`/`break`/`continue` was missing from the inferred info. The
elaboration framework only skips subsequent doElems syntactically for
top-level `return`/`break`/`continue`; for every other `numRegularExits
== 0` case (e.g. a `match`/`if`/`try` whose branches all terminate, or a
`repeat` without `break`) the elaborator keeps visiting the continuation
and the for/match elaborator then tripped its invariant check with
`Early returning ... but the info said there is no early return`. With
this change the inferred info matches what the elaborator actually sees,
which also removes the need for the `numRegularExits := 1` workaround on
`repeat` introduced in #13479.
@sgraf812 sgraf812 deleted the sg/remove-init-while-macros branch April 21, 2026 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants