[ANN] jlrs 0.22: Julia version autodetection, async closure support, and more!

Taaitaaiger
Sat, 11 Oct 2025 15:49:06 +0000
Package Announcements

jlrs is a crate for the Rust programming language for interop between Rust and Julia, version 0.22 brings many changes. The tutorial has been updated to this new version.

Version and juliaup support

Julia versions 1.10 up to and including 1.12 are supported. The MSRV is 1.85, the codebase has been migrated to the 2024 edition of Rust. Unlike previous versions the targeted Julia version is now detected at build time, all version features (e.g. julia-1-10) have been removed. The old JULIA_DIR environment variable has been renamed to JLRS_JULIA_DIR.

Using jlrs with juliaup has long been unsupported, but is now possible by installing jlrs-launcher. This application uses juliaup internally to find the requested Julia version; by invoking jlrs-launcher +1.12 cargo run, cargo run is executed in a new process where the environment has been updated to allow the version to be detected and the library to be linked.

The JlrsCore package is used internally by jlrs, the specific version that is used can be overridden with the environment variables JLRS_CORE_REVISION, JLRS_CORE_REPO, JLRS_CORE_VERSION and JLRS_CORE_NO_INSTALL.

Async runtime

The async runtime has been updated to support, and in some cases require, async closures. Async closures that take an AsyncGcFrame implement the AsyncTask-trait. The async_scope method requires an async closure to be used instead of a closure that returns an async block. Unsafe work-arounds for lifetime limitations of closure that return async blocks, like relaxed_async_scope, have been removed.

Thanks to the stabilization of async methods in traits, traits with such methods no longer depend on async_task.

Weak types and targets

Unrooted data has long been called a Ref in jlrs, but this is a misnomer: there is no additional level of indirection, rather it’s weakly instead of strongly referenced from Rust. Such data is now called Weak, types like ValueRef have been renamed to WeakValue. Similarly, unrooting targets have been renamed to weak targets.

Exported type derive macros

The OpaqueType and ForeignType traits, which are used to export Rust types to Julia, are now derive macros. The ParametricBase and ParametricVariant traits have been removed; OpaqueType now supports types with generics. Features like setting the super-type of an exported type are now handled by annotating the struct instead of implementing a trait method. A custom mark function for a ForeignType can be implemented by annotating the fields that reference Julia data or by implementing the Mark trait.

Scope generics

The previous version of jlrs moved the return type of a scope from the method to the trait. This was a bad choice and has been reverted. The unnameable generic type of the scope has been removed from the signature in favor of using impl Trait. The Returning and LocalReturning traits have been removed.

Calling Julia functions

Methods that call a function with a small number of arguments like Call::call1 have been deprecated in favor of Call::call. Providing keyword arguments with ProvideArguments::provide_arguments has been deprecated in favor Call::call_kw. The keyword arguments must be provided as a NamedTuple. The managed Function type has been removed and replaced by an abstract type.

Other changes

The exception handler passed to catch_exceptions is now invoked inside the catch block. It takes an Exception instead of a Value.

Arrays can no longer be index with tuples like (1, 2), use arrays: [1, 2] instead.

The IntoJlrsResult trait has been removed in favor of supporting the ? operator.

The multithreaded runtime can no longer be started but must be spawned. They require the use of scoped threads to ensure that the main thread outlives all adopted threads.

GitHub
jlrs-launcher
Docs
Tutorial

1 post - 1 participant