Rust 1.100
Rust 1.100

原始链接: https://blog.rust-lang.org/2026/11/12/Rust-1.100.0/

Rust 1.100.0 发布,包含多项主要特性: - **Never 类型 (`!`)**:经过 10 年终于稳定,允许在任何地方使用 `!` 作为规范的不可实例化类型,`Infallible` 现在成为其别名。一项破坏性变更调整了旧版本中的 never-type 回退行为。 - **Allocator API**:核心部分稳定,库作者可通过 `Allocator` trait 为 `Vec` 和 `Box` 定义自定义分配器。 - **DropGuard**:新增的 `core::mem::DropGuard` 在每个退出路径上运行闭包,便于事务/回滚模式。 - **`conjure_zst`**:专用的 unsafe 函数,用于创建零大小类型。 - **Cargo 改进**:报告未使用的依赖;一致的构建配置哈希减少缓存冲突;`min-publish-age` 依赖冷却期延迟新发布的版本。 - **稳定的 API**:新增多项,包括 `Box::map`、`Rc::map`、`Arc::map`、`bool::toggle`、`str::trim_prefix/suffix`、`Path::trim_prefix` 以及 `UnsafeCell` 辅助方法。 通过 `rustup update stable` 更新。完整详情请参阅完整发布说明。

Rust 1.100 已发布,这一里程碑标志着一个主要版本。主要特性包括“never”类型(`!`)的稳定化、自定义分配器、最低发布年龄/依赖冷却配置,以及 `cargo install` 默认使用现有 lockfile(`--locked` 变为空操作)。Cargo 还新增了未使用依赖的警告。其他稳定化 API 包括 `bool::toggle`、`Box::map` 以及 `trim_prefix`/`trim_suffix` 方法。 讨论涉及编译时间和过大的 target 目录,维护者概述了正在进行的工作(构建目录垃圾回收、增量改进、减少调试信息)。依赖冷却引发了关于在供应链安全与及时修复 0-day 漏洞之间取得平衡的争论。稳定的 ABI 仍然是未来目标,因泛型而复杂。一些用户强调 Rust 的强类型和编译器错误使其特别适合 AI 辅助开发,而另一些人则因编译速度慢而倾向于在大型项目中选择 Go 或 C。
相关文章

原文

Nov. 12, 2026 · The Rust Release Team

The Rust team is happy to announce a new version of Rust, 1.100.0. Rust is a programming language empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, you can get 1.100.0 with:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.100.0.

If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!

never type is finally stable! This also completes the project goal for this work.

The never type, spelled ! in code, is the canonical uninhabited type. It represents the type of diverging computations – computations which never resolve to any value – where any code that follows is unreachable. Expressions that terminate control flow, such as return, break, and std::process::exit, also have the type !.

Since having a value of the never type is impossible, Rust permits a never-to-any coercion, allowing to turn ! into any other type (this is what distinguishes it from any other uninhabited types). This can be used, for example, to not return a value from one of the branches of a match or an if:

fn mrrrow(option: Option<u32>) {
    let value = match option {
        // `x` has type `u32`
        Some(x) => x,
        // `return` has type `!`, which is then coerced to `u32`,
        // allowing the `match` to pass type checking.
        None => return,
    };
    // ...
}

While the never type could already be used and observed this way, and even named in the return type of functions (-> !), this release allows naming the never type anywhere:

fn infallible_unwrap<T>(res: Result<T, !>) -> T {
    // ^^ writing `Result<_, !>` was not allowed before
    let Ok(v) = res;
    v
}

Additionally this release changes Infallible to be an alias to the never type. That makes all old APIs that used Infallible be compatible with using !. This was the plan ever since the introduction of Infallible and is one of the reasons why the never type stabilization was so hard (waffle gave a talk about some of the troubles of the stabilization).

Unfortunately, to allow changing Infallible, we had to introduce a breaking change. This release changes the "never type fallback" from () to ! in editions before 2024 (i.e. 2015, 2018, and 2021), similarly to what has already been done in edition 2024. This should largely be unnoticeable, but can affect code in some rare cases (for example when ignoring a result of a function returning a generic parameter). Note that this change might also make the compiler detect more code as unreachable.

We tried to minimize the impact of this breaking change as much as possible, by providing future compatibility warnings far in advance and releasing fixes to public crates that have been broken by this. If a dependency is failing due to issues with the never type, consider updating it, as a fix might have already been released for it.

allocator_api, enabling library authors to define custom allocators that can be used together with certain standard library types - currently Vec and Box. These are enabled through the newly-stabilized Allocator trait.

This is the foundation of the Allocators 1.0 project goal. A lot remains to be done still, including expanding the API surface usable with custom allocators and stabilizing their use on more collections and pointer types; with the core trait and design out of the way though, expect to see more being stabilized soon!

in Rust you never have to close a socket.

Implementing Drop can however feel a little inconvenient when all you want is to run some code unconditionally when a function exits. This is why we’re introducing core::mem::DropGuard: a new helper type that runs a closure when dropped.

DropGuard takes two arguments: a variable and a closure. It implements Deref and DerefMut so you can keep working with the variable as normal. But when dropped it runs the closure and consumes the variable.

DropGuard also implements a dismiss method which returns the variable from the guard without running the destructor. This makes it possible to quickly implement all-or-nothing transaction-like APIs with a rollback. Here is an example implementing a parser which uses a guard to roll back mutations in case of failure:

use std::mem::DropGuard;
use std::num::ParseIntError;

/// Attempt to parse all `strings` and push them into `nums`.
/// If parsing any of them fails, `nums` remains unchanged.
fn parse_all(nums: &mut Vec<u32>, strings: &[&str]) -> Result<(), ParseIntError> {
    let len = nums.len();
    let mut nums = DropGuard::new(nums, move |nums| {
        nums.truncate(len);    // ← 1. Reset the vec on failure
    });

    for s in strings {
        nums.push(s.parse()?); // ← 2. If `?` returns an error, roll back
    }

    DropGuard::dismiss(nums);  // ← 3. Parsing successful, dismiss the guard
    Ok(())
}

unsafe code guidelines are still being decided, it became clear that it would be very useful to decide what exactly it means to create zero-sized types in an unsafe way, and what we should recommend for people to do this.

This question is answered in Rust 1.100 with a single function: std::mem::conjure_zst.

Instead of transmuting (), MaybeUninit::uninit().assume_init(), or various other incantations, this is the dedicated way to create a value of a zero-sized type when you know that doing so is safe to do. If an inhabited type has no size, we know exactly what value it must be: nothing.

Of course, APIs often rely on the inability to construct such types for safety, and that's why this function is unsafe. For example, PyO3's Python<'py> is a zero-sized marker token that represents holding the Python GIL (global interpreter lock). Many of Python's APIs require holding this lock to be safe, but conjuring a token from thin air would allow safe PyO3 calls to violate that precondition.

project goal. See also the other lints that have been introduced.

build directory layout project goal in 2025, and its stabilization is a milestone toward a new project goal, unblocking future improvements such as cache garbage collection, cross-workspace cache de-duplication, cross-workspace caching, and fine grain locking.

We previously published a call for testing for the changes that are now taking effect. While this is an internal change, this may break build processes and tests that had workarounds for missing or incomplete features. In some cases, the workaround is no longer needed. See cargo#17287 for possible solutions and to add any new use cases.

.cargo/config.toml:

[registry]
global-min-publish-age = "3 days"

When selecting versions, Cargo now skips any version published more recently than that, and tells you what it held back:

$ cargo update
    Updating crates.io index
     Locking 2 packages to highest compatible version as of min-publish-age
      Adding cc v1.11.0 (available: v1.18.0, published 3 hours ago)
      Adding clap 4.6.7 (available: 4.6.9, published 2 days ago)

When a new version is needed right away, you can override the check for a single update:

$ CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow cargo update clap --precise 4.6.9
    Updating crates.io index
    Updating clap 4.6.7 -> clap 4.6.9 (published 2 days ago, minimum age 3 days)

The newer version will be recorded in Cargo.lock and kept from then on until a later cargo update re-resolves it.

A few things to keep in mind:

  • This depends on the registry recording when each version was published. Versions without a pubtime field in the index are never held back.

  • cargo install ignores the minimum publish age, for both the installed crate and its dependencies. Pin a version with cargo install [email protected] if needed.

  • Cooldowns reduce the risk from some supply chain attacks but are not a complete defense on their own. Please keep reviewing dependency updates as you otherwise would.

Further work to protect the ecosystem is planned under the crates.io supply chain hardening project goal, including quarantine support and automated detection of suspicious releases.

Rust, Cargo, and Clippy.

Thanks!

联系我们 contact @ memedata.com