Skip to content

哈喽,大家好呀,我是呼噜噜,近期Rust 1.92.0 已于 2025 年 12 月 11 日正式发布,带来了一系列语言、标准库、工具链等方面的重要改进与稳定化更新,让我们一起看看吧

要想升级到此版本:

java
rustup update stable

如果尚未安装 rustup,您可以从 Rust 官网的相应页面 获取 rustup,并查看 1.92.0 的详细发布说明。

以下是该版本的核心亮点:

"Never Type" (!) 稳定化

Rust 团队长期以来一直在推进 !(从不返回类型)的稳定化。在 1.92.0 中,两个重要的未来兼容性 Lint 已被设为默认拒绝(deny-by-default):

  • never_type_fallback_flowing_into_unsafe
  • dependency_on_unit_never_type_fallback

在以前的版本中,当编译器无法推导某些类型时,会默认回退(fallback)到 ()(单元类型)。

如今为了将来能安全地让其回退到 !,编译器强制要求开发者显式处理这些情况,以防代码在未来版本中出现意外的行为变更。

也就是说,如果我们的rust代码触发了这些 lint,现在会导致编译错误,以前只是警告)

这只影响当前构建的 crate,作为依赖项引入时只会报警告。

如果你的代码受影响,建议修复,通过显式类型标注,显式返回类型,避免依赖推断的回退行为。如果暂时无法修复,可以使用 #[allow(...)] 显式允许这些 lint 通过编译。

unused_must_use 不再对 Result<(), UninhabitedType> 发出警告

Rust 的 unused_must_use lint 规则会在忽略函数返回值时发出警告,前提是该函数或其返回类型带有 #[must_use] 注解。例如,如果忽略 Result 类型的返回值,它会发出警告,提醒您使用 ? 运算符或类似 .expect("...") 的方法来处理返回值。

然而,有些函数返回 Result 类型,但其使用的错误类型实际上是“不可实例化”的,也就是「不可能失败」,这意味着您无法构造该类型的任何值(例如 !Infallible 类型)。

这个改动还是很不错的

以前只要函数返回类型带 #[must_use](比如 Result),你忽略返回值就会收到警告。

Rust 1.92.0 起,以下这类返回值被忽略时不再触发 unused_must_use 警告:

  • Result<(), UninhabitedType>,例如 Result<(), Infallible>
  • ControlFlow<UninhabitedType, ()>

示例代码:

java
use core::convert::Infallible;
fn can_never_fail() -> Result<(), Infallible> {
    // ...
    Ok(())
}

fn main() {
    can_never_fail();
}

这在 trait 带有关联错误类型的常见模式中特别有用,其中错误类型有时可能是不可失败的。

java
//定义一个 trait:错误类型通过关联类型给出
trait UsesAssocErrorType {
    type Error;
    fn method(&self) -> Result<(), Self::Error>;
}
// 一个永不失败的实现
struct CannotFail;
impl UsesAssocErrorType for CannotFail {
    type Error = core::convert::Infallible;
    fn method(&self) -> Result<(), Self::Error> {
    //这里的错误类型是 Infallible,理论上永远不会返回 Err
        Ok(())
    }
}
// 一个可能失败的实现
struct CanFail;
impl UsesAssocErrorType for CanFail {
    type Error = std::io::Error;
    fn method(&self) -> Result<(), Self::Error> {
        Err(std::io::Error::other("something went wrong"))
    }
}

fn main() {
    CannotFail.method(); // No warning,Rust 1.92.0 起,忽略警告
    CanFail.method(); // Warning: unused `Result` that must be used
}

现在我们可以直接调用该方法而无需写 .unwrap().expect()

Linux 上 -Cpanic=abort 的堆栈回溯体验改善:默认生成 unwind tables

带有 -Cpanic=abort 的回溯在 Rust 1.22 中曾正常,但在 Rust 1.23 中出现了问题,当时为了性能优化,不再生成 -Cpanic=abort 的回溯表

Rust 1.45 中,稳定了 -Cforce-unwind-tables=yes 这一变通方法,如果你想要栈回溯,得自己加个编译选项:-Cforce-unwind-tables=yes

1.92.0 修复了这个问题。即使开启了 panic=abort,默认也会生成 unwind tables。当我们的程序崩了,就能看到完整的调用栈,方便定位问题。

如今即使在 abort 模式下,也能获得正常的调试堆栈信息。如果想禁用此行为以减小二进制体积,需显式使用 -Cforce-unwind-tables=no

这有助于性能分析工具(如 perf)在不牺牲太多二进制体积的情况下更好地获取调用栈。

更严格的 #[macro_export] 验证

编译器在近几个版本改进了内建属性的处理方式,目标是让错误信息更一致。

Rust 1.92.0 里,macro_export 对参数的允许范围检查更严格,并以「默认拒绝的 lint」形式报告,甚至会在依赖里也报告出来

非法的参数如今会触发 deny-by-default lint(即编译错误)

这是为了统一所有内置属性的错误处理逻辑

Rust 1.92 新稳定 API 一览

  • [NonZero<u{N}>::div_ceil](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil)
  • [Location::file_as_c_str](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str)
  • [RwLockWriteGuard::downgrade](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade)
  • [Box::new_zeroed](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed)
  • [Box::new_zeroed_slice](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice)
  • [Rc::new_zeroed](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed)
  • [Rc::new_zeroed_slice](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice)
  • [Arc::new_zeroed](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed)
  • [Arc::new_zeroed_slice](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice)
  • [btree_map::Entry::insert_entry](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry)
  • [btree_map::VacantEntry::insert_entry](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry)
  • [impl Extend<proc_macro::Group> for proc_macro::TokenStream](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream)
  • [impl Extend<proc_macro::Literal> for proc_macro::TokenStream](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream)
  • [impl Extend<proc_macro::Punct> for proc_macro::TokenStream](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream)
  • [impl Extend<proc_macro::Ident> for proc_macro::TokenStream](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream)

这些先前稳定的 API 现在在 const 上下文中稳定:

  • [<[_]>::rotate_left](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left)
  • [<[_]>::rotate_right](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right)

这些 API 的具体签名与安全约束建议以标准库文档为准,尤其是涉及「zeroed」内存初始化的接口,通常会带来额外的安全注意事项

我们重点来看看这个RwLockWriteGuard::downgrade这个API,等了9年,终于稳定了!

它可以实现锁降级,即将持有的“写锁”(独占访问)原子性地降级为“读锁”(共享访问),而不释放锁

以前我们获取了写锁修改了数据,紧接着又想以只读的方式继续使用这些数据,必须分两步走:得先释放写锁,再获取读锁,所以中间有空窗期,期间可能有其他线程"插队"(抢先获取写锁并再次修改数据)

当有了RwLockWriteGuard::downgrade后,它可以直接降级,中间不会释放锁,原子操作,不给其他线程插队的机会

java
use std::sync::{RwLock, RwLockWriteGuard};

fn main() {
    let config = RwLock::new("Default Config".to_string());

    // 获取写锁,准备修改数据
    let mut w_guard = config.write().unwrap();
    
    // 修改数据
    *w_guard = "New Config".to_string();
    println!("配置已修改。");

    // 使用 downgrade 将写锁降级为读锁,保持锁,原子化
    let r_guard = RwLockWriteGuard::downgrade(w_guard);

    // 现在 w_guard 已经被消耗了,不能再写了。
    // 但是 r_guard 依然持有锁(读锁)。
    
    // 此刻,其他的读线程(readers)可以并行访问了!但写线程依然被阻塞。
    println!("当前配置是: {}", *r_guard);
    
    // 模拟耗时读取
    // std::thread::sleep(...) 
    
} // r_guard 离开作用域,锁最终被彻底释放

文档搜索与构建指南的优化

Rustdoc的搜索功能变得更加智能和友好,比如当搜索结果中包含某个 trait 定义的方法时,Rustdoc 会自动隐藏那些具体实现该trait的类型中的同名方法。

还有当搜索 “last” 将主要显示 Iterator::last,而不会用各个迭代器实现的 last 方法刷屏,使得像 BTreeSet::last 这样的固有方法更容易被找到。

另一方面Cargo 新增了关于 “构建性能优化”的官方文档章节。这对于想要加快项目编译速度的开发者而言,是一个很实用的参考。

小结

这次Rust 1.92.0更新 并没有带来重大变化和新功能,而是为了未来的 !类型稳定化清理技术债务,优化了错误处理的体验(针对 Infallible),并修复了 Linux 下长期存在的调试痛点,同时带来了一些非常实用的 API(如锁降级和零初始化内存分配),以及完善文档与调试能力

参考:https://blog.rust-lang.org/2025/12/11/Rust-1.92.0

关注我,第一时间获得更多学习干货!


作者:小牛呼噜噜

本文到这里就结束啦,感谢阅读,关注同名公众号:小牛呼噜噜,防失联+获取更多技术干货