Commit graph

40306 commits

Author SHA1 Message Date
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
Leonardo de Moura
ee8acc14e2
fix: grind cast internalization order (#13625)
This PR fixes a `grind` internal error triggered when `cast` (or
`Eq.rec`, `Eq.ndrec`, `Eq.recOn`) is applied to an argument that has not
yet been internalized. `pushCastHEqs` was emitting `e ≍ a` before
internalizing the args of `e`, so the `rhs` of the heq had no enode and
the debug sanity check tripped. The call now runs after the args are
internalized.
2026-05-03 16:32:10 +00:00
Leonardo de Moura
1b23b051f3
fix: missing proof hints in grind propagators (#13623)
This PR fixes proof construction issues in the `grind` projection
propagators.
2026-05-03 14:51:03 +00:00
Leonardo de Moura
2d79ec2883
fix: another grind AC invariant (#13622)
This PR fixes another issue in the `grind` AC invariant checker.
2026-05-03 13:33:13 +00:00
Leonardo de Moura
fe3c7394fd
fix: grind AC invariant (#13614)
This PR fixes the invariant in `grind` AC. equations in the todo queue
are not fully simplified.
2026-05-03 02:19:51 +00:00
Leonardo de Moura
030397785c
fix: missing case in processLevel at SymM (#13612)
This PR improves the universe unifier used by `SymM`.
2026-05-02 17:52:43 +00:00
Leonardo de Moura
75e37def8c
fix: remove incorrect assertion at Sym/Simp/Have.lean (#13611)
This PR removes an incorrect assertion in the simproc used to simplify
`have`-expressions in `Sym.simp`.
2026-05-02 16:26:35 +00:00
Sebastian Ullrich
508a113242
feat: add .instances-transparency type-check diagnostics (#13368)
This PR adds infrastructure to help diagnose cases where tactics like
`unfold`
leave the goal in a state that is type-correct only at `.default`
transparency,
causing `rw`/`simp` to fail at `.instances` transparency.

Changes:
- Add a `transparency` parameter to `Meta.check` (defaults to `.all`)
- Add `withInstancesTypeCheckNote` which appends a
lazy note to tactic errors when the target is not type-correct at
`.instances`
- Wrap `rw`, `simp`, `dsimp`, and `simp_all` at the Elab level
- Add opt-in `linter.tacticCheckInstances` that proactively checks every
  tactic goal and reports semireducible defs that should be marked
`@[implicit_reducible]`, using diagnostic counter diffing between
`.default`
  and `.instances` checks
2026-05-02 12:17:51 +00:00
Sebastian Ullrich
b7ca76a96e
chore: refine PR description guidance in .claude/CLAUDE.md (#13597)
Keep it short and user-level in the first paragraph
2026-05-02 12:02:25 +00:00
Sebastian Ullrich
4b8e74b27a
chore: disable flaky test (#13603) 2026-05-02 11:58:17 +00:00
Sebastian Ullrich
06ac472859
feat: detect further sub-instances in wrapInstance (#13536)
This PR extends the procedure behind `inferInstanceAs`/`def ...
deriving` to continue recursion through the class graph even when a
(local) instance to wrap was found in order to re-use already-wrapped
instance of subclasses.
2026-05-02 11:55:04 +00:00
Sebastian Ullrich
c53c4b4d2e
fix: prevent private default instances from leaking into public scope (#13596)
This PR fixes private(ly imported) default instances from accidentally
being used in public signatures, leading to follow-up errors.

As reported at
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Elaboration.20of.20heterogeneous.20mul.20with.20the.20module.20system
2026-05-02 07:53:44 +00:00
David Thrane Christiansen
659249a7df
fix: always fail on unsolved metavariables after Verso docstring elab (#13574)
This PR ensures consistent metavariable behavior between Verso
docstrings and Verso moduledocs by sharing more code between their
elaborators. It also improves the error message when a metavariable leak
is prevented.
2026-05-01 22:34:52 +00:00
Leonardo de Moura
53db221124
fix: disable model-based theory combination in grind derived tactics (#13593)
This PR disables model-based theory combination (`mbtc`) in `grind`'s
`NoopConfig`, which is the base configuration used by the derived
tactics `lia`, `linarith`, `cutsat`, `order`, and `ring`. Without this
fix, these tactics could engage in wasteful reasoning via theory
combination, causing them to run for a long time (or hit the
deterministic timeout) on problems they are not designed to solve. With
this fix, these tactics fail quickly on out-of-scope problems, as
expected.

Closes #13573.
2026-05-01 01:45:17 +00:00
Leonardo de Moura
a9946fe4ac
fix: case-split on arithmetic implications with And/Or antecedents (#13590)
This PR makes `lia` (and `grind`'s arithmetic case-split heuristic)
recognize
implications whose antecedent is an `And` or `Or` of arithmetic
predicates as
relevant case-split candidates. Previously, `Arith.isRelevantPred` only
matched
`Not`, `LE`, `LT`, `Eq`, and `Dvd`. With `splitImp := false` (the
default),
implications `p → q` are added as split candidates only when `p` is
arith-relevant, so a hypothesis like `(b ≤ e ∧ e < b + c → a ≤ e ∧ e < a
+ d)`
was never registered as a candidate. cutsat/lia would then find a
satisfying
assignment for the constraints it had been told about, but that
assignment
would not necessarily satisfy the original implication, yielding the bad
counterexample reported in #13575.

After this change, `isRelevantPred` recurses through `And` and `Or`
(returning
`true` if either operand is relevant), so the implication is split,
modus
ponens fires in the True branch, and cutsat/lia closes the False branch
via the
disjunction over negated atoms.

Closes #13575.
2026-04-30 23:15:34 +00:00
Wojciech Różowski
84f8c167c4
feat: script for finding deprecated options, modules and syntax (#13586)
This PR adds a script that imports the target modules and reads an
appropriate information from environment extensions about deprecated
modules, options and usage of deprecated syntax.
2026-04-30 17:30:43 +00:00
Leonardo de Moura
427e3bcdbc
fix: limit ring solver polynomial degree in grind (#13585)
This PR adds a `ringMaxDegree` configuration option (default `1024`)
that bounds the maximum degree of polynomials processed by the `grind`
ring solver. Equality constraints whose polynomial exceeds this
threshold are discarded (with an issue reported once per goal),
preventing pathological degree explosion on inputs such as `r ^ (2 ^ 250
- 1)`.

This PR also introduces `Poly.simpM?`, a monadic version of `Poly.simp?`
built on the existing safe arithmetic primitives (`mulMonM`, `combineM`,
`mulConstM`) in `Grind.Arith.CommRing.SafePoly`. The previous
reflection-oriented `Poly.simp?` in `Sym.Arith.Poly` lacked the abort
mechanisms needed during proof search, so the simplification path used
by `EqCnstr` now goes through the safe variant. A regression test
`tests/elab/grind_ring_degree_explosion.lean` ensures `grind` fails
quickly on high-degree problems.
2026-04-30 14:00:00 +00:00
Kyle Miller
19baa470e5
feat: MVarId.assertAfter fvar alias info, MVarId.replace mvar dependencies, specialize tactic using eta arguments (#13528)
This PR gives the `specialize` tactic the ability to instantiate
universal quantifiers other than the first using `specialize h (y := v)`
syntax. It also fixes an issue where `MVarId.assertAfter` did not record
variable alias information, and an issue where `MVarId.replace` and
`MVarId.replaceLocalDecl` did not take metavariables into account when
calculating dependencies. Additionally it fixes some uninstantiated
metavariables bugs, including one in the Infoview tactic state
hypothesis diff.

The `specialize` tactic now uses `Lean.MVarId.replace` to simplify the
implementation, and as a consequence it tries to keep the specialized
hypothesis close to its original spot in the local context.

Additional metaprogramming API:
- `Lean.Expr.getLambdaBody` to accompany `Lean.Expr.getNumHeadLambdas`
- `Lean.LocalContext.setType`, `Lean.MetavarContext.setFVarType`,
`Lean.MVarId.setFVarType`
- `Lean.MVarId.assertAfter'` to assert a new hypothesis as early as
possibly in the context where it is well-formed, as a frontend to
`Lean.MVarId.assertAfter`, which assumes the new hypothesis is
well-formed

Breaking change: metaprograms cannot assume that `MVarId`s change if
metavariables are assigned. For example, the `change` tactic will no
longer change `MVarId`s if the only effect is incidental metavariable
assignments.

Mathlib impact: this revealed many `dsimp`s that did nothing and could
be deleted.

Closes #9893
2026-04-30 10:36:29 +00:00
Sebastian Graf
ad5a3291dc
chore: switch Invariant helpers from abbrev to def + @[simp] (#13583)
This PR changes `Invariant`, `StringInvariant`, and
`StringSliceInvariant` from `abbrev` to `@[spec_invariant_type, simp,
grind =] def`, so that they remain visible as applications of a named
constant in proof states (where `SymM` does not unfold `def`s) and can
be detected as invariant types by `isSpecInvariantType`. The `@[simp,
grind =]` annotations ensure they still unfold on demand under `simp`
and `grind`.
2026-04-30 09:57:44 +00:00
Joachim Breitner
9efe4283e2
fix: propagate parent cancel token to parallel tactic subtasks (#13428)
This PR fixes parallel tactic combinators (`attempt_all_par`,
`first_par`) leaking their subtasks when the server cancels elaboration
on re-elaboration. Subtasks spawned via `CoreM.asTask` (and its
`MetaM`/`TermElabM`/`TacticM` variants) get a fresh `IO.CancelToken`,
which previously had no link to the parent token; `cancelRec` would set
the command-level token but the children kept running.

The fix is one line in `CoreM.asTask`: when a parent token is in scope,
register `cancelToken.set` as an `onSet` callback on the parent.
Server-level cancellation now flows down to every parallel subtask, and
`Core.checkInterrupted` inside the child sees the token set as expected.

Fixes #13300.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-30 09:22:33 +00:00
Sebastian Graf
906d9cf848
feat: add SPred and PostCond entailment lemmas (#13582)
This PR adds several entailment-related lemmas to `Std.Do.SPred` and
`Std.Do.PostCond`, intended for goal-decomposition during program
verification proof automation.

- `SPred.down_pure_nil` and `SPred.apply_pure_cons` (existing `rfl`
lemmas) become `@[simp, grind =]`. Drops the now-redundant `pure_cons`
argument from `simp` in `conjunction_apply`.
- New `SPred.entails_nil_intro` and `SPred.entails_nil_pure_intro`:
introduction forms for `entails` at `SPred []`, mirroring the existing
`entails_cons_intro`.
- New `SPred.down_pure_intro`: derive `(pure φ).down` from `φ`.
- New `SPred.apply_pure_cons_entails_l`/`_r`: peel a state argument from
`pure (σ::σs) φ s` on either side of `⊢ₛ`.
- New `Std.Do.ExceptConds.entails.pure`: closes any `⊢ₑ` goal at
`PostShape.pure`, where `ExceptConds.entails` reduces to `True`.
2026-04-30 06:30:49 +00:00
Wojciech Różowski
2b5d154a4c
feat: upstream unnecessarySeqFocus linter (#13540)
This PR upstreams `unnecessarySeqFocus` linter from batteries to core
lean as a "clippy" linter - i.e. one that is disabled by default and
executed by `lake lint --clippy`.

---------

Co-authored-by: Mac Malone <tydeu@hatpress.net>
Co-authored-by: Thomas R. Murrills <68410468+thorimur@users.noreply.github.com>
2026-04-29 14:51:10 +00:00
Sebastian Graf
e6f44eeeec
test: regression tests for do issues fixed by the new elaborator (#13541)
This PR adds regression tests for `do`-notation issues that the new
elaborator fixes:

* `tests/elab/doNotation7.lean` collects reproducers for #2663, #2676,
#3126, #5607, #6426, and #8119.
* `tests/elab/12229.lean` covers the `logInfo` and `Std.TreeMap`
reproducers from #12229.
2026-04-29 14:37:23 +00:00