Commit graph

772 commits

Author SHA1 Message Date
Eric Wieser
848832dd61
chore: demote a panic to an exception in saveModuleData (#9127)
This PR makes `saveModuleData` throw an IO.Error instead of panicking,
if given something that cannot be serialized. This doesn't really matter
for saving modules, but is handy when writing tools to save auxiliary
date in olean files via Batteries' `pickle`.

The caller of this C++ function already is guarded in a `try`/`catch`
that promotes from a `lean::exception` to an `IO.userError`.

A simple test of this in the web editor is
```
import Batteries

#eval pickle "/tmp/foo.txt" fun x : Nat => x
```
which crashes before this change.

---------

Co-authored-by: Laurent Sartran <lsartran@google.com>
2025-09-02 12:25:45 +00:00
Mac Malone
db3fb47109
refactor: port more of shell.cpp to Lean (#10086)
This PR ports more of the post-initialization C++ shell code to Lean.

All that remains is the initialization of the profiler and task manager.
As initialization tasks rather than main shell code, they were left in
C++ (where the rest of the initialization code currently is).

The `max_memory` and `timeout` Lean options used by the the `--memory`
and `--timeout` command-line options are now properly registered. The
server defaults for max memory and max heartbeats (timeout) were removed
as they were not actually used (because the `server` option that was
checked was neither set nor exists).

This PR also makes better use of the module system in `Shell.lean` and
fixes a minor bug in a previous port where the file name check was
dependent on building the `.ilean` rather than the `.c` file (as was
originally the case).

Fixes #9879.
2025-08-26 20:02:42 +00:00
Henrik Böving
6d5ce9b87f
refactor: implement IO.waitAny using Lean (#9732)
This PR re-implements `IO.waitAny` using Lean instead of C++. This is to
reduce the size and
complexity of `task_manager` in order to ease future refactorings.

There is an import behavioral change of `IO.waitAny` in this PR.
Consider a situation where we have
two promises `p1`, `p2` and call `IO.waitAny [p1.result!, p2.result!]`
and `p1` resolves instantly.
Previously this would just return the result of `p1` and require nothing
else. With the new
implementation if `p2` is released before being resolved this can cause
a panic, even if
`IO.waitAny` has already finished. I argue that this is reasonable
behavior, given that an
invocation of `result!` promises that the promise will eventually be
resolved.
2025-08-06 13:09:15 +00:00
Rob23oba
d817fb0ef3
fix: handle NUL bytes in IO functions (#9616)
This PR introduces checks to make sure that the IO functions produce
errors when inputs contain NUL bytes (instead of ignoring everything
after the first NUL byte).
2025-08-01 06:12:53 +00:00
Mario Carneiro
7cdd65d5fb
fix: build with libuv pre-1.45.0 (part 2) (#9652)
This PR continues #9644 , fixing the core build when using an older
system libuv.

This only affected users building Lean from scratch, since the lean
binaries we ship as part of toolchains statically link their own copy of
libuv 1.50+.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-08-01 05:53:55 +00:00
Markus Himmel
33eac4497b
fix: build with libuv pre-1.45.0 (#9644)
This PR fixes the core build when using an older system libuv.

This only affected users building Lean from scratch, since the `lean`
binaries we ship as part of toolchains statically link their own copy of
libuv 1.50+.
2025-07-31 13:18:41 +00:00
Rob23oba
b7ab7ea745
fix: behavior of String.next (#9449)
This PR fix the behavior of `String.next` on the scalar boundary (`2 ^
63 - 1` on 64-bit platforms).

Closes #9440
2025-07-22 06:48:33 +00:00
Rob23oba
b7f433c5b9
fix: behavior of String.prev (#9441)
This PR fixes the behavior of `String.prev`, aligning the runtime
implementation with the reference implementation. In particular, the
following statements hold now:
- `(s.prev p).byteIdx` is at least `p.byteIdx - 4` and at most
`p.byteIdx - 1`
- `s.prev 0 = 0`
- `s.prev` is monotone

Closes #9439
2025-07-21 10:50:14 +00:00
Eric Wieser
0106ca3bec
fix: undefined symbol without LEAN_USE_GMP (#9106)
This PR fixes `undefined symbol: lean::mpz::divexact(lean::mpz const&,
lean::mpz const&)` when building without `LEAN_USE_GMP`

This fixes a regression in #8089
2025-07-03 16:50:21 +00:00
Eric Wieser
232443371b
perf: add missing std::moves (#9107)
Continues from #4700.

This will save a handful of refcounts here and there.
2025-07-01 12:39:12 +00:00
Eric Wieser
72f421054d
fix: do not truncate at null bytes in panic messages (#9103)
This PR prevents truncation of `panic!` messages containing null bytes.

The C api for `lean_panic` is left untouched.

Closes #9102
2025-07-01 11:34:16 +00:00
Sofia Rodrigues
bf2e91b6d1
feat: add system information functions to the standard library (#8109)
This PR adds system information functions to the standard library
2025-06-27 16:31:34 +00:00
Sebastian Ullrich
7ed1a4b576
perf: inline lean_inc_ref_cold (#4978)
The body is a single instruction
2025-06-27 15:58:00 +00:00
Sofia Rodrigues
fe1b407031
feat: add DNS resolution functions to the standard library (#8072)
This PR adds DNS functions to the standard library

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-06-27 11:11:47 +00:00
Sofia Rodrigues
0f2cb91336
feat: add lean_setup_libuv for initializing required LIBUV components (#8636)
This PR adds a function called `lean_setup_libuv` that initializes
required LIBUV components. It needs to be outside of
`lean_initialize_runtime_module` because it requires `argv` and `argc`
to work correctly.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
2025-06-27 11:11:17 +00:00
Mac Malone
e0a793ae20
feat: ignore lean -R if module name is in setup (#8874)
This PR skips attempting to compute a module name from the file name and
root directory (i.e., `lean -R`) if a name is already provided via `lean
--setup`.

This is accomplished by porting the rest of the frontend code in the
`try` block to Lean.
2025-06-23 17:55:52 +00:00
Henrik Böving
50cfe354be
chore: remove old LEAN_AUTO_THREAD_FINALIZATION workaround (#8885)
This PR removes an old workaround around non-implemented C++11 features
in the thread finalization.

This `ifdef` dates back to approximately 2015 as can be seen
[here](https://github.com/leanprover/lean3/blame/master/src/util/thread.cpp#L177),
the comments mention that it was originally implemented because not all
compilers at the time were able to support the C++11 `thread_local`
keyword. 10 years later this is hopefully the case and we can remove
this workaround.

There is an additional motivation for doing this,
`lean::initialize_thread` contains the following allocation:
```cpp
    g_thread_finalizers_mgr = new thread_finalizers_manager;
```
this is supposed to be freed at some point but:
```cpp
// TODO(gabriel): race condition with thread finalizers
void delete_thread_finalizer_manager() {
    // delete g_thread_finalizers_mgr;
    // g_thread_finalizers_mgr = nullptr;
}
```
so `g_thread_finalizers_mgr` leaks upon repeated invocation of
`lean::initialize_thread`.

Note that Windows has already been using this alternative implementation
for a while so the alternative implementation has (hopefully) not rotten
away in the meantime.
2025-06-20 08:52:17 +00:00
Mac Malone
2a8cd373ca
feat: respect lean --setup module name in code generation (#8780)
This PR makes Lean code generation respect the module name provided
through `lean --setup`.

This is accomplished by porting to Lean the portion of `shell.cpp` that
spans running the frontend to exiting the process. This makes it easier
to load the module setup and control how its name is passed to the code
generation functions. This port attempts to minimize the changes made to
Lean. It marks the new Lean functions `private` and tries to preserve as
faithfully as possible the behavior of the original C++ code. Exposing
the new Lean interface publicly and/or further improving the code now
that is written in Lean is left for the future.
2025-06-15 01:11:58 +00:00
Rob23oba
e713232623
fix: resolve symbolic links through IO.FS.realPath on windows (#8534)
This PR fixes `IO.FS.realPath` on windows to take symbolic links into
account.

Closes #810
2025-06-13 13:16:13 +00:00
Justin King
0d0da768d8
perf: update free_sized declaration to be compatible with glibc (#8661)
glibc adds `__attribute__((nothrow))` to its declarations, at least for
those related to malloc. glibc has yet to introduce `free_sized`, but
when it does it would cause compilation errors. This is due to the fact
that if a function declarations has `__attribute__((nothrow))` and it is
re-declared or implemented in C++ it must also have
`__attribute__((nothrow))` or `noexcept`, otherwise the compilation will
fail.

This is a follow up to https://github.com/leanprover/lean4/pull/6598.

Signed-off-by: Justin King <jcking@google.com>
2025-06-13 13:13:00 +00:00
Sebastian Ullrich
f0347ee719
chore: lean --stats gives number of imported bytes (#8725)
Thanks to `mmap`, startup time is not necessarily related to this
figure, but it can be used as a rough measure for that and how much data
the module depends on, i.e. the rebuild chance.

Also adds new cumulative benchmarks for this metric as well as the
number of imported constants and env ext entries.
2025-06-12 08:29:42 +00:00
Sebastian Ullrich
add3e1ae12
fix: IO.FS.removeDirAll should not follow symlinks (#8573)
This PR avoids the likely unexpected behavior of `removeDirAll` to
delete through symlinks and adds the new function
`IO.FS.symlinkMetadata`.

---------

Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
2025-06-02 08:44:17 +00:00
Leonardo de Moura
6940d2c4ff
fix: block adversarial exploit of non-aborting assert! (#8559)
This PR fixes an adversarial soundness attack described in #8554. The
attack exploits the fact that `assert!` no longer aborts execution, and
that users can redirect error messages.
Another PR will implement the same fix for `Expr.Data`.
2025-05-31 00:08:30 +00:00
Cameron Zwarich
575b4786f9
feat: optimize lean_nat_shiftr for scalars (#8268)
This PR optimizes lean_nat_shiftr for scalar operands. The new compiler
converts Nat divisions into right shifts, so this now shows up as hot in
some profiles.
2025-05-11 01:39:59 +00:00
Markus Himmel
925e53fcba
fix: include libuv outside of namespace (#8166)
This PR makes sure we never `#include <uv.h>` while inside a namespace,
which recent GCC versions don't seem to like.
2025-04-29 22:19:17 +00:00
Henrik Böving
7b6c16a44b
feat: implement a Selector for async UDP (#8139)
This PR is a follow up to #8055 and implements a `Selector` for async
UDP in order to allow IO multiplexing using UDP sockets.

The technical approach taken for this PR is basically a copy of #8078
but adjusted for UDP. The libuv API gives the same guarantee that was
used in that PR.
2025-04-29 21:01:14 +00:00
Rob23oba
9f06aff834
feat: optimized division without remainder for Int and Nat (#8089)
This PR adds optimized division functions for `Int` and `Nat` when the
arguments are known to be divisible (such as when normalizing
rationals). These are backed by the gmp functions `mpz_divexact` and
`mpz_divexact_ui`. See also leanprover-community/batteries#1202.
2025-04-29 07:23:35 +00:00
Henrik Böving
406bda8807
feat: implement a Selector for async TCP (#8078)
This PR is a follow up to #8055 and implements a `Selector` for async
TCP in order to allow IO multiplexing using TCP sockets.

As we must not commit to actually fetching data from the socket buffer
this cannot be implemented by just racing on `recv?`. Instead we perform
a call to `uv_read_start` and pass an `alloc_cb` that allocates no
memory at all. According to the docs of
[`uv_alloc_cb`](https://docs.libuv.org/en/v1.x/handle.html#c.uv_alloc_cb)
this is guaranteed to give us a `UV_ENOBUFS` in the relevant callback.
Thus we can first run this "zero read" and then go into one of three
cases:
1. We get cancelled before the zero read completes, in this case just
cancel the zero read and give up.
2. The zero read completes and we loose the race for completing the
`select`, in this case just don't do anything anymore
3. The zero read completes and we win the race for completing the
`select`, in this case we perform the actual read on the socket. As we
know that data is available already (since the read callback of the zero
read is only triggered if data actually is available) we know that the
subsequent actual read should complete right away.

In this way we avoid any data loss if we loose the race.
2025-04-24 16:05:35 +00:00
Sebastian Ullrich
7feb583b9e
feat: enable experimental module system in Init (#8047) 2025-04-23 17:21:33 +00:00
Mac Malone
b51115dac5
feat: IO.Process.SpawnArgs.inheritEnv (#6081)
This PR adds an `inheritEnv` field to `IO.Process.SpawnArgs`. If
`false`, the spawned process does not inherit its parent's environment.

For example, Lake will make use of this to ensure that build processes
do not use environment variables that Lake is not properly tracking with
its traces.
2025-04-16 00:25:32 +00:00
Sebastian Ullrich
0076ba03d4
fix: race condition in IO.getTaskState (#7945)
This PR fixes a potential race between `IO.getTaskState` and the task in
question finishing, resulting in undefined behavior.

All task state must be accessed under the respective lock.
2025-04-14 14:08:36 +00:00
Henrik Böving
8e9da7a1bc
feat: wait on dedicated tasks after main is finished (#7958)
This PR ensures that after `main` is finished we still wait on dedicated
tasks instead of exiting forcefully. If users wish to violently kill
their dedicated tasks at the end of main instead they can run
`IO.Process.exit` at the end of `main` instead.
2025-04-14 11:53:54 +00:00
Henrik Böving
ac738a8e81
perf: use mimalloc in compactor hashmaps (#7929)
This PR changes the compactor hashmap to use mimalloc which speeds up
olean serialization.
2025-04-14 09:11:34 +00:00
Sebastian Ullrich
5cd352588c
perf: use mimalloc with important C++ hash maps (#7868)
`unordered_map`/`unordered_set` does an allocation per insert, use
mimalloc for them for important hash maps
2025-04-11 16:23:33 +00:00
Sebastian Ullrich
69536808ca
feat: read/writeModuleDataParts API for serialization with cross-file sharing (#7854)
This PR introduces fundamental API to distribute module data across
multiple files in preparation for the module system.
2025-04-10 13:32:24 +00:00
Sebastian Ullrich
1b40c46ab1
chore: panic on blocking waits in sync tasks (#7853) 2025-04-08 14:49:26 +00:00
euprunin
2ea675369f
chore: fix spelling mistakes (#7328)
Co-authored-by: euprunin <euprunin@users.noreply.github.com>
2025-04-07 01:15:48 +00:00
Leonardo de Moura
5f684b4777
feat: support mpz in the shareCommon APIs (#7838)
This PR adds support for mpz objects (i.e., big nums) to the
`shareCommon` functions.
2025-04-06 19:52:50 +00:00
Mac Malone
7947457305
perf: Task.bind short circuit (#7795)
This PR skips scheduling the resulting task in `Task.bind` /
`BaseIO.bindTask` if the task has already finished. Instead, it just
returns its value.
2025-04-04 23:24:51 +00:00
Sebastian Ullrich
83067d67d6
chore: avoid mimalloc warnings (#7800) 2025-04-03 13:52:16 +00:00
Henrik Böving
626075ca34
feat: add Std.SharedMutex (#7770)
This PR adds a shared mutex (or read-write lock) as `Std.SharedMutex`.

In order to easily migrate a `Std.Mutex` to `Std.SharedMutex` if
necessary, the functions for obtaining exclusive access are named the
same, allowing a correct drop in to be done by just swapping types.
2025-04-03 08:30:54 +00:00
Sebastian Ullrich
bd24ca3093
test: re-elaboration benchmarks (#7784)
Tests language server memory use by repeatedly re-elaborate a given file
2025-04-02 10:10:46 +00:00
Henrik Böving
32cd701994
feat: add Std.RecursiveMutex (#7755)
This PR adds `Std.RecursiveMutex` as a recursive/reentrant equivalent to
`Std.Mutex`.
2025-04-01 07:35:36 +00:00
Henrik Böving
1b5a52a5e9
feat: Std.BaseMutex.tryLock and Mutex.tryAtomically (#7751)
This PR adds `Std.BaseMutex.tryLock` and `Std.Mutex.tryAtomically` as
well as unit tests for our locking and condition variable primitives.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-03-31 12:19:09 +00:00
Sebastian Ullrich
2edfe2e9cf
perf: store mimalloc object size in header (#7734) 2025-03-31 06:52:56 +00:00
Sebastian Ullrich
3b85d26af7
perf: use mimalloc for all Lean allocations (#7736) 2025-03-30 23:00:17 +00:00
Sebastian Ullrich
5ebac3fa50
perf: use mimalloc by default (#7710)
This PR improves memory use of Lean, especially for longer-running
server processes, by up to 60%
2025-03-30 22:40:41 +00:00
Sofia Rodrigues
74b1c29a48
feat: UDP socket support using LibUV (#7574)
This PR introduces UDP socket support using the LibUV library, enabling
asynchronous I/O operations with it.
2025-03-26 15:04:25 +00:00
Sofia Rodrigues
ad547b56f5
feat: add network interfaces (#7578)
This PR introduces a function called `interfaceAddresses` that retrieves
an array of system’s network interfaces.
2025-03-24 17:57:05 +00:00
Sebastian Ullrich
884fa444a1
chore: fix fsanitize preset (#7651) 2025-03-24 09:17:45 +00:00