Commit graph

20 commits

Author SHA1 Message Date
Mac Malone
49d4752bfd
fix: lake: meta import transitivity (#11683)
This PR fixes an inconsistency in the way Lake and Lean view the
transitivity of a `meta import`. Lake now works as Lean expects and
includes the meta segment of all transitive imports of a `meta import`
in its transitive trace.
2025-12-16 08:28:52 +00:00
Sebastian Ullrich
1f80b3ffbe
feat: module system is no longer experimental (#11637)
This PR declares the module system as no longer experimental and makes
the `experimental.module` option a no-op, to be removed.
2025-12-12 21:20:26 +00:00
Mac Malone
d145b9f8ee
chore: lake: mv targets test to tests (#11592)
This PR moves Lake's `tests/lake/examples/targets` test from `examples`
to `tests` (and thus disabling it by default).

It is being
[flaky](https://github.com/leanprover/lean4/actions/runs/20111185289/attempts/1)
for some unknown reason, so I am disabling until I have a better
opportunity to debug it.
2025-12-11 09:28:44 +00:00
Mac Malone
1d0d3915ca
refactor: lake: disambiguate packages by workspace index (#11500)
This PR adds a workspace-index to the name of the package used by build
target. To clarify the distinction between the different uses of a
package's name, this PR also deprecates `Package.name` for more
use-specific variants (e.g., `Package.keyName`, `Package.prettyName`,
`Package.origName`).

More to come. (WIP)
2025-12-09 02:07:24 +00:00
Mac Malone
5db4f96699
feat: lake: resolve module clashes on import (#11270)
This PR adds a module resolution procedure to Lake to disambiguate
modules that are defined in multiple packages.

On an `import`, Lake will now check if multiple packages within the
workspace define the module. If so, it will verify that modules have
sufficiently similar definitions (i.e., artifacts with the same content
hashes). If not, Lake will report an error.

This verification is currently only done for direct imports. Transitive
imports are not checked for consistency. An overhaul of transitive
imports will come later.
2025-12-03 00:46:20 +00:00
Mac Malone
c1a82c4bd7
chore: lake: update tests/toml (#11314)
This PR fixes a breakage in Lake's TOML test caused by String API
changes. It also removes a JSON parser workaround that has since been
fixed, and it more generally polishes up the code.
2025-11-22 04:41:58 +00:00
Mac Malone
5bb9839887
fix: symbol clashes between packages (#11082)
This PR prevents symbol clashes between (non-`@[export]`) definitions
from different Lean packages.

Previously, if two modules define a function with the same name and were
transitively imported (even privately) by some downstream module,
linking would fail due to a symbol clash. Similarly, if a user defined a
symbol with the same name as one in the `Lean` library, Lean would use
the core symbol even if one did not import `Lean`.

This is solved by changing Lean's name mangling algorithm to include an
optional package identifier. This identifier is provided by Lake via
`--setup` when building a module. This information is weaved through the
elaborator, interpreter, and compiler via a persistent environment
extension that associates modules with their package identifier.

With a package identifier, standard symbols have the form
`lp_<pkg-id>_<mangled-def>`. Without one, the old scheme is used (i.e.,
`l_<mangled-def>`). Module initializers are also prefixed with package
identifier (if any). For example, the initializer for a module `Foo` in
a package `test` is now `initialize_test_Foo` (instead of
`initialize_Foo`). Lake's default for native library names has also been
adjusted accordingly, so that libraries can still, by default, be used
as plugins. Thus, the default library name of the `lean_lib Foo` in
`package test` will now be `libtest_Foo`.

When using Lake to build the Lean core (i.e., `bootstrap = true`), no
package identifier will be used. Thus, definitions in user packages can
never have symbol clashes with core.

Closes #222.
2025-11-19 02:24:44 +00:00
Mac Malone
06f457b48a
fix: lake: indeterminism in targets test (#11188)
This PR fixes a source of indeterminism in the `examples/targets` Lake
test (checking the job index).
2025-11-15 04:20:24 +00:00
Mac Malone
8ad0a61169
refactor: lake: scope all module build keys by package (#11169)
This PR changes all module build keys in Lake to be scoped by their
package. This enables building modules with the same name in different
packages (something previously only well-supported for executable
roots).

API-wise, the `BuildKey` definitions `module` and `moduleFacet` have
been deprecated and replaced with `packageModule` and
`packageModuleFacet`. The `moduleTargetIndicator` has also been removed
(with its purpose subsumed by `packageModule`).
2025-11-15 04:13:00 +00:00
Mac Malone
80409a9ceb
feat: lake: Job.sync & other touchups (#11118)
This PR adds `Job.sync` as a standard way of declaring a synchronous
job.

It makes some non-behavior changes to related Job APIs to improve
compilation.
2025-11-08 04:35:05 +00:00
Mac Malone
590ff23e71
fix: lake: moreLinkObjs|Libs on a lean_exe (#11117)
This PR fixes a bug where Lake ignored `moreLinkObjs` and `moreLinkLibs`
on a `lean_exe`.
2025-11-08 04:20:42 +00:00
Mac Malone
528c0dd2e4
feat: lake: require dependencies by semver range (#10959)
This PR enables Lake users to require Reservoir dependencies by a
semantic version range. On a `lake update`, Lake will fetch the
package's version information from Reservoir and select the newest
version of the package that satisfies the range.

### Using Version Ranges

Version ranges can be specified through the `version` field of a TOML
`require` or the `@` clause of a Lean `require`. They are only
meaningful on Reservoir dependencies.

**lakefile.lean**
```lean-4
require "Seasawher" / "mdgen" @ "2.*"
```

**lakefile.toml**
```toml
[[require]]
name = "mdgen"
scope = "Seasawher"
version = "2.*"
```

The syntax for these versions ranges is a mix of
[Rust's](https://doc.rust-lang.org/stable/cargo/reference/specifying-dependencies.html?highlight=caret#version-requirement-syntax)
and
[Node's](https://github.com/npm/node-semver/tree/v7.7.3?tab=readme-ov-file#ranges)
with some Lean-friendly deviations.

### Comparators

The basic unit of semantic version ranges are version comparators. They
take a base version and a comparison operator and match versions which
compare positively with their base. Lake supports the following
comparison operators.

* `<`, `<=` / `≤`, `>`, `>=` / `≥`, `=`, `!=` / `≠`

Unlike Rust and Node, Lake supports Unicode alternatives for the
operators. It also adds the not-equal operator (`!=` / `≠`) to make
excluding broken versions easier.

Comparators can be combined into clauses via conjunction or disjunction:

* **AND clauses**: Rust-style `≥1.2.3, <1.8.0` or Node-style `1.2.3
<1.8.0`
* **OR clauses**: Node-style `1.2.7 || >=1.2.9, <2.0.0`

When the base version of a comparator has a `-` suffix (e.g.,
`>1.2.3-alpha.3`) it will match versions of the same core (`1.2.3`) with
suffixes that lexicographically compare (e.g., `1.2.3-alpha.7` or
`1.2.3-beta.2`) but will not match suffixed versions of different cores
(e.g., `3.4.5-rc5`). An empty `-` suffix can be used to disable this
behavior. For example, `<2.0.0-` will match `1.2.3-beta.2` and
`2.0.0-alpha.1`.

### Range Macros

In addition to the basic comparators, Lake also supports standard
shorthand for specifying more complex ranges. Namely, it supports the
caret (`^`) and tilde (`~`) operator along with wildcard ranges.

**Caret Ranges**
* `^1` => `≥1.0.0, <2.0.0-`
* `^1.2` => `≥1.2.0, <2.0.0-`
* `^1.2.3` => `≥1.2.3, <2.0.0-`
* `^1.2.3-beta.2` => `≥1.2.3-beta.2, <2.0.0-`
* `^0.2` => `≥0.0.0, <0.3.0-`
* `^0.2.3` => `≥0.2.3, <0.3.0-`
* `^0.0.3` => `≥0.0.3, <0.0.4-`
* `^0` => `≥0.0.0, <1.0.0-`
* `^0.0` => `≥0.0.0, <0.1.0-`

**Tilde Ranges**
* `~1` => `≥1.0.0, <2.0.0-`
* `~1.2` => `≥1.2.0, <1.3.0-`
* `~1.2.3` => `≥1.2.3, <1.3.0-`
* `~1.2.3-beta.2` => `≥1.2.3-beta.2, <1.3.0-`
* `^0` => `≥0.0.0, <1.0.0-`
* `^0.2.3` => `≥0.2.3, <0.3.0-`
* `^0.0.3` => `≥0.0.3, <0.0.4-`
* `~0` => `≥0.0.0, <1.0.0-`
* `~0.0` => `≥0.0.0, <0.1.0-`
* `~0.0.0` => `≥0.0.0, <0.1.0-`

**Wildcard Ranges**
* `*` => `≥0.0.0`
* `1.x` => `≥1.0.0, <2.0.0-`
* `1.*.x` => `≥1.0.0, <2.0.0-`
* `1.2.*` => `≥1.2.0, <1.3.0-`

These ranges closely follow Rust's and Node's syntax. Like Node but
unlike Rust, wildcard ranges support `x` and `X` as alternative syntax
for wildcards.
2025-11-03 04:18:24 +00:00
Mac Malone
d23dcc88ea
fix: lake: pin mathlib in new/init to toolchain (#11063)
This PR changes the `math` and `math-lax` templates for `lake new` and
`lake init` to use the version of Mathlib corresponding to the current
Lean toolchain. Thus, `lake +x.y.z new <pkg> math` will use the Mathlib
for Lean `x.y.z`. On the other hand, `lake update` on such packages will
no longer update Mathlib automatically. Users will need to change the
Mathlib revision in the configuration file before updating.

This change was inspired by a
[discussion](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Build.20error.20on.20.60lake.20.2Bleanprover.2Flean4.3Av4.2E22.2E0.20new.20foo.20math.60/near/546236449)
on the community Zulip.
2025-11-03 02:16:29 +00:00
Henrik Böving
52b1b342ab
feat: zero cost BaseIO (#10625)
This PR implements zero cost `BaseIO` by erasing the `IO.RealWorld`
parameter from argument lists and structures. This is a **major breaking
change for FFI**.

Concretely:
- `BaseIO` is defined in terms of `ST IO.RealWorld`
- `EIO` (and thus `IO`) is defined in terms of `EST IO.RealWorld`
- The opaque `Void` type is introduced and the trivial structure
optimization updated to account for it. Furthermore, arguments of type
`Void s` are removed from the argument lists of the C functions.
- `ST` is redefined as `Void s -> ST.Out s a` where `ST.Out` is a pair
of `Void s` and `a`

This together has the following major effects on our generated code:
- Functions that return `BaseIO`/`ST`/`EIO`/`IO`/`EST` now do not take
the dummy world parameter anymore. To account for this FFI code needs to
delete the dummy world parameter from the argument lists.
- Functions that return `BaseIO`/`ST` now return their wrapped value
directly. In particular `BaseIO UInt32` now returns a `uint32_t` instead
of a `lean_object*`. To account for this FFI code might have to change
the return type and does not need to call `lean_io_result_mk_ok` anymore
but can instead just `return` values right away (same with extracting
values from `BaseIO` computations.
- Functions that return `EIO`/`IO`/`EST` now only return the equivalent
of an `Except` node which reduces the allocation size. The
`lean_io_result_mk_ok`/`lean_io_result_mk_error` functions were updated
to account for this already so no change is required.

Besides improving performance by dropping allocation (sizes) we can now
also do fun new things such as:
```lean
@[extern "malloc"]
opaque malloc (size : USize) : BaseIO USize
```
2025-10-22 10:55:12 +02:00
Mac Malone
3768c07654
fix: lake: cache revision path (#10883)
This PR fixes a bug with Lake's cache where revisions were stored at the
incorrect path. Revisions were stored at `<rev>/<pkg>.jsonl` rather than
the correct `<pkg>/<rev>.jsonl`.
2025-10-21 23:59:44 +00:00
Mac Malone
efbbb0b230
fix: lake: recurse directories in input_dir (#10861)
This PR fixes `input_dir` tracking to also recurse through
subdirectories. The `filter` of an `input_dir` will be applied to each
file in the directory tree (the path names of directories will not be
checked).

Closes #10827.
2025-10-21 04:19:10 +00:00
Mac Malone
d9ee24bf36
fix: lake: local cache w/ --old (#10741)
This PR fixes a bug where partially up-to-date files built with `--old`
could be stored in the cache as fully up-to-date. Such files are no
longer cached. In addition, builds without traces now only perform an
modification time check with `--old`. Otherwise, they are considered
out-of-date.
2025-10-11 02:20:31 +00:00
Mac Malone
0639d49a4c
feat: scope output cache by platform & toolchain (#10730)
This PR changes the Lake's remote cache interface to scope cache outputs
by toolchain and/or platform were useful.

Packages that set `platformIndependent = true` will not be scoped by
platform and the core build (i.e., `bootstrap = true`) will not be
scoped by toolchain. Lake's detected platform and toolchain can be
overridden with the new `--platform` and `--toolchain` options to `cache
get` and `cache put`.

Lake no longer accepts the `--scope` option when using `cache get` with
Reservoir.. The `--repo` option must be used instead.
2025-10-11 02:17:39 +00:00
Mac Malone
215bc30296
feat: lake: allowImportAll configuration option (#9855)
This PR adds a new `allowImportAll` configuration option for packages
and libraries. When enabled by an upstream package or library,
downstream packages will be able to `import all` modules of that package
or library. This enables package authors to selectively choose which
`private` elements, if any, downstream packages may have access to.
2025-10-08 02:47:35 +00:00
Mac Malone
aa3d409eb6
refactor: lake: mv tests/examples to top-level tests dir (#10688)
This PR moves Lake's test infrastructure from `src/lake` to
`tests/lake`.
2025-10-06 21:47:57 +00:00