Commit Graph

39816 Commits

Author SHA1 Message Date
Wojciech Różowski
47833725ea feat: add String simprocs to cbv (#12888)
This PR adds `String`-specific simprocs to `cbv` tactic.
2026-03-12 11:52:06 +00:00
Lean stage0 autoupdater
24acf2b895 chore: update stage0 2026-03-11 21:36:12 +00:00
Henrik Böving
d9ebd51c04 feat: option to ignore borrowing annotations completely (#12886)
This PR adds support for ignoring user defined borrow annotations. This
can be useful when defining
`extern`/`export` pairs as the `extern` might be infected by borrow
annotations while in `export`
they are already ignored.
2026-03-11 20:59:06 +00:00
Garmelon
6a2a884372 chore: migrate pkg tests (#12889)
Also refactor util.sh in the process, so test scripts become easier to
write (inspired in part by lake's test suite).
2026-03-11 18:55:46 +00:00
Joachim Breitner
4740e044c8 test: add elab_bench for string literal simp performance (#12883)
This PR adds a benchmark that measures `simp` performance on string
literal equality and inequality for various string lengths and
difference positions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:06:26 +00:00
Markus Himmel
4deb8d5b50 chore: do not use internal append in ToString instances for basic types (#12885)
This PR shifts some material in `Init` to make sure that the `ToString`
instances of basic types don't rely on `String.Internal.append`.
2026-03-11 15:25:54 +00:00
Lean stage0 autoupdater
d3db4368d4 chore: update stage0 2026-03-11 14:53:48 +00:00
Henrik Böving
652ca9f5b7 refactor: port EmitC to LCNF (#12781)
This PR ports the C emission pass from IR to LCNF, marking the last step
of the IR/LCNF conversion and thus enabling end-to-end code generation
through the new compilation infrastructure.
2026-03-11 14:19:54 +00:00
Sebastian Graf
a32be44f90 feat: add @[mvcgen_witness_type] attribute for extensible witness classification (#12882)
This PR adds an `@[mvcgen_witness_type]` tag attribute, analogous to
`@[mvcgen_invariant_type]`, that allows users to mark types as witness
types. Goals whose type is an application of a tagged type are
classified as witnesses rather than verification conditions, and appear
in a new `witnesses` section in the `mvcgen` tactic syntax (before
`invariants`).

Witnesses are concrete values the prover supplies (inspired by
zero-knowledge proofs), as opposed to invariants (predicates maintained
across iterations) or verification conditions (propositions to prove).
The test uses a ZK-inspired example where a `SquareRootWitness` value
must be provided by the prover, with the resulting constraint
auto-discharged.

Changes:
- `src/Lean/Elab/Tactic/Do/Attr.lean`: register `@[mvcgen_witness_type]`
tag attribute and `isMVCGenWitnessType` helper
- `src/Lean/Elab/Tactic/Do/VCGen/Basic.lean`: add `witnesses` field to
`State`, three-way classification in `addSubGoalAsVC`
- `src/Std/Tactic/Do/Syntax.lean`: add `witnesses` section syntax
(before `invariants`), extract shared `goalDotAlt`/`goalCaseAlt` syntax
kinds
- `src/Lean/Elab/Tactic/Do/VCGen.lean`: extract shared
`elabGoalSection`, add `elabWitnesses`, wire up witness labeling and
elaboration
- `tests/elab/mvcgenWitnessType.lean`: end-to-end tests for
witness-only, witness with `-leave`, and combined witness+invariant
scenarios

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 11:38:05 +00:00
Wojciech Różowski
e43b526363 feat: add cbv simprocs for arrays (#12875)
This PR adds `cbv` simprocs for getting elements out of arrays.
2026-03-11 11:03:22 +00:00
Sebastian Graf
734566088f feat: add withEarlyReturnNewDo variants for new do elaborator (#12881)
This PR adds `Invariant.withEarlyReturnNewDo`,
`StringInvariant.withEarlyReturnNewDo`, and
`StringSliceInvariant.withEarlyReturnNewDo` which use `Prod` instead of
`MProd` for the state tuple, matching the new do elaborator's output.
The existing `withEarlyReturn` definitions are reverted to `MProd` for
backwards compatibility with the legacy do elaborator. Tests and
invariant suggestions are updated to use the `NewDo` variants.

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

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 10:44:34 +00:00
Sebastian Graf
17807e1cbe feat: apply @[mvcgen_invariant_type] to Invariant, StringInvariant, StringSliceInvariant (#12880)
This PR applies `@[mvcgen_invariant_type]` to `Std.Do.Invariant` and
removes the hard-coded fallback in `isMVCGenInvariantType` that was
needed for bootstrapping (cf. #12874). It also extracts
`StringInvariant` and `StringSliceInvariant` as named abbreviations
tagged with `@[mvcgen_invariant_type]`, so that `mvcgen` classifies
string and string slice loop invariants correctly.

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

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 10:00:24 +00:00
Sebastian Ullrich
4450ff8995 chore: fix shlib rebuild detection under LAKE_USE_CACHE (#12879) 2026-03-11 08:35:53 +00:00
Henrik Böving
9fac847f5f perf: faster LCNF internalization (#12878)
This PR speeds up the LCNF internalization procedure.
2026-03-11 08:15:05 +00:00
Lean stage0 autoupdater
7acf5710c4 chore: update stage0 2026-03-11 08:49:43 +00:00
Sebastian Graf
220a242f65 feat: add @[mvcgen_invariant_type] attribute for extensible invariant classification (#12874)
This PR adds an `@[mvcgen_invariant_type]` tag attribute so that users
can mark
custom types as invariant types for the `mvcgen` tactic. Goals whose
type is an
application of a tagged type are classified as invariants rather than
verification
conditions. The hard-coded check for `Std.Do.Invariant` is kept as a
fallback
until a stage0 update allows applying the attribute directly.

A follow-up PR (after a stage0 update) will apply
`@[mvcgen_invariant_type]` to
`Std.Do.Invariant` and remove the hard-coded fallback.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 08:04:22 +00:00
Kim Morrison
ff6816a854 fix: avoid duplicate lake test registration when LAKE_CI is on (#12877)
This PR fixes a CMake error when the `lake-ci` label is used. The
previous
implementation appended the full `tests/lake/tests/` glob to a base list
that
already included `tests/lake/tests/shake/test.sh`, causing a duplicate
`add_test` name. This uses an if/else to select the appropriate glob
instead.

Discovered via https://github.com/leanprover/lean4/pull/12540 which has
the
`lake-ci` label.

🤖 Prepared with Claude Code

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

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 05:51:09 +00:00
Mac Malone
cd85b93d93 fix: lake-ci test glob (#12876)
This PR fixes an error in the test globs for `lake-ci`. With `lake-ci`,
the shake test was created twice, which CMake does not accept.
2026-03-11 03:31:44 +00:00
Jovan Gerbscheid
bb047b8725 fix: improve Name.isMetaprogramming (#12767)
This PR makes sure that identifiers with `Meta` or `Simproc` in their
name do not show up in library search results.

For example, `Nat.Simproc.eq_add_gt` can currently be suggested by
library search, even though it is an implementation detail.
Additionally, there are various declarations in mathlib in the
`Mathlib.Meta` namespace that we do not want to suggest.
2026-03-10 21:35:47 +00:00
Eric Wieser
2ea4d016c4 doc: remark that CoreM.toIO ignores ctx.initHeartbeats (#12859)
This is slightly surprising behavior, and so should be in the docstring.
2026-03-10 21:34:11 +00:00
Sebastian Graf
b626c6d326 test: apply simp theorems in SymM mvcgen' (#12872)
This PR adds support for simp/equational spec theorems in the SymM-based
`mvcgen'` tactic,
catching up with a feature that the original `mvcgen` has supported for
a long time.
Users can write `@[spec] theorem : get (m := StateT σ m) = fun s => pure
(s, s) := rfl`
instead of manually specifying equivalent Hoare triples. The equational
form is more
concise and natural for specs that simply unfold definitions.

The universe level normalization (`normalizeLevelsExpr`) applied in
`work` and the backward
rule constructors is a workaround; ideally this should be integrated
into
`preprocessMVar`/`preprocessExpr` in the SymM framework so all users
benefit.

Changes:
- Add `SpecTheoremKind` to distinguish triple vs simp specs in
`SpecTheoremNew`
- Add `mkSpecTheoremNewFromSimpDecl?` to create spec entries from
equational lemmas, filtering no-op equations
- Add `mkBackwardRuleFromSimpSpec` to build backward rules via
`Eq.mpr`/`congrArg`, with instance synthesis, projection reduction, and
`unfoldReducible` on the RHS
- Migrate simp theorems from `SimpTheorems` database during
`migrateSpecTheoremsDatabase`
- Normalize universe levels so structural matching in
`BackwardRule.apply` succeeds when `max u v` vs `max v u` arise from
different code paths
- Simplify `mkSpecContext` by removing the mock `simp` context
construction
- Use `mkBackwardRuleFromExpr` instead of `mkAuxLemma` for triple specs,
since the proof may contain free variables from the goal context
- Add `AddSubCancelSimp` benchmark case and test exercising the simp
spec code path
- Change `AddSubCancel` spec proofs from `mvcgen` to `mvcgen'`
(dogfooding)


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

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:15:04 +00:00
Wojciech Różowski
ebfc34466b refactor: use builtin_cbv_simproc for the control-flow simprocs in cbv (#12870)
This PR refactors control-flow simprocs in `cbv` to use
`builtin_cbv_simproc`.
2026-03-10 16:37:09 +00:00
Sebastian Graf
49ed556479 test: add VCGen test suite for sym mvcgen benchmarks (#12855)
This PR extracts the example programs from the sym mvcgen benchmarks
into
shared `Cases.*` modules so that both benchmarks and a new fast test
suite
can reuse them. It also renames `vcgen_deep_add_sub_cancel` to
`vcgen_add_sub_cancel_deep` for consistency.

The test suite (`test_vcgen.lean`) runs all cases at n=10, completing in
~2s vs minutes for the full benchmarks. It is wired up as a `lake test`
driver and integrated with the lean4 test/bench infrastructure via
`run_test`/`run_bench` scripts registered in `CMakeLists.txt`.

Benchmark output now uses aligned `CaseName(n):` labels. The `run_bench`
script extracts per-case vcgen and kernel timings into
`measurements.jsonl`.
Benchmarks run single-threaded (`LEAN_NUM_THREADS=1`) for
reproducibility.
`vcgen_get_throw_set` is excluded from benchmarks due to pathological
`instantiateMVars` behavior.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:32:13 +00:00
Sofia Rodrigues
e9060e7a4e fix: remove use of native_decide in the HTTP library (#12857)
This PR removes the use of `native_decide` in the HTTP library and adds
proofs to remove the `panic!`.
2026-03-10 13:25:22 +00:00
Lean stage0 autoupdater
0ebc126718 chore: update stage0 2026-03-10 13:16:48 +00:00
Sebastian Graf
daddac1797 feat: support expected type annotation in doPatDecl (#12866)
This PR adds `optType` support to the `doPatDecl` parser, allowing
`let ⟨width, height⟩ : Nat × Nat ← action` in do-notation. Previously,
only
the less ergonomic `let ⟨width, height⟩ : Nat × Nat := ← action`
workaround
was available. The type annotation is propagated to the monadic action
as an
expected type, matching `doIdDecl`'s existing behavior.

Both the legacy and new (BuiltinDo) elaborators are updated.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:42:03 +00:00
Lean stage0 autoupdater
04f676ec64 chore: update stage0 2026-03-10 11:49:44 +00:00
Wojciech Różowski
9b1973ada7 feat: add cbv_simproc infrastructure for user-extensible cbv simplification procedures (#12597)
This PR adds a `cbv_simproc` system for the `cbv` tactic, mirroring
simp's `simproc` infrastructure but tailored to cbv's three-phase
pipeline (`↓` pre, `cbv_eval` eval, `↑` post). User-defined
simplification procedures are indexed by discrimination tree patterns
and dispatched during cbv normalization.

New syntax:
- `cbv_simproc [↓|↑|cbv_eval] name (pattern) := body` — define and
register a cbv simproc
- `cbv_simproc_decl name (pattern) := body` — define without registering
- `attribute [cbv_simproc [↓|↑|cbv_eval]] name` — register an existing
declaration
- `builtin_cbv_simproc` variants for the internal use

New files:
- `src/Init/CbvSimproc.lean` — syntax and macros
- `src/Lean/Meta/Tactic/Cbv/CbvSimproc.lean` — types, env extensions,
registration, dispatch
- `src/Lean/Elab/Tactic/CbvSimproc.lean` — pattern elaboration and
command elaborators

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 10:59:13 +00:00
Wojciech Różowski
85d38cba84 feat: allow erasing cbv_eval attributes (#12851)
This PR add support for erasing `@[cbv_eval]` annotations using
`attribute [-cbv_eval]`, mirroring the existing `@[-simp]` mechanism for
simp lemmas.

The `CbvEvalEntry` now tracks the original declaration name (`origin`)
so that inverted theorems (`@[cbv_eval ←]`) can be erased by their
original name. The `CbvEvalState` stores individual entries alongside
the composed `Theorems` discrimination tree, allowing the tree to be
rebuilt from remaining entries after erasure. Erasure is properly scoped
via `modifyState`, so `attribute [-cbv_eval]` inside a `section` is
reverted when the section ends.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-10 09:40:19 +00:00
Henrik Böving
e5e7dcc00f chore: measure EmitC accurately (#12864) 2026-03-10 09:19:32 +00:00
Paul Reichert
ce6a07c4d9 feat: persistent hash map iterator (#12852)
This PR implements an iterator for `PersistentHashMap`.
2026-03-10 08:01:32 +00:00
Kim Morrison
320ddae700 feat: add lake-ci label to enable full Lake test suite (#12836)
This PR adds a `lake-ci` label that enables the full Lake test suite in
CI,
avoiding the need to temporarily commit and revert changes to
`tests/CMakeLists.txt`. The `lake-ci` label implies `release-ci` (check
level
3), so all release platforms are also tested.

Motivated by
https://github.com/leanprover/lean4/pull/12540#issuecomment-4000081071
where @tydeu requested running `release-ci` with Lake tests enabled,
which
previously required temporarily uncommenting a line in
`tests/CMakeLists.txt`.

Users can add it via a PR comment containing `lake-ci` on its own line,
or by
adding the label manually. CI automatically restarts when the label is
added.

Implementation:
- `ci.yml`: detect `lake-ci` label, set check level 3, pass
`-DLAKE_CI=ON` to cmake
- `tests/CMakeLists.txt`: `option(LAKE_CI ...)` conditionally enables
full `tests/lake/tests/` glob
- `restart-on-label.yml`: restart CI on `lake-ci` label
- `labels-from-comments.yml`: support `lake-ci` comment

🤖 Prepared with Claude Code

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 03:23:35 +00:00
Kim Morrison
ada53633dc feat: add grind.unusedLemmaThreshold option to report unused E-matching activations (#12805)
This PR adds a `set_option grind.unusedLemmaThreshold` that, when set to
N > 0
and `grind` succeeds, reports E-matching lemmas that were activated at
least N
times but do not appear in the final proof term. This helps identify
`@[grind]`
annotations that fire frequently without contributing to proofs.

🤖 Prepared with Claude Code

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 02:57:37 +00:00
Kim Morrison
e01cbf2b8f feat: add structured TraceResult to TraceData (#12698)
This PR adds a `result? : Option TraceResult` field to `TraceData` and
populates it in `withTraceNode` and `withTraceNodeBefore`, so that
metaprograms walking trace trees can determine success/failure
structurally instead of string-matching on emoji.

`TraceResult` has three cases: `.success` (checkEmoji), `.failure`
(crossEmoji), and `.error` (bombEmoji, exception thrown). An
`ExceptToTraceResult` typeclass converts `Except` results to
`TraceResult` directly, with instances for `Bool` and `Option`.
`TraceResult.toEmoji` converts back to emoji for display. This replaces
the previous `ExceptToEmoji` typeclass — `TraceResult` is now the
primary representation rather than being derived from emoji strings.

`withTraceNodeBefore` (used by `isDefEq`) uses
`ExceptToTraceResult.toTraceResult` directly, correctly handling `Bool`
(`.ok false` = failure) and `Option` (`.ok none` = failure), with
`Except.error` mapping to `.error`.

For `withTraceNode`, `result?` defaults to `none`. Callers can pass
`mkResult?` to provide structured results; when set, the corresponding
emoji is auto-prepended to the message.

Motivated by mathlib's `#defeq_abuse` diagnostic tactic
(https://github.com/leanprover-community/mathlib4/pull/35750) which
currently string-matches on emoji to determine trace node outcomes. See
https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/backward.2EisDefEq.2ErespectTransparency

🤖 Prepared with Claude Code

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 02:42:57 +00:00
Kyle Miller
71ff366211 feat: use unicode(...) in Init/Notation and elsewhere (#10384)
This PR makes notations such as `∨`, `∧`, `≤`, and `≥` pretty print
using ASCII versions when `pp.unicode` is false.

Continuation of #10373. Closes #1056.

This will require followup with a stage0 update and removal of the
ASCII-only `<=` and `>=` syntaxes from `Init.Notation`, for cleanup.
2026-03-09 22:17:32 +00:00
Henrik Böving
670360681f perf: handle match_same_ctor.het similar to matchers in compiler (#12850)
This PR optimizes the handling of `match_same_ctor.het` to make it emit
nice match trees as opposed to unoptimized CPS style code.

`match_same_ctor.het` is essentially a specialized kind of matcher where
we know that two objects are built from the same constructor and we wish
to call a continuation on their data. This means for every constructor
that contains data `het` takes one closure as an argument. Then after
matching on one of the objects every closure but the one relevant for
the match is released in every match arm, causing quadratic code
generation. This PR ensures that the `het` declarations get inlined and
then further processed by ordinary matcher and casesOn compilation,
thereby removing all of the continuations from the compiled code.
2026-03-09 22:02:06 +00:00
Paul Reichert
079db91c8c feat: append iterator combinator (#12844)
This PR provides the iterator combinator `append` that permits the
concatenation of two iterators.
2026-03-09 20:22:31 +00:00
Mac Malone
007e082b1c feat: bundle leantar with Lean (#12822)
This PR downloads a prebuilt release of `leantar` and bundles it with
Lean as part of the core build.
2026-03-09 20:10:59 +00:00
Paul Reichert
cdfde63734 feat: tree map toArray/keysArray lemmas (#12481)
This PR provides lemmas about `toArray` and `keysArray` on tree maps and
tree sets that are analogous to the existing `toList` and `keys` lemmas.
2026-03-09 20:04:59 +00:00
Joachim Breitner
2e06fb5008 perf: fuse fvar substitution into instantiateMVars (#12233)
This PR replaces the default `instantiateMVars` implementation with a
two-pass variant that fuses fvar substitution into the traversal,
avoiding separate `replace_fvars` calls for delayed-assigned MVars and
preserving sharing. The old single-pass implementation is removed
entirely.

The previous implementation had quadratic complexity when instantiating
expressions with long chains of nested delayed-assigned MVars. Such
chains arise naturally from repeated `intro`/`apply` tactic sequences,
where each step creates a new delayed assignment wrapping the previous
one. The new two-pass approach resolves the entire chain in a single
traversal with a fused fvar substitution, reducing this to linear
complexity.

### Terminology (used in this PR and in the source)

* **Direct MVar**: an MVar that is not delayed-assigned.
* **Pending MVar**: the direct MVar stored in a
`DelayedMetavarAssignment`.
* **Assigned MVar**: a direct MVar with an assignment, or a
delayed-assigned MVar with an assigned pending MVar.
* **MVar DAG**: the directed acyclic graph of MVars reachable from the
expression.
* **Resolvable MVar**: an MVar where all MVars reachable from it
(including itself) are assigned.
* **Updateable MVar**: an assigned direct MVar, or a delayed-assigned
MVar that is resolvable but not reachable from any other resolvable
delayed-assigned MVar.

In the MVar DAG, the updateable delayed-assigned MVars form a cut (the
**updateable-MVar cut**) with only assigned MVars behind it and no
resolvable delayed-assigned MVars before it.

### Two-pass architecture

**Pass 1** (`instantiate_direct_fn`): Traverses all MVars and
expressions reachable from the initial expression and instantiates all
updateable direct MVars (updating their assignment with the result),
instantiates all level MVars, and determines if there are any updateable
delayed-assigned MVars.

**Pass 2** (`instantiate_delayed_fn`): Only run if pass 1 found
updateable delayed-assigned MVars. Has an **outer** and an **inner**
mode, depending on whether it has crossed the updateable-MVar cut.

In outer mode (empty fvar substitution), all MVars are either unassigned
direct MVars (left alone), non-updateable delayed-assigned MVars
(pending MVar traversed in outer mode and updated with the result), or
updateable delayed-assigned MVars. When a delayed-assigned MVar is
encountered, its MVar DAG is explored (via `is_resolvable_pending`) to
determine if it is resolvable (and thus updateable). Results are cached
across invocations.

If it is updateable, the substitution is initialized from its arguments
and traversal continues with the value of its pending MVar in inner
mode. In inner mode (non-empty substitution), all encountered
delayed-assigned MVars are, by construction, resolvable but not
updateable. The substitution is carried along and extended as we cross
such MVars. Pending MVars of these delayed-assigned MVars are NOT
updated with the result (as the result is valid only for this
substitution, not in general).

Applying the substitution in one go, rather than instantiating each
delayed-assigned MVar on its own from inside out, avoids the quadratic
overhead of that approach when there are long chains of delayed-assigned
MVars.

**Write-back behavior**: Pass 2 writes back the normalized pending MVar
values of delayed-assigned MVars above the updateable-MVar cut (the
non-resolvable ones whose children may have been resolved). This is
exactly the right set: these MVars are visited in outer mode, so their
normalized values are suitable for storing in the mctx. MVars below the
cut are visited in inner mode, so their intermediate values cannot be
written back.

### Pass 2 scope-tracked caching

A `scope_cache` data structure ensures that sharing is preserved even
across different delayed-assigned MVars (and hence with different
substitutions), when possible. Each `visit_delayed` call pushes a new
scope with fresh fvar bindings. The cache correctly handles cross-scope
reuse, fvar shadowing, and late-binding via generation counters and
scope-level tracking.

The `scope_cache` has been formally verified:
`tests/elab/scopeCacheProofs.lean` contains a complete Lean proof that
the lazy generation-based implementation refines the eager
specification, covering all operations (push, pop, lookup, insert)
including the rewind lazy cleanup with scope re-entry and degradation.
The key correctness invariant is inter-entry gen list consistency
(GensConsistent), which, unlike per-entry alignment with `currentGens`,
survives pop+push cycles.

### Behavioral differences from original `instantiateMVars`

The implementation matches the original single-pass `instantiateMVars`
behavior with one cosmetic difference: the new implementation
substitutes fvars inline during traversal rather than constructing
intermediate beta-redexes, producing more beta-reduced terms in some
edge cases. This changes the pretty-printed output for two elab tests
(`1179b`, `depElim1`) but all terms remain definitionally equal.

### Tests

Correctness and performance tests for the new implementation were added
in #12808.

### Files

- `src/library/instantiate_mvars.cpp` — C++ implementation of both
passes (replaces `src/kernel/instantiate_mvars.cpp`)
- `src/library/scope_cache.h` — scope-aware cache data structure
- `src/Lean/MetavarContext.lean` — exported accessors for
`DelayedMetavarAssignment` fields
- `tests/elab/scopeCacheProofs.lean` — formal verification of
`scope_cache` correctness
- `tests/elab/1179b.lean.out.expected`,
`tests/elab/depElim1.lean.out.expected` — updated expected output

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:05:21 +00:00
fiforeach
37f10435a9 fix: make option linter.unusedSimpArgs respect linter.all (#12560)
This PR changes the way the linting for `linter.unusedSimpArgs` gets the
value from the environment. This is achieved by using the appropriate
helper functions defined in `Lean.Linter.Basic`.

The following now compiles without warning

```lean4
set_option linter.all false in
example : True := by simp [False]
```

Fixes #12559
2026-03-09 15:12:02 +00:00
Joachim Breitner
a4dd66df62 perf: bypass typeclass synthesis in SizeOf spec theorem generation (#12849)
This PR constructs SizeOf instances directly in SizeOf spec theorem
generation.

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

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 15:08:48 +00:00
Sebastian Graf
40e8f4c5fb chore: turn on new do elaborator in Core (#12656)
This PR turns on the new `do` elaborator in Init, Lean, Std, Lake and
the testsuite.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:38:33 +00:00
Garmelon
63098493b3 chore: add --force option to fix_expected.py (#12847)
Also uses shutil.copy instead of Path.copy. The latter was added only
recently in 3.14.
2026-03-09 12:21:04 +00:00
Michael Rothgang
fe3ba4dc4c fix: make the omit, unusedSectionVars and loopingSimpArgs linter respect linter.all (#12563)
This PR makes the `omit`, `unusedSectionVars` and `loopingSimpArgs`
linters respect the `linter.all` option:
when `linter.all` is set to false (and the respective linter option is
unset), the linter should not report errors.

Similarly to #12559, these linters should honour the linter.all flag
being set to false. These are all remaining occurrences of this pattern.

This fixes an issue analogous to #12559.
This PR and #12560 fix all occurrences of this pattern. (The only
question is around `RCases.linter.unusedRCasesPattern`: should this also
respect this? I have left this alone for now.)

Co-authored-by: fiforeach <249703130+fiforeach@users.noreply.github.com>
2026-03-09 11:58:02 +00:00
Sebastian Graf
e9e46f4199 chore: fix two semantic merge errors in SymM mvcgen (#12845) 2026-03-09 11:00:01 +00:00
Lean stage0 autoupdater
e2b500b204 chore: update stage0 2026-03-09 08:53:25 +00:00
Kyle Miller
e804829101 feat: have #eval elaborate variables (#11427)
This PR modifies `#eval e` to elaborate `e` with section variables in
scope. While evaluating expressions with free variables is not possible,
this lets `#eval` give a better error message than "unknown identifier."

Example:
```lean
section
variable (n : Nat)
/-- error: Cannot evaluate, contains free variable `n` -/
#guard_msgs in #eval n
end
```

The error is localized to `#eval`. It would be more friendly if the
error were to be placed on uses of free variables.

[Zulip
discussion](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Unknown.20identifier.20error.20messages.20for.20.60.23eval.60/near/560864544)
2026-03-09 04:52:08 +00:00
Kyle Miller
27b583d304 feat: mutually dependent structure default values, and avoiding self-dependence (#12841)
This PR changes the elaboration of the `structure`/`class` commands so
that default values have later fields in context as well. This allows
field defaults to depend on fields that come both before and after them.
While this was already the case for inherited fields to some degree, it
now applies uniformly to all fields. Additionally, when elaborating the
default value for a field, all fields that depend on it are cleared from
the context to avoid situations where the default value depends on
itself.

This addresses an issue reported by Aaron Liu [on
Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/default.20structure.20values.20can.20depend.20on.20themselves/near/578014370).
2026-03-09 04:15:06 +00:00
Kyle Miller
d8accf47b3 chore: use terminology "non-recursive structure" instead of "struct-like" (#12749)
This PR changes "structure-like" terminology to "non-recursive
structure" across internal documentation, error messages, the
metaprogramming API, and the kernel, to clarify Lean's type theory. A
*structure* is a one-constructor inductive type with no indices — these
can be created by either the `structure` or `inductive` commands — and
are supported by the primitive `Expr.proj` projections. Only
*non-recursive* structures have an eta conversion rule. The PR
description contains the APIs that were renamed.

Addresses RFC #5891, which proposed this rename. The change is motivated
by the need to distinguish between `structure`-defined structures,
structures, and non-recursive structures. Especially since #5783, which
enabled the `structure` command to define recursive structures,
"structure-like" has been easy to misunderstand.

Changes:
- Kernel: `is_structure_like()` -> `is_non_rec_structure()`
- `Lean.isStructureLike` -> `Lean.isNonRecStructure`
- `Lean.matchConstStructLike` -> `Lean.matchConstNonRecStructure`
- `Lean.getStructureLikeCtor?` -> `Lean.getNonRecStructureCtor?`
- `Lean.getStructureLikeNumFields` -> `Lean.getNonRecStructureNumFields`
- `Lean.Expr.proj`: extended and corrected documentation (note: despite
the fact that not every projection can be written as a recursor
application, I left in this claim since it seems good to document a
more-restrictive specification, and some users have requested the kernel
be more restrictive in this way)

Closes #5891
2026-03-09 03:44:38 +00:00