Commit graph

40328 commits

Author SHA1 Message Date
Kim Morrison
68764f5382
doc: add CLAUDE.md guidance on rebasing vs changing PR base (#13652)
This PR adds a short guidance note to `.claude/CLAUDE.md` clarifying
that "rebase onto X" requests should only change the local branch base,
never the PR's `--base` target on GitHub. The Lean4 workflow
specifically uses `nightly-with-mathlib` as a rebase target to get a
mathlib-tested snapshot for CI, while the PR continues to target
`master`.

🤖 Prepared with Claude Code

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 11:34:50 +00:00
Mac Malone
41ecccec6d
feat: lake: hoist compiled configurations (#13683)
This PR moves the compiled Lake configurations (e.g., `lakefile.olean`)
from the package's `.lake/config` directory to the workspace's
`.lake/config`. This removes a potential source contention between
workspaces sharing a dependency.
2026-05-08 18:00:37 +00:00
Julia Markus Himmel
819f4549d9
chore: remove some more String.length calls (#13687)
This PR drops another few `String.length`s out of the codebase.
2026-05-08 10:46:34 +00:00
Kim Morrison
85d46c351f
chore: pin test-summary action to v2.4 SHA to unblock CI (#13686)
This PR pins the `test-summary/action` GitHub Action to the immutable
commit SHA for `v2.4` to work around a broken upstream `v2` tag.
Upstream retagged `v2` to point at `v2.5`, which ships without the
bundled `index.js`, causing every job using the shared build template to
fail in the `Test Summary` post-step with `File not found:
'/home/runner/work/_actions/test-summary/action/v2/index.js'`, even when
all tests pass.

Pinning to the SHA (rather than another floating tag like `@v2.4`)
matches GitHub's [security
guidance](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions)
for third-party actions and avoids a repeat of this exact incident if
`v2.4` is later retagged. Dependabot is already configured for
`github-actions` updates in `.github/dependabot.yml`, so version bumps
remain low-cost.

Verification:
- `curl -sI
https://raw.githubusercontent.com/test-summary/action/v2/index.js`
returns 404
- `curl -sI
https://raw.githubusercontent.com/test-summary/action/31493c76ec9e7aa675f1585d3ed6f1da69269a86/index.js`
returns 200

The summary action is shared across every workflow that includes
`build-template.yml`, so this affects all CI Lake jobs, not just one.

🤖 Prepared with Claude Code

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 10:38:53 +00:00
Wojciech Różowski
a416b90d22
feat: remove redundant deprecation warnings (#13595)
This PR silences the `Linter.deprecated` warnings inside of definitions
that are themselves deprecated.


Closes #8942.
2026-05-07 15:43:34 +00:00
Julia Markus Himmel
79659457fb
chore: reduce usage of String.length (#13681)
This PR reduces the usage of `String.length` in our codebase.

This is just the first step of many towards eliminating `String.length`.
2026-05-07 14:27:06 +00:00
Sebastian Graf
422920f643
feat: mvcgen', an experimental SymM-based implementation mvcgen (#13644)
This PR adds an experimental tactic `mvcgen'` that will soon replace
`mvcgen`. It has been reimplemented from the ground up using the new
`SymM`-based framework for efficient symbolic evaluation and can
outperform `mvcgen` by a factor of >100x for some synthetic benchmarks.
`mvcgen'` aspires to be feature-complete with `mvcgen`. Known exceptions
currently are join point sharing, introduction of local specs and
smaller bugs.

The implementation of `mvgen'` used to live in the benchmark suite for
rapid prototyping; this commit merely moves it into the Lean toolchain.
Doing so results in an build time instruction count increase in
seemingly unrelated tests such as `elab/delayed_assign//instructions`;
the reason is that the builtin elaborator attribute now pulls in
substantially more import code on startup.

---------

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2026-05-07 12:53:02 +00:00
Sebastian Graf
049b7ebee2
feat: verifiable repeat/while loops (#13209)
This PR adds `whileM`, a counterpart to `Lean.Loop.forIn` that admits a
one-step unfolding lemma `whileM_eq` (impossible to prove for the
original `partial def`). `Lean.Loop.forIn` now expands to `whileM`, so
`repeat`/`while` keep working without source changes, and the
`Spec.whileM`/`Spec.forIn_loop` `@[spec]` theorems let `mvcgen`
discharge their bodies given a Nat variant and an `α ⊕ β` invariant.

`whileM.impl` is still a `partial def`, but returns a `Subtype
(whileM.Pred f a)` whose property pins the value to an `Acc.recOn` term
whenever an `Acc` and a `MonadAttach` witness exist; `whileM_eq`
extracts that property. A `@[implemented_by]` `whileM.erased` keeps the
runtime a tail call after specialization and would be unnecessary if the
compiler were able eta-expand through the trivial `Subtype` structure.
Supporting infrastructure:
`Internal.Ensures`/`MayReturn`/`ErasesTo`/`IsAttach` and `WPAdequate`
for `Id`/`ReaderT`/`StateT`/`ExceptT`/`OptionT`.

The resulting `while` loops take more work to optimize, hence a modest
increase in build time instructions.
2026-05-07 12:48:42 +00:00
Joachim Breitner
9151360469
fix: preserve symbol hover for fun_induction function target (#13678)
This PR ensures that one can hover over the function name in
fun_induction. Fixes #13673

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-05-07 12:09:36 +00:00
Sebastian Ullrich
443615f27e
test: remove printDecls test (#13677)
This is a test from the very beginnings of the elab framework, which has
since become the second-slowest test.
2026-05-07 11:18:33 +00:00
Wojciech Różowski
c17c4598bc
chore: refactor the usages of Meta.mkCongrArg with SymM primitives in cbv (#13665)
This PR replaces `Meta.mkCongrArg` call sites in `handleProj` and
`simplifyAppFn` are replaced with direct `congrArg` constructions that
reuse types already in the `Sym` pointer cache. A few stray unqualified
`inferType` / `getLevel` / `isDefEq` calls in the same file are also
routed through the cached `Sym` equivalents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 10:31:48 +00:00
Henrik Böving
355dca6f57
perf: optimize lean_dec_ref_cold (#13669)
This PR optimizes `lean_dec_ref_cold` by outlining the "freezing cold"
path and performing a small microarchitecural optimization. The latter
is better as it makes clear to LLVM that we believe the pointer to only
use 48 bits.
2026-05-07 08:18:39 +00:00
David Thrane Christiansen
5d5642107d
fix: elaborate and render blockquotes in Verso docstrings (#13670)
This PR adds support for blockquotes to Verso docstrings, which had been
missing before. It also substantially improves the robustness of
Verso->Markdown rendering of docstrings, especially the handling of
blockquote line prefixes.
2026-05-06 23:59:11 +00:00
Sebastian Graf
36a54dbe9c
test: mvcgen' with grind should fail when grind fails (#13672)
This PR fixes the semantics of `mvcgen' with grind`: it now logs an
error per VC that `grind` cannot close and throws at the end, instead of
silently leaving the unsolved VC as a residual. The previous
silent-fallback behaviour is preserved as `mvcgen' with (try grind)`,
which `elabPreTac` recognises and routes to the same efficient `.grind`
path with a `silent` flag.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2026-05-06 21:41:38 +00:00
Sebastian Graf
a81628ddbf
test: add BackwardRule.applyChecked debug wrapper for mvcgen' (#13671)
This PR adds a `+debug` config option to `mvcgen'` and a
`BackwardRule.applyChecked` wrapper around `BackwardRule.apply`. On
apply failure with `+debug` set, the wrapper retries on the
`unfoldReducible`-normalized goal type; if the retry succeeds, an
earlier step missed a normalization and `mvcgen'` raises a hard error
naming the rule (auto-derived from `rule.expr.getAppFn` when available)
and showing the original vs. normalized types.

---------

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2026-05-06 21:33:27 +00:00
Joachim Breitner
0c6785c68f
test: simplify cancellation_par test infrastructure (#13663)
This PR replaces the `check_cancel` two-way coordination protocol used
by
`tests/server_interactive/cancellation_par.lean` with a single tactic
`block_until_cancelled "<label>"`. The first invocation for a label
registers
a promise, prints `<label>: blocked`, and loops on
`Core.checkInterrupted`
until the cancel token fires (then `finally` resolves the promise). Any
later
invocation for the same label waits on that promise — so the test only
terminates if the first invocation actually exited the loop. If
cancellation
fails to propagate, the second invocation's `IO.wait` blocks forever and
the
test hangs (timeout = failure), with no false-success path.

The test was disabled in `tests/CMakeLists.txt` due to flakiness in the
old
two-way protocol; this PR re-enables it. Verified that reverting #13428
makes the test deadlock as expected.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 19:10:35 +00:00
Sebastian Graf
d34811b5c9
test: tidy Util.lean in the mvcgen' prototype (#13667)
This PR cleans up `tests/bench/mvcgen/sym/lib/VCGen/Util.lean`.

- Drops the four `mkApp{Rev,RevRange,Range,N}S` helpers that were
vendored locally; they are now public in `Lean.Meta.Sym.Internal`
(`Lean.Meta.Sym.AlphaShareBuilder`).
- Moves `Std.HashMap.getDM` out of the root `Std.HashMap` namespace into
`namespace VCGen` and relocates it to `RuleCache.lean`, where its only
call sites live.

---------

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2026-05-06 18:00:25 +00:00
Sebastian Graf
65906d9ccc
test: unfold reducible abbreviations in inline-elaborated invariant values (#13668)
This PR fixes an issue in the `mvcgen'` prototype where user-provided
invariant values were elaborated against a goal type containing
reducible abbreviations like `PostShape.args ps`, baking
`(PostShape.args PostShape.pure)` into the assignment instead of `[]`.

After `tryInlineInvariant` confirms the user tactic assigned the
invariant metavariable, reduce its assignment with `unfoldReducible`.
Fixes the `mvcgen'` migration path for several `tests/elab/*` proofs
that had been blocked on the entailment-phase apply failure.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2026-05-06 17:58:03 +00:00
Sebastian Ullrich
22abf93a59
chore: CLAUDE.md: test moddocs (#13662) 2026-05-06 14:03:06 +00:00
Kim Morrison
036bd4f0df
fix: withoutExporting around diagnostic reporting (#13630)
This PR fixes an "Unknown constant" error when `set_option diagnostics
true` is enabled in module mode under a `public section`. Diagnostic
output may reference private declarations such as `_match_*` and
`_sparseCasesOn_*` that are recorded in unfold counters; constructing
the message previously failed because the environment was in exporting
mode and could not resolve those names. The diagnostic-printing paths in
`Lean.Meta.Diagnostics.reportDiag` and
`Lean.Meta.Tactic.Simp.Diagnostics.reportDiag` now run under
`withoutExporting`.

Closes https://github.com/leanprover/lean4/issues/13581.

🤖 Prepared with Claude Code

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 13:47:26 +00:00
Eric Wieser
56fe75eef4
fix: prevent corruption of the small allocator state (#13548)
This PR fixes possible corruption when recovering from memory
exhaustion.

This code threw an `std::bad_alloc` in the case of memory exhaustion,
but left the small allocator in an inconsistent state when doing so.
This would mean any code catching and recovering from the allocation
failure would likely find itself with a corrupt small allocator.

While we could try and make this code exception safe in future, simply
making it panic is better than the status quo, and is consistent with
how we handle most other allocation failures.

changelog-please-rerun-the-changelog-ci
2026-05-06 13:46:03 +00:00
Sebastian Ullrich
e3eb9aa832
chore: rename reldebug preset to more appropriate relwithassert (#13657) 2026-05-06 13:27:53 +00:00
Henrik Böving
8d2b5d08a1
perf: upgrade to LLVM 22 (#13545)
This PR upgrades LLVM from version 19 to version 22. This brings general
performance improvements of up to 5% instructions depending on
benchmark.
2026-05-06 12:36:06 +00:00
Sebastian Ullrich
e6dfdfdcee
fix: reject attribute uses whose module is reachable only via IR (#13613)
This PR makes the elaborator reject `@[foo]` when the module that
registers `foo` is not visibly imported into the current file but merely
loaded as IR. Previously such uses silently elaborated but led to
divergence of cmdline and server behavior and caused `lake shake --fix`
to flip-flop on successive runs (#13599).
2026-05-06 11:55:43 +00:00
Wojciech Różowski
0e2088fc83
feat: upstream unreachableTactic linter (#13580)
This PR upstreams `unreachableTactic` linter from `batteries` to core
lean.
2026-05-06 11:55:26 +00:00
Henrik Böving
9533f3f5ac
doc: how to LLVM upgrade (#13656)
This PR documents how to perform an LLVM upgrade.
2026-05-06 10:03:53 +00:00
Wojciech Różowski
ea6e767078
feat: rename --clippy to --extra and run defaults under it (#13649)
This PR renames the `lake lint --clippy` flag to `--extra` and broadens
its scope so that it runs the default builtin linters together with the
non-default ones, instead of only the non-default ones. Use `--lint-all`
to additionally enable any other off-by-default linters.

The matching internal names follow: the namespace `Lean.Linter.Clippy`
becomes `Lean.Linter.Extra`, the option `linter.clippy` becomes
`linter.extra`, and the env-linter attribute form `@[builtin_env_linter
clippy]` becomes `@[builtin_env_linter extra]`.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 20:24:11 +00:00
Mac Malone
ad5ec0e196
feat: user-specified init fn when loading plugins (#13510)
This PR adds the ability to specify a name for the initialization
function of a Lean plugin on load.

* The `Lean.loadPlugin` API has gained a `initFn?` argument that
defaults to `none`. When `none`, the initialization function name will
be inferred from the shared library's name (as before).
* The CLI `--plugin` option can now have a initialization function
specified via `--plugin=path:initFn`.
* The `--setup` JSON configuration now also accepts`{"path": ...,
"initFn": ...}` for plugins.
2026-05-05 20:20:54 +00:00
Lean stage0 autoupdater
25ec7e5b0f chore: update stage0 2026-05-05 18:38:42 +00:00
Joachim Breitner
03bd8847dc
fix: distinguish recursive applications by source position (#13645)
This PR fixes the termination checker reporting errors at the wrong
recursive call site when a function contains structurally-identical
recursive calls at different source locations.

The `_recApp` `MData` attached to recursive applications carried the
attached `Syntax`, but two structurally-equal `MData` wrappers could be
merged by hashconsing/simplification, so the syntax of the first call
ended up associated with both call sites. We now also store the source
byte position as `_recAppPos`, which keeps the wrappers distinct.

Closes #13444.
2026-05-05 16:40:29 +00:00
Sebastian Ullrich
6998af1850
fix: record instances unfolded by wrapInstance as shake dependencies (#13579) 2026-05-05 15:00:23 +00:00
Henrik Böving
aa6fa1cf1a
chore: use the lean-llvm LLVM for benchmarking (#13634)
This PR makes radar use the LLVM that we actually ship to users (stored
at https://github.com/leanprover/lean-llvm). In doing so it also makes
the lake build compatible with lean-llvm, allowing us to do potential
release builds with lake in the future.
2026-05-05 14:26:08 +00:00
Garmelon
e47636cdca
chore: fix CI for PRs from external repos (#13643)
Those action runs don't have access to the READ_RUNNERS_TOKEN secret, so
they should just fall back to the namespace runner.

Also, this PR removes the permission checks again. They are failing for
some non-user authors (e.g. copilot) and could be removed anyways by a
malicious actor in a PR.
2026-05-05 13:38:54 +00:00
Sebastian Graf
42eb0385a5
test: bring Sym-based mvcgen' on par with mvcgen (#13578)
This PR brings the Sym-based `mvcgen'` to feature parity with `mvcgen`;
the only remaining gap is `+jp` (join-point handling).

The slight benchmark regressions are due to simplifying VCs out of
`SPred` form, hitting hardest on cases with linearly many VCs like
`PurePreCond`. The ~10% vcgen slowdown is worth it for the cleaner
user-visible VCs.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 13:17:20 +00:00
Henrik Böving
a43972c856
chore: don't use grind in HTTP (#13639) 2026-05-05 13:06:12 +00:00
Joachim Breitner
bd20c51ae4
feat: add trace.Meta.Tactic.simp.backwardDefEq (#13640)
This PR adds a trace event emitted whenever a `dsimp` (or rfl-only
`simp`) rewrite fires
because of a `[backward_defeq]`-tagged theorem (i.e., one that would not
have applied without `set_option backward.defeqAttrib.useBackward
true`).

Useful for finding where downstream code is silently relying on the
backwards escape hatch — a precursor to either re-tagging the lemma as
`[defeq]` or restructuring the proof so it works under the strict
defeq rules.
2026-05-05 13:02:27 +00:00
Eric Wieser
e4c0a5a511
fix: perform severity overrides before counting errors (#13589)
This PR ensures that the `lean --error=tag` flag actually sets a
non-zero exit code on promoted errors.

Closes #13588, fixing the feature introduced in #6362.
2026-05-05 09:31:50 +00:00
Eric Wieser
94a29d1952
fix: prevent undefined behavior without LEAN_MMAP (#13521)
This PR prevents undefined behavior in `readModuleDataParts #[]` on
configurations without `LEAN_MMAP`. Previously this would lead to
out-of-bounds indexing.
2026-05-05 07:42:20 +00:00
Eric Wieser
70098e432b
fix: handle interrupted reads (#13493)
This PR ensures that `import` gracefully processes `EINTR` errors from
the filesystem.

`read()` is allowed to return fewer bytes than requested, if it is
interrupted. If it is interrupted before returning any bytes, then it
returns `EINTR`. In either case, Lean should keep reading the file.
2026-05-05 07:41:52 +00:00
Eric Wieser
c9855f5dbf
fix: propagate memory errors in mpz.cpp (#13547)
This PR prevents silent allocation failures leading to memory corruption
when not using GMP.
2026-05-05 07:40:35 +00:00
Eric Wieser
a2c4b7305d
fix: indicate in readModuleDataParts if memory is exhausted (#13549)
This PR makes `readModuleDataParts` report a clearer error if there is
insufficient memory to load a module.

changelog-ignores-my-messages-unless-i-edit-the-description-afterwards
2026-05-05 07:38:46 +00:00
Leonardo de Moura
8ebd294673
fix: kernel projection panic in Sym.simp match reduction (#13635)
This PR fixes a `Sym.simp` panic ("unexpected kernel projection term
during simplification") that triggered when matcher iota-reduction
exposed kernel `Expr.proj` terms via struct-eta. For example, a `do`
block with a `for` loop whose state is a tuple, where `Sym.simp`
unfolds the equational lemma and then descends into a destructuring
match.
2026-05-05 03:20:20 +00:00
Garmelon
9e5c86eac9
chore: move more radar bench logic to this repo (#13633)
These commands were previously executed in the radar-bench-lean4
repository, but are now moved here for additional control.
2026-05-04 18:21:22 +00:00
Sebastian Ullrich
c8191c5e2c
refactor: align ScopedEnvExtension.exportEntry? with new PersistentEnvExtension.exportEntriesFn (#13628) 2026-05-04 15:35:59 +00:00
Garmelon
5f262d3b18
chore: update release tooling and docs (#13631) 2026-05-04 15:33:36 +00:00
Garmelon
666e8302c7
chore: use self-hosted actions runner for some runs (#13543) 2026-05-04 15:33:24 +00:00
Julia Markus Himmel
ba502f7027
chore: rename UInt8.ofNatTruncate to UInt8.ofNatClamp (#13627)
This PR renames `UInt8.ofNatTruncate` to `UInt8.ofNatClamp`.

The new name is more consistent with the rest of the library (e.g.,
`Int8.toNatClampNeg`) and also more clear. See also [#lean4 > Name of
UInt32.ofNatTruncate etc may be
wrong](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Name.20of.20UInt32.2EofNatTruncate.20etc.20may.20be.20wrong/with/591873604).

Historical note: during prehistoric times (in January 2024),
`UInt32.ofNatTruncate` (only the 32 bit version) was introduced for use
in the `simp` configuration. When I looked at the `UIntX` API more
properly later, I added the missing variants but didn't reconsider the
name.
2026-05-04 11:02:10 +00:00
Mac Malone
dae325700c
fix: lake: await needs before processing module headers (#13601)
This PR changes Lake's module import graph processing to await the
completion of any `needs` targets or other extra dependencies (such as
cloud releases). This both enables the `needs` targets to influence
header processing and prevents them from racing with said processing.

**Known Limitation:** This PR currently blocks on the `needs` targets
rather than running the import processing in a callback. This is done to
keep import processing simple and in a single thread. If this proves to
be a performance issue, this can be restructured in a future PR with a
more sophisticated refactor.

Closes #13598
2026-05-03 18:17:08 +00:00
Mac Malone
326f43aa3a
fix: lake: meta import transitive import artifacts (#13600)
This PR fixes a Lake issue where the IR for a `meta import`'s transitive
imports was not included in the import artifacts Lake provided to Lean
(e.g., via `--setup`). When using the Lake artifact cache, this could
produce "missing data file" errors due to absent IR.

Closes #13419

---------

Co-authored-by: Claude Code <noreply@anthropic.com>
2026-05-03 17:44:46 +00:00
Leonardo de Moura
316c39ffe4
fix: grind congruence-table invariant for lazy ite branches (#13624)
This PR fixes a `grind` congruence-table invariant violation that could
panic
when an `ite` branch was internalized lazily (after the condition became
`True`
or `False`) and that branch's equivalence class was later merged with
another.

`Internalize.lean` has a special case for `ite` that internalizes only
the
condition; the `then`/`else` branches are skipped and only internalized
later
on demand by `propagateIte`. The on-demand path (`applyCongrFun`) called
`internalize` for the branch but never called `registerParent` to add
the
parent `ite` to the branch's parent set in the e-graph. Subsequent
merges of
the branch's equivalence class then skipped re-hashing the `ite` in the
congruence table, leaving an orphan entry whose `congr` chain no longer
matched
the table's representative.

The fix adds the explicit `registerParent e rhs` that the standard
`for arg in args` loop in `Internalize.lean` would have made for an
ordinary
application argument; we are simply mirroring that pattern lazily. The
same
helper is reused by `propagateDIte`, but with parent registration
disabled
(controlled by a new `ite : Bool` parameter): for `dite` the `rhs`
propagated
upwards is a *constructed* reduction (built via `mkApp` from `e`'s
children,
possibly post-`preprocess`), not a structural argument of `e`, so
registering
`e` as its parent would be incorrect. The lambda branches of a `dite`
are
already eagerly internalized as parents of `e` by `Internalize.lean`, so
this
case does not need the fix.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:27:54 +00:00