What Is New in Rust 1.70
| Category | Highlights |
|---|---|
| New Features | Sparse index protocol default for crates.io, OnceCell and OnceLock types, IsTerminal trait, Named debug-info levels |
| Improvements | Faster crate index fetching, clearer debug-info naming, test CLI now rejects unstable options on stable/beta |
| Breaking Changes | Unstable `test` command-line options are no longer accepted on stable and beta releases |
How does the new default sparse protocol affect Cargo crate fetching?
The sparse protocol is now the default method Cargo uses to read the crates.io index, which reduces network latency and bandwidth usage.
- Fetching the index is up to several times faster because only the needed parts are downloaded.
- Firewalls must allow HTTPS access to
https://index.crates.io; otherwise you need to revert to the git protocol viaregistries.crates-io.protocol = "git"in.cargo/config.toml. - Switching protocols changes the cache layout, so existing crates will be re-downloaded the first time you build after the upgrade.
In practice, most teams will see quicker cargo update and cargo build runs without any code changes.
What are OnceCell and OnceLock and when should I use them?
OnceCell (unsynchronized) and OnceLock (thread-safe) provide one-time, lazy initialization for global or static data without requiring a separate crate.
use std::sync::OnceLock;
static CONFIG: OnceLock<String> = OnceLock::new();
fn get_config() -> &'static str {
CONFIG.get_or_init(|| std::fs::read_to_string("config.toml").unwrap())
}
- Replace
lazy_staticoronce_cellfor simple cases. - Ideal for non-const data that must be initialized at runtime, such as configuration files, database connections, or expensive computations.
- Future stabilization may add LazyCell/LazyLock which store the initializer.
This matters if you want to avoid the overhead of a mutex for read-only data after the first set.
How can I detect if stdout is a terminal in stable Rust?
The newly stabilized IsTerminal trait lets you query whether a handle represents a TTY.
use std::io::{stdout, IsTerminal};
fn main() {
let use_color = stdout().is_terminal();
// Enable ANSI colors only when attached to a terminal
}
- Works on Windows, Unix, and WASI targets.
- Useful for conditional coloring, progress bars, or switching to a full-screen TUI when interactive.
Most CLI tools will now have a single, portable way to decide between script-friendly and user-friendly output.
What are the new named debug-info levels and how do they map to the old numeric flags?
Rust 1.70 adds symbolic names for -Cdebuginfo levels, making build scripts more readable.
none= 0 (no debug info)limited= 1 (function names, line tables, but no types/variables)full= 2 (complete DWARF)line-tables-only= a minimal level for backtracesline-directives-only= NVPTX profiling use case
In practice, you can replace -Cdebuginfo=1 with -Cdebuginfo=limited for clearer intent; Cargo will expose these names in a future release (1.71).
How does Rust 1.70 enforce test CLI stability and what impact does it have on CI pipelines?
Starting with 1.70, the test harness rejects any unstable --format json or similar flags on stable and beta compilers.
- CI configurations that relied on JSON output must switch to a nightly toolchain or use alternative reporting mechanisms.
- IDE plugins (e.g., IntelliJ Rust) have already been updated to avoid the unstable flag on stable builds.
- The change tightens the contract of the stable test runner, reducing surprise failures when upgrading.
Watch out for hidden dependencies on unstable test options in custom test scripts; they will need a nightly toolchain after the upgrade.
Frequently Asked Questions
Do I need to change my Cargo configuration to use the new sparse protocol?
No, Cargo automatically switches to the sparse protocol; you only need to adjust the config if you must stay on the git protocol.
How can I clear the old GitHub crate cache after enabling sparse?
Delete the directories under $CARGO_HOME/registry/*/github.com-* and let Cargo repopulate them with the sparse layout.
Can I still use lazy_static after OnceLock stabilizes?
Yes, lazy_static continues to work, but OnceLock offers a std-only alternative for simple one-time initialization.
What is the difference between the "limited" and "line-tables-only" debug levels?
"limited" includes function names and line tables, while "line-tables-only" provides only the minimal information needed for backtraces.
How do I enable colored output based on terminal detection?
Use stdout().is_terminal() from std::io::IsTerminal to conditionally add ANSI escape codes.
Will my existing CI pipelines break because of the test CLI change?
If they rely on unstable test flags like --format json on a stable toolchain, they will need to switch to nightly or remove those flags.