Rust Release 1.60 and 1.61

Rust 1.60, introduced just this April 7, 2022, stabilizes support for LLVM-based coverage instrumentation in rustc. This provides for source-based code coverage. Developers can try this out by rebuilding their code with -Cinstrument-coverage. Afterward, running the resulting binary will produce a default.profraw file in the current directory.

The llvm-tools-preview component includes llvm-profdata for processing and merging raw profile output, llvm-profdata for processing raw file output, and llvm-cov for report generation. Baseline functionality is stable and will exist in all future Rust releases, but the specific output format and LLVM tools that produce it are subject to change. Developers should use the same version for both llvm-tools-preview and the rustc binary used to compile code.

Rust 1.60 has also re-enables incremental compilation. The Rust team continues to work on fixing bugs in incremental but no problems causing widespread breakage are known at this time.

Also in Rust 1.60:

  • On all platforms, Instant will try to use an operating system API that guarantees monotonic behavior if available. In practice, such guarantees are, under rare circumstances, broken by hardware, virtualization, or operating system bugs. To work around these bugs, and to work with platforms that lack monotonic clocks, Instant::duration_since, Instant::elapsed, and Instant::sub now saturate to zero. In older versions of Rust, this led to a panic, instead.
  • Cargo has established support for collecting information on build with the --timings flag.
  • Namespaced dependencies and weak dependency features have been introduced to improve support for Cargo features and how they interact with optional dependencies. Cargo features provide a mechanism to express conditional compilation and optional dependencies.
  • A number of APIs have been stabilized such as Arc::new_cyclic, Rc::new_cyclic, and slice::EscapAscii.

Rust 1.61 Release

Published May 19, Rust 1.61 highlights custom exit codes from main. Rust proponents said that in the beginning, Rust main functions only could return the unit type () either implicitly or explicitly, indicating success in the exit status, and if developers wanted otherwise, they had to call process::exit. Since Rust 1.26, main has been allowed to return a Result, where Ok translated to a C EXIT_SUCCESS and Err to EXIT_Failure. These alternate return types were unified by an unstable Termination trait. In this release, Termination trait is stable, along with a more-general ExitCode type that wraps platform-specific return types. The Termination trait also can be implemented for a developer’s own types, allowing for customization of reporting before converting to an ExitCode.

Also in Version 1.61:

  • Several incremental features have been stabilized to enable more functionality in const. Developers now can create, pass, and cast function pointers in a const fn, which could be useful to build compile-time function tables for an interpreter. But it is still not permitted to call fn pointers. Developers also now can write trait bounds on generic parameters to const fn, such as T: Copy, where previously only Sized was permitted. Also, const fn now can deal with trait objects, whereas arguments and return values for const fn can be opaque impl Trait types.
  • APIs have been stabilized such as Pin::static_mut, Pin;;static_ref, and Vec::retain_mut.
  • Previously, the creation of locked handles to stdin/stdlout/stderr would borrow the handles being locked, which prevented writing let out = std::io::stdout().lock(); because out would outlive the return value of stdout(). This code now works, eliminating a common pitfall affecting many Rust users.