Series: The Rust Annals

Vol. I Issue 71 nlopes.dev

Announcing Rust 1.70.0

Rust 1.70 makes Cargo’s sparse crates.io protocol the default, substantially improving index-fetch performance, and brings one-time initialization and terminal detection into the standard library. It also adds named compiler debug-information levels and begins enforcing the documented nightly-only boundary for unstable test-harness options.

Cargo now uses the sparse crates.io index by default

Cargo’s “sparse” protocol is now enabled by default for reading the crates.io index. The protocol was stabilized in Rust 1.68.0 but still required configuration for crates.io; Rust 1.70 completes the announced default switch. Users should see substantially improved performance when fetching information from the index.

Restrictive firewalls need to permit access to https://index.crates.io. Users who need the previous default—the git index hosted by GitHub—can select it through registries.crates-io.protocol.

Changing the access method also changes the crate-cache path, so dependencies will be downloaded again. After fully committing to the sparse protocol, users may want to clear the old $CARGO_HOME/registry/*/github.com-* paths.

One-time initialization and terminal detection join the standard library

std::cell::OnceCell and its thread-safe counterpart std::sync::OnceLock provide one-time initialization of shared data where immediate construction is unwanted or may be impossible, such as non-const data in global variables.

use std::sync::OnceLock;

static WINNER: OnceLock<&str> = OnceLock::new();

fn main() {
    let winner = std::thread::scope(|s| {
        s.spawn(|| WINNER.set("thread"));

        std::thread::yield_now(); // give them a chance...

        WINNER.get_or_init(|| "main")
    });

    println!("{winner} wins!");
}

Crates such as lazy_static and once_cell previously filled this need. The standard-library types were ported from once_cell’s unsync and sync modules. More methods may be stabilized later, along with LazyCell and LazyLock, which store their initializing function; this first stabilization step should already cover many use cases.

The newly stable std::io::IsTerminal trait has one method, is_terminal, which determines whether a file descriptor or handle represents a terminal or TTY. It standardizes functionality previously supplied by crates such as atty and is-terminal, using the C library’s isatty function on Unix targets and similar functionality elsewhere. Programs can use it to distinguish scripts from interactive operation, including whether to present colors or a full TUI.

use std::io::{stdout, IsTerminal};

fn main() {
    let use_color = stdout().is_terminal();
    // if so, add color codes to program output...
}

Named debug-information levels clarify what rustc emits

The -Cdebuginfo compiler option previously accepted only the numeric levels 0..=2. Cargo defaults to level 2 in dev and test profiles and level 0 in release and bench profiles. The levels can now be named none (0), limited (1), and full (2), with two additional levels: line-directives-only and line-tables-only.

Cargo and rustc documentation previously called level 1 “line tables only,” although it also included information about every function, but not types and variables. That level is now called limited. The new line-tables-only level is reduced to the minimum needed for backtraces containing filenames and line numbers, and may eventually become the level selected by -Cdebuginfo=1. line-directives-only is intended for NVPTX profiling and is otherwise not recommended.

These names cannot yet be used through Cargo.toml; that support will be available in Rust 1.71.

Stable and beta test harnesses now reject unstable options

Compiling #[test] functions produces an executable whose command-line interface comes from the test crate. Some of its options are unstable and require -Zunstable-options. Although such options were documented as nightly-only, the test harness had not enforced that restriction.

Starting with Rust 1.70, stable and beta builds no longer allow unstable test options. Some users may have relied on them indirectly, particularly on --format json through IntelliJ Rust or other IDE plugins. Those projects were already adjusting; JSON output remains tracked in the relevant issue.

Reproduced from the Rust blog under its publication licence. Typeset in Literata.