BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Rust 1.51 Stabilizes Const Generics MVP, Improves Cargo and Compile Times

Rust 1.51 Stabilizes Const Generics MVP, Improves Cargo and Compile Times

This item in japanese

Rust 1.51 brings to stable a minimum value proposition for const generics, which enable parametrizing types by constant values, for example integers, as opposed to types or lifetimes. The new Rust release also includes improvements to Cargo with a new feature resolver, and faster compile times on macOS.

Previous to 1.51, const generics were not complete foreigners in Rust land. Indeed, Rust 1.47 introduced limited support for const generics in order to simplify working with arrays. The issue with Rust arrays was they include an integer as part of their type, i.e., [T; N], so up to Rust 1.46 you had to manually implement traits for arrays for every N you needed to support. This also applied to Rust standard library, so most of its functions operating on arrays were limited to arrays of up to 32 elements.

As mentioned, 1.47 removed this limitation for arrays. Now Rust 1.51 makes it possible to create const generics types over integral types such as integers, characters, and booleans. The following snippet shows how you can define a wrapper for a pair of arrays of the same size:

struct ArrayPair<T, const N: usize> {
    left: [T; N],
    right: [T; N],
}

impl<T: Debug, const N: usize> Debug for ArrayPair<T, N> {
    // ...
}

Const generics allow developers to define a variety of new generic types, but their implementations is not yet complete. Indeed, the Rust team is working on adding support for strings and custom types, as well as on making it possible to specify const generics using complex expressions instead of const arguments. Support for const generics for custom types will require to define a notion of structural equality and only types implementing that notion will be allowed as const parameters.

Future work will also include adding methods to the standard library that take advantage of const generics. One example of that is the already stabilized array::IntoIter which enables iterating arrays by value rather than by reference.

The new feature resolver in Cargo is aimed to fix a long-standing issue which arises, for example, when you use a given crate both as a developer dependency to be used at compile time and as a dependency of your final binary. When a crate appears more than once in the dependency graph, Cargo merges all used features for that crate in order to build it just once. There may be a situation, though, when you do not want a feature that you use at compile-time, e.g., std, to be also included in your final binary, e.g., when it target embedded systems and only uses #![no_std] crates.

To solve this behaviour, Cargo includes a new resolver option that can detect cases when a crate should be compiled twice.

On the front of compile times, as mentioned, Rust 1.51 brings significant improvements to performance on macOS thanks to a new behaviour when collecting debug information from the binary. Indeed, instead of using dsymutil, it now uses a different backend that is able to collect debug info incrementally, thus not requiring to go over the entire final binary, which can be quite expensive with larger projects.

You can find the full list of changes, fixes, and stabilizations in the official release notes.

Rate this Article

Adoption
Style

BT