Skip to content

feat: inject unreachable! after break-less repeat#13506

Merged
sgraf812 merged 1 commit into
masterfrom
sg/repeat-polymorphic
Apr 23, 2026
Merged

feat: inject unreachable! after break-less repeat#13506
sgraf812 merged 1 commit into
masterfrom
sg/repeat-polymorphic

Conversation

@sgraf812
Copy link
Copy Markdown
Contributor

@sgraf812 sgraf812 commented Apr 22, 2026

This PR appends unreachable! to the expansion of break-less repeat when the expected result type does not unify with PUnit. The continuation then has a polymorphic value, so the enclosing do block's result type is inferred without a user-written filler, and ControlInfo for break-less repeat can report noFallthrough honestly — dead-code warnings on subsequent elements are now actionable.

@sgraf812 sgraf812 force-pushed the sg/repeat-polymorphic branch from b388a6f to e92af04 Compare April 22, 2026 20:48
@sgraf812 sgraf812 added the changelog-language Language features and metaprograms label Apr 22, 2026
@sgraf812 sgraf812 enabled auto-merge April 22, 2026 20:51
@sgraf812 sgraf812 disabled auto-merge April 22, 2026 20:51
@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 22, 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 cae4decead7dae180b50b25f2225419a1ed4280e --onto b6f5892e2247b3ca3c9a535e286f26121656d10f. You can force Mathlib CI using the force-mathlib-ci label. (2026-04-22 21:49:06)

@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 cae4decead7dae180b50b25f2225419a1ed4280e --onto 3fc99eef102549c743c6c63547983319bfae6f01. You can force reference manual CI using the force-manual-ci label. (2026-04-22 21:49:08)

@sgraf812 sgraf812 force-pushed the sg/repeat-polymorphic branch from e92af04 to c7fc1cb Compare April 23, 2026 05:21
@sgraf812 sgraf812 requested a review from mhuisi as a code owner April 23, 2026 05:21
…-code warnings

When a `repeat` body has no `break`, the loop does not terminate
normally and the `ForIn.forIn` result type is fixed to `PUnit`. Using
such a `repeat` in a do block that expects a non-`Unit` result type
used to require a trailing `return`/`unreachable!` from the user. To
make matters worse, that trailing element was flagged as dead by the
`ControlInfo`-based warning, yet removing it broke the do block's
type, so the warning was not actionable and had to be suppressed.

This PR teaches `elabDoRepeat` to append its own `unreachable!` after
the `for _ in Loop.mk do ...` expansion when the body cannot `break`.
The `unreachable!` gives the continuation a polymorphic value, so the
enclosing do block's result type is inferred from context and the
user no longer needs to write any trailing filler. The
`ControlInfo` for break-less `repeat` now reports `noFallthrough`
(and `numRegularExits := 0`) honestly, so dead-code warnings fire on
any user-written element after the loop — and because the loop
supplies its own `unreachable!`, those warnings are actionable: the
user can simply delete the flagged element.

Co-authored-by: Rob23oba <robin.arnez@web.de>
@sgraf812 sgraf812 force-pushed the sg/repeat-polymorphic branch from c7fc1cb to 3365536 Compare April 23, 2026 05:44
@sgraf812 sgraf812 added this pull request to the merge queue Apr 23, 2026
Merged via the queue into master with commit e3d4240 Apr 23, 2026
21 checks passed
@sgraf812 sgraf812 deleted the sg/repeat-polymorphic branch April 23, 2026 08:34
pull Bot pushed a commit to justinlietz93/lean4 that referenced this pull request Jun 1, 2026
This PR makes the new `do` elaborator (leanprover#12459) the default by flipping
`backward.do.legacy` to `false`. Legacy behavior remains available via
`set_option backward.do.legacy true`.

New surface syntax that is now accepted (and may shadow user-defined
macros of the same shape):

* `while let pat := e do …`, `while let pat ← e do …`, and `while h :
cond do …` via a unified condition syntax (leanprover#13534).
* `let ⟨a, b⟩ : T ← act` propagates the type annotation to the monadic
action (leanprover#12866).
* `letConfig` options (`(eq := h)`, `+nondep`, `+usedOnly`, `+zeta`) on
do `let`/`have` (leanprover#13250, leanprover#13255). They are rejected on `let mut`, and
`+postponeValue`/`+generalize` are rejected outright.
* Anonymous dependent `if _ : p then … else …` now elaborates inside
`do` blocks (leanprover#13192).

Breaking changes:

* `do` notation now requires a `Pure` instance, not just `Bind`.
* The arms of `do match` are non-dependent by default; write `do match
(dependent := true)` to recover the legacy term-match expansion. The
patterns are still dependently refined (leanprover#12673), which subsumes many
former dependent uses.
* `try`/`catch` no longer accepts a body whose result type matches the
surrounding expected type only via coercion (leanprover#13849). The same
expression has never been accepted outside `do`.
* Unreachable code now triggers a warning instead of an error. Code
written after a `break`-less `repeat` is now reported as unreachable
(leanprover#13506).
* The syntax for `let pat := rhs | otherwise` and similar now scope over
the `doSeq` that follows. Furthermore, `otherwise` and the sequence that
follows are now `doSeqIndented` in order not to steal syntax from record
syntax.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog-language Language features and metaprograms 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