Commit graph

1275 commits

Author SHA1 Message Date
Henrik Böving
805012fb84
chore: revert "perf: improve over-applied cases in ToLCNF (#12284)" (#12693)
This PR reverts commit 9b7a8eb7c8. After
some more contemplation on
the implications of these changes I think this is not the direction we
want to move into.
2026-02-25 15:23:24 +00:00
Henrik Böving
e96d969d59
feat: support for del, isShared, oset and setTag (#12687)
This PR implements the LCNF instructions required for the expand reset
reuse pass.
2026-02-25 10:43:15 +00:00
Sebastian Ullrich
423671a6c0 feat: strengthen evalConst meta check 2026-02-25 11:40:02 +01:00
Henrik Böving
1bf43863e6
fix: better LCNF pretty printing (#12684) 2026-02-25 09:30:23 +00:00
Sebastian Ullrich
d0f8eb7bd6
fix: @[nospecialize] is never template-like (#12663)
This PR avoids false-positive error messages on specialization
restrictions under the module system when the declaration is explicitly
marked as not specializable. It could also provide some minor public
size and rebuild savings.
2026-02-23 20:00:36 +00:00
Henrik Böving
e16e2b2ffa
refactor: use Code.forM more (#12649) 2026-02-23 14:06:28 +00:00
Henrik Böving
d20b6ece58
refactor: port toposort from IR to LCNF (#12644)
This PR ports the toposorting pass from IR to LCNF.

We can already do this now as the remaining IR pipeline does not insert
any new auxiliary
declarations into the SCC so now is as good a time as ever to do it.
2026-02-23 10:09:32 +00:00
Sebastian Ullrich
ebd22c96ee
fix: mark failed compilations as noncomputable (#12625)
This PR ensures that failure in initial compilation marks the relevant
definitions as `noncomputable`, inside and outside `noncomputable
section`, so that follow-up errors/noncomputable markings are detected
in initial compilation as well instead of somewhere down the pipeline.

This may require additional `noncomputable` markers on definitions that
depend on definitions inside `noncomputable section` but accidentally
passed the new computability check.

Reported at
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Cryptic.20error.20message.20in.20new.20lean.20toolchain.3F.
2026-02-23 09:18:21 +00:00
Henrik Böving
527a07b3ad
refactor: remove SCC special casing for fetching signatures (#12619) 2026-02-20 22:45:39 +00:00
Henrik Böving
5c4f61aa26
refactor: remove unnecessary type correction heuristic from the compiler (#12617)
This PR removes the type correction heuristic from the RC pass as it is
already present in the
boxing pass. Previously the boxing pass did not try to correct types so
the RC pass did. We
discovered issues with not doing this in the boxing pass and
accidentally maintained two corrections
for a while. This PR merges both and removes the one from RC.
2026-02-20 14:57:04 +00:00
Henrik Böving
78df48bdf4
perf: put mapMonoM where sensible in the compiler (#12610) 2026-02-20 13:12:59 +00:00
Henrik Böving
de522117d7
refactor: move to consistent naming for fvars in LCNF (#12611) 2026-02-20 12:36:45 +00:00
Henrik Böving
8cd4c44055
feat: derived value analysis for Array.uget (#12604)
This PR makes the derived value analysis in RC insertion recognize
`Array.uget` as another kind of
"projection-like" operation. This allows it to reduce reference count
pressure on elements accessed
through uget.
2026-02-20 08:51:07 +00:00
Henrik Böving
43956fc069
feat: lazy initialization of closed terms (#12044)
This PR implements lazy initialization of closed terms. Previous work
has already made sure that ~70% of the closed terms occurring in core
can be statically initialized from the binary. With this the remaining
ones are initialized lazily instead of at startup.

For this we implement a small statically initializable lock that goes
with each term. When trying to access the term we quickly check a flag
to say whether it has already been initialized. If not we take the lock
and initialize it, otherwise we dereference the pointer and fetch the
value.
2026-02-20 08:45:15 +00:00
Sebastian Ullrich
ace52b38f2
chore: reserve compiler.relaxedMetaCheck option for staging preparation (#12600) 2026-02-19 17:41:46 +00:00
Henrik Böving
9f0b44b260
refactor: port RC insertion from IR to LCNF (#12548)
This PR ports the RC insertion from IR to LCNF.

In doing so it makes the entire code monadic as opposed to simulating a
ReaderT StateRefT stack manually.
2026-02-19 16:55:09 +00:00
Leonardo de Moura
b668a18a9d
refactor: rename instance_reducible to implicit_reducible (#12567)
This PR renames `instance_reducible` to `implicit_reducible` and adds a
new
`backward.isDefEq.implicitBump` option to prepare for treating all
implicit
arguments uniformly during definitional equality checking.

## Changes

**Rename `instance_reducible` → `implicit_reducible`:**
- Rename `ReducibilityStatus.instanceReducible` constructor to
`implicitReducible`
- Register new `[implicit_reducible]` attribute, keep
`[instance_reducible]` as alias
- Rename `isInstanceReducible` → `isImplicitReducible` (with deprecated
aliases)
- Update all references across src/ and tests/

The rename reflects that this reducibility level is used not just for
instances
but for any definition that needs unfolding during implicit argument
resolution
(e.g., `Nat.add`, `Array.size`).

**Add `backward.isDefEq.implicitBump` option:**
- When `true` (+ `respectTransparency`), bumps transparency to
`.instances` for
ALL implicit arguments in `isDefEqArgs`, not just instance-implicit ones
- Defaults to `false` for staging compatibility — will be flipped to
`true` after
  stage0 update
- Adds `// update me!` to `stage0/src/stdlib_flags.h` to trigger CI
stage0 update

## Follow-up (after stage0 update)
- Flip `backward.isDefEq.implicitBump` default to `true`
- Fix resulting test/module failures

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

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:19:16 +00:00
Henrik Böving
ad64f7c1ba
feat: LCNF inc/dec instructions (#12550)
This PR adds `inc`/`dec` instructions to LCNF. It should be a functional
no-op.
2026-02-18 10:55:16 +00:00
Henrik Böving
a5d0ab510e
fix: regression caused by LCNF boxing (#12522)
This PR fixes a regression caused by the porting of the IR boxing to the
LCNF boxing pass.
2026-02-17 11:28:25 +00:00
Leonardo de Moura
0d2a511bde
fix: type class resolution cache (#12286)
This PR ensures the type resolution cache properly caches results for
type classe containing output parameters.

It ensures the cache key for a query like
```
HAppend.{0, 0, ?u} (BitVec 8) (BitVec 8) ?m
```
should be independent of the specific metavariable IDs in output
parameter positions. To achieve this, output parameter arguments are
erased from the cache key. Universe levels that only appear in output
parameter types (e.g., ?u corresponding to the result type's universe)
must also be erased to avoid cache misses when the same query is issued
with different universe metavariable IDs.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2026-02-15 03:07:15 +00:00
Henrik Böving
92aec45057
perf: boxing a uint64 yields and object not a tobject (#12465)
This PR changes the boxed type of `uint64` from `tobject` to `object` to
allow for more precise reference counting.
2026-02-13 12:14:37 +00:00
Henrik Böving
4eabd86604
chore: put compiler off critical path (#12464) 2026-02-13 10:47:43 +00:00
Henrik Böving
9f64f53fef
refactor: port Boxing from IR to LCNF (#12458)
This PR ports the IR pass for box/unbox insertion to LCNF.
2026-02-13 09:56:50 +00:00
Markus Himmel
6cbaada1bf
feat: verification of String.positions, String.chars, String.revPositions, String.revChars, ForIn m String Char (#12456)
This PR verifies all of the `String` iterators except for the bytes
iterator by relating them to `String.toList`.

Along the way we define `String.posLE` and `String.posLT` analogously to
`String.posGE` and `String.posGT` and redefine `String.prev` to go
through `String.posLT`.

We also define and verify `String.positionsFrom` and
`String.revPositionsFrom`, which are the obvious generaliziations of
`String.positions` and `String.revPositions` starting at a positions
other than the start/end.

Finally, we get various lemmas about strings and positions, including
some nice induction principles `String.Pos.next_induction` and
`String.Pos.prev_induction`.

Of course, we also have all of the analogous results for `String.Slice`.
2026-02-12 15:32:44 +00:00
Henrik Böving
db12e64845
chore: mitigate noncomputable section issues in the code generator (#12453)
This is a mitigation for the fact that the upfront noncomputable checker
currently doesn't error out early enough in certain situations so we
violate invariants later on.
2026-02-12 12:34:49 +00:00
Henrik Böving
d9cea67e24
perf: fold Task.get (Task.pure x) to just x (#12446)
This PR adds a simplification rule for `Task.get (Task.pure x) = x` into
the LCNF simplifier. This
ensures that we avoid touching the runtime for a `Task` that instantly
gets destructed anyways.
2026-02-12 08:29:52 +00:00
Henrik Böving
975f81d560
fix: use getImpureSignature? everywhere (#12436)
This PR uses `getImpureSignature?` instead of the `findEnvDecl` from IR
in the LCNF compiler. We
were previously still relying on the IR function because only IR
contained proper borrow
annotations. Now we infer the borrow annotations on the LCNF level and
can thus use the LCNF
signatures.
2026-02-11 17:10:25 +00:00
Henrik Böving
cad960267b
refactor: port borrow inference to LCNF (#12413)
This PR ports the IR borrow pass to LCNF.
2026-02-11 12:08:17 +00:00
Sebastian Ullrich
bc30710c67
fix: LCNF.getImpureSignature? on imported decls (#12410) 2026-02-10 14:43:31 +00:00
Henrik Böving
611337ecee
doc: the different chunks of the pass manager (#12400) 2026-02-10 08:48:36 +00:00
Henrik Böving
7488201604
refactor: port IR.SimpCase to LCNF (#12384)
This PR ports the IR SimpCase pass to LCNF.
2026-02-10 08:35:31 +00:00
Henrik Böving
892475dcac
fix: LCNF casesOnCtor can only act if type correct (#12387)
This PR fixes an issue in LCNF simp where it would attempt to act on
type incorrect `cases`
statements and look for a branch, otherwise panic. This issue did not
yet manifest in production as
various other invariants upheld by LCNF simp help mask it but will start
to become an issue with the
upcoming changes.

This is the proper fix for #6957.
2026-02-09 12:44:01 +00:00
Sebastian Ullrich
ae79d14d27
feat: shake: track [csimp] uses (#12351)
This PR extends the `@[csimp]` attribute to be correctly tracked by
`lake shake`
2026-02-07 14:27:00 +00:00
Henrik Böving
9f2f33bd65
perf: more brave dead variable elimination (#12365) 2026-02-06 22:36:17 +00:00
Henrik Böving
f5e5914b54
fix: placement of saveImpure (#12366) 2026-02-06 22:05:22 +00:00
Henrik Böving
32fb1ccf1c
refactor: port IR elim_dead_vars to LCNF (#12356)
This PR moves the IR elim_dead_vars pass to LCNF. It cannot delete the
pass yet as it is still used
in later IR passes.
2026-02-06 17:01:59 +00:00
Henrik Böving
8d29c591e6
refactor: behavior of inline annotations in the compiler (#12344)
This PR changes the semantics of `inline` annotations in the compiler.
The behavior of the original `@[inline]` attribute remains the same but
the function `inline` now comes with a restriction that it can only use
declarations that are local to the current module. This comes as a
preparation to pulling the compiler out into a separate process.

Closes: #12334
2026-02-06 10:38:14 +00:00
Rob23oba
9b7a8eb7c8
perf: improve over-applied cases in ToLCNF (#12284)
This PR changes the handling of over-applied cases expressions in
`ToLCNF` to avoid generating function declarations that are called
immediately. For example, `ToLCNF` previously produced this:
```lean-4
set_option trace.Compiler.init true
/--
trace: [Compiler.init] size: 4
    def test x y : Bool :=
      fun _y.1 _y.2 : Bool :=
        cases x : Bool
        | PUnit.unit =>
          fun _f.3 a : Bool :=
            return a;
          let _x.4 := _f.3 _y.2;
          return _x.4;
      let _x.5 := _y.1 y;
      return _x.5
-/
#guard_msgs in
def test (x : Unit) (y : Bool) : Bool :=
  x.casesOn (fun a => a) y
```
which is now simplified to
```lean-4
set_option trace.Compiler.init true
/--
trace: [Compiler.init] size: 3
    def test x y : Bool :=
      cases x : Bool
      | PUnit.unit =>
        let a := y;
        return a
-/
#guard_msgs in
def test (x : Unit) (y : Bool) : Bool :=
  x.casesOn (fun a => a) y
```
This is especially relevant for #8309 because there `dite` is defined as
an over-applied `Bool.casesOn`.
2026-02-06 09:27:15 +00:00
Henrik Böving
8e5655516e
perf: put the compiler off the critical path (#12335) 2026-02-05 20:39:11 +00:00
Henrik Böving
c3779bc8d5
refactor: reset reuse pass to LCNF (#12315)
This PR migrates the IR ResetReuse pass to LCNF.
2026-02-05 15:54:46 +00:00
Sebastian Ullrich
b4d4e371d2
chore: shake core (#12276) 2026-02-05 09:10:32 +00:00
Kim Morrison
d49e5d8a3d Revert "chore: temporarily disable proofs for bootstrap"
This reverts commit c56a5732a5a215f7b74d3f7a5cefd8612cf50474.
2026-02-05 13:41:34 +11:00
Kim Morrison
7b12b504df chore: temporarily disable proofs for bootstrap
This adds `set_option debug.byAsSorry true` and `decreasing_by sorry` to
various files to allow bootstrapping with Config structure changes. These
changes will be restored after the bootstrap dance is complete.
2026-02-05 13:41:34 +11:00
Henrik Böving
34620ec1f6
perf: speedup some fvar handling in LCNF (#12298) 2026-02-03 20:52:16 +00:00
Henrik Böving
7ba76bd33e
refactor: port push_proj to LCNF (#12294)
This PR ports the `push_proj` pass from IR to LCNF. Notably it cannot
delete it from IR yet as the pass is still used later on.
2026-02-03 19:21:45 +00:00
Henrik Böving
3516b66019
chore: two typos in the impure refactoring (#12288) 2026-02-03 13:34:28 +00:00
Henrik Böving
26f6bc67ee
feat: lambda pure conversion in LCNF (#12272)
This PR shifts the conversion from LCNF mono to lambda pure into the
LCNF impure phase. This is preparatory work for the upcoming refactor of
IR into LCNF impure.

The LCNF impure phase differs from the other LCNF phases in two crucial
ways:
1. I decided to have `Decl.type` be the result type as opposed to an
arrows from the parameter types to the result type. This is done because
impure does not have a notion of arrows anymore so keeping them around
for this one particular purpose would be slightly odd.
2. In order to avoid cluttering up the olean size LCNF impure saves only
the signature persistently to the disk. This is possible because we no
longer have inlining/specialization at this point of compilation so all
we need is typing information (and potentially other environment
extensions) to guide our analyses.
2026-02-03 10:24:59 +00:00
Leonardo de Moura
4606c35c40
feat: @[instance_reducible] (#12247)
This PR adds the new transparency setting `@[instance_reducible]`. We
used to check whether a declaration had `instance` reducibility by using
the `isInstance` predicate. However, this was not a robust solution
because:

- We have scoped instances, and `isInstance` returns `true` only if the
scope is active.

- We have auxiliary declarations used to construct instances manually,
such as:

```lean
    def lt_wfRel : WellFoundedRelation Nat
```
    
`isInstance` also returns `false` for this kind of declaration.

In both cases, the declaration may be (or may have been) used to
construct an instance, but `isInstance`
returns `false`. Thus, we claim it is a mistake to check the
reducibility status using `isInstance`.
`isInstance` indicates whether a declaration is available for the type
class resolution mechanism,
not its transparency status.

**We are decoupling whether a declaration is available for type class
resolution from its transparency status.**

**Remak**: We need a update stage0 to complete this feature.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2026-02-01 03:03:16 +00:00
Sebastian Ullrich
85341d02ac
feat: immediate noncomputable check (#12028)
This PR gives a simpler semantics to `noncomputable`, improving
predictability as well as preparing codegen to be moved into a separate
build step without breaking immediate generation of error messages.

Specifically, `noncomputable` is now needed whenever an axiom or another
`noncomputable` def is used by a def except for the following special
cases:
* uses inside proofs, types, type formers, and constructor arguments
corresponding to (fixed) inductive parameters are ignored
* uses of functions marked `@[extern]/@[implemented_by]/@[csimp]` are
ignored
* for applications of a function marked `@[macro_inline]`,
noncomputability of the inlining is instead inspected

# Breaking change

After this change, more `noncomputable` annotations than before may be
required in exchange for improved future stability.
2026-01-30 16:07:25 +00:00
Henrik Böving
5ce756f350
refactor: introduce a phase separation to the IR (#12214)
This PR introduces a phase separation to the LCNF IR. This is a
preparation for the merge of
the old `Lean.Compiler.IR` and the new `Lean.Compiler.LCNF` framework.

The change parametrizes all relevant `LCNF` data structures over a
`Purity` parameter and
additionally carries around proofs that the `Purity` has certain values,
depending on what's
required. This is done as opposed to indexing the types over `Purity`
because we do (almost) never
have to store the `Purity` value for phase generic structures this way.
2026-01-30 09:42:29 +00:00