Rust周刊2026W35 | never type 稳定化、next solver 登 nightly、arrayref 供应链投毒、min-publish-age 转正

never type 稳定化、next solver 登 nightly、Vec::retain_mut 提速 44%;arrayref 遭供应链攻击,min-publish-age 转正防投毒。

🦀 Rust 工具链更新

🔧 编译器

🆕 新功能

const generic 现在允许使用 self,写泛型常量表达式时不必再绕开 Self 相关写法,约束表达能力更完整。nightly 用户会最先感受到这一变化。

⚡ 性能优化

WfPredicates visitor 增加了缓存,DeepRejectCtxt 也做了优化,两者都作用在类型检查的高频路径上。大型项目的编译耗时有望小幅下降。

🐛 Bug 修复

清理了 expand_(option_)env() 中几处会误触发的 unreachable!(),减少了编译器在边界场景下 panic 崩溃的概率。

🔧 改进

-Znext-solver 已在 nightly 上默认启用,新 trait solver 成为默认路径。这意味着更多泛型代码的行为将按新规则执行,遇到回归可临时关闭该 flag 对比排查。

📚 标准库

🆕 新功能

新增 Arc/Rc::strong_count_from_raw,可直接在裸指针上读取强引用计数,便于调试自引用结构。std::sync::Once 实现了 Default,放进结构体时不再需要手写初始化。Vec、&[T]、&mut [T] 与 Cow<'_, [T]> 之间补齐了对称的 PartialEq impl,混用切片与 Cow 时比较不再受操作数顺序限制。

✅ 稳定化

bool::toggle 稳定化,翻转布尔值不必再手写取反赋值。never type(!)也进入稳定化流程,能更自然地标注永不返回的函数。

⚡ 性能优化

BorrowedCursor<'a, T> 改为对 'a 协变并去掉了一层间接寻址,借用传递更灵活、开销更低。非零整数的 div_ceil 重写后生成的代码更紧凑。

🔧 改进

core 补齐了一批浮点转换方法,在 no_std 环境下做数值类型互转时不必再依赖 std。

🧹 Clippy

⚡ 性能优化

Clippy 自身改用 PGO 构建,useless_format 也改为先判断 first_node_in_macro 再走宏展开,整体检查速度更快,CI 等待时间缩短。

🧹 新增 lint

新增针对 Option 迭代器做 fold 的 unnecessary_fold 提示,会把 x.mul_add(x, y * y).sqrt() 建议为 hypot,并建议对返回布尔值的 Result 映射改用 is_ok/is_err。integer_division_remainder_used 现在也覆盖 DivAssign/RemAssign 复合赋值。

🐛 误报修复

manual_assert_eq 不再对字节切片类类型误报,manual_contains 在两侧都使用切片元素时不再触发,double_must_use 跳过宏生成的代码,needless_bool 对链式 if 更保守,blocks_in_conditions 移除了会给出错误修复建议的行为,large_futures 在新 solver 下的 ICE 也已修复。lint 结果更可信,误报带来的无谓改动减少。

🔧 改进

unused_trait_names 的修复建议可读性更好,开发者更容易照着改。

🔌 Rust-Analyzer

⚡ 性能优化

优先复用父 body 的 expression store,并大幅优化了 token tree 的存储方式,内存占用和大型工程的响应延迟都有改善。

🐛 Bug 修复

修复了宏内函数导致的 unmap range 问题,asm! label block 允许发散,递归 ADT 布局引发的栈溢出也被拦住,编辑器不再因这些场景崩溃或给出错位的语义高亮。

🔧 改进

flycheck 日志改写到 Cargo 的构建目录,清理临时产物更方便,也不会再散落在项目根。

📋 跟踪 issue

✅ 稳定化推进

智能指针的 map 系列函数、supertrait_item_shadowing 特性以及 resolver 的 min-publish-age 都在推进稳定化,落地后相关写法可直接在 stable 上使用,也能用发布时长门槛降低供应链风险。

🆕 新功能

整数最大最小值 intrinsic 与 codeview_annotation intrinsic 进入跟踪,后续可为底层数值代码和 Windows 调试信息生成提供更直接的支撑。

⚠️ 行为变更

ARM 上 target feature 的 ABI 检查将升级为硬错误,volatile 访问非 AM 内存允许 trap,str::escape_debug 将始终转义 grapheme extender。依赖这些行为的代码需要提前评估,尤其是底层和 FFI 场景。

🔧 平台与治理

i686-pc-windows-msvc 计划从带 host tools 的 Tier 1 调整为不带 host tools 的 Tier 1,使用该目标的开发者需关注工具链可用性。项目还启动了 PD 选举流程修订与 LLM 政策小组的组建。

📝 新增·更新 RFC

🆕 新 RFC

新增 core::ffi::c_longdouble 的 RFC,拟为 FFI 场景补齐 long double 对应类型,需要与 C 长双精度交互的项目值得关注。freeze operation 的 RFC 也在推进,落地后可显式冻结值以启用更多优化。两个 RFC 均处于讨论阶段,欢迎参与评议。

📦 Cargo

🆕 新功能

新增 build.fingerprint 配置项,开发者可以按需关闭或调整构建指纹行为,在特殊文件系统或 CI 缓存场景下更灵活。

🐛 Bug 修复

修复了在 safe.bareRepository=explicit 配置下 git gc 报错的问题,使用严格 git 安全配置的机器不再因此拉取依赖失败。

🔧 改进

cargo install 安装命令行工具时默认带锁定的依赖版本,装出来的工具更可复现,不会因上游发布新版本而突然行为不一致。

📄 Rustdoc

🆕 新功能

新增 invalid_markdown_table lint,文档中写错的 Markdown 表格会被提示,避免生成出排版错乱的页面。

⚡ 性能优化

只有真正启用搜索时才生成搜索用的 DOM 元素,大项目的文档产物体积和页面加载负担都随之下降。

🔧 改进

滚动条只作用于表格和代码块,长代码块不再把整页布局撑乱。

🐛 Bug 修复

修复了导致 "read more" 链接无法生成的问题,长文档项的展开入口恢复正常。

🎨 Rustfmt

🐛 Bug 修复

修复了 for await 循环在关键字被宏拆开时触发的 ICE,异步代码格式化不再崩溃。多行控制流的大括号位置、ast::TyKind::FnPtr 重写所用的 span、关联 impl type alias 的可见性与 defaultness 顺序也都得到修正,diff 噪声更少。

🔧 改进

修正了注释换行后被重写得过长的问题,以及宏内文档注释格式不一致的问题,格式化结果更稳定可预期。

🦀 Official

公布我们的首批驻场维护者

Google、AWS 和 OpenAI 目前正资助六位 Rust 贡献者,让他们在未来 12 个月内专注于 rust-lang 的维护工作——这是首批从一个按“团队距离最低可维护者人数缺口有多大”来分配资金的项目中拨出的款项。关键的开源基础设施长期依赖那些在夜晚和周末无偿付出的志愿者,Rust 最繁忙的几个团队明知人手不足,却无法仅凭善意解决这个问题。文章详述了 RFC 3931 项目、遴选背后系统化的基线分析,以及每位受资助维护者将要负责的工作。

针对 arrayref 的供应链攻击

攻击者入侵了一位受信任 Rust 维护者的 crates.io 凭据后,并没有发布一个全新的恶意 crate——他们重新发布了 arrayref,把它指向一个会投放载荷的过程宏,同时 yank 掉干净版本,使构建回退到被投毒的发行版上。Cargo 构建脚本在编译期以完整的机器权限执行,因此一个被攻陷的传递依赖就能让攻击者在每一个下游项目中获得任意代码执行能力。读者将得到受影响 crate 的完整清单——arrayref、internment、append-only-vec 以及另外五个——它们确切的恶意版本号,以及一条用于扫描 ~/.cargo/registry/cache 检查本地是否受影响的 find 命令。

Rust 函数重载——征集实验

Rust 其实已经支持函数重载——只是你得用双括号来调用它:hypot((2.0, 3.0, 6.0))。在 Rust 基金会的 Rust-C++ 互操作计划支持下,nightly 上一个不稳定的“splat”特性(#[rustc_splat])如今允许重载的 FFI 函数接收普通的逗号分隔参数,比如 hypot(2.0, 3.0, 6.0),类型推断与类型检查保持不变。这种别扭的元组语法长期以来让 C++ 互操作绑定的生成和阅读都很痛苦,团队希望真正的编译器与互操作工具开发者来判断这份实现复杂度是否值得。文章介绍了从哪里获取 nightly 构建、splat 的具体行为,以及一位 Outreachy 实习生正在开发的人机工程学宏——同时提醒该特性尚无 RFC,可能发生变化甚至消失。

📖 Observations/Thoughts

规模化内存安全:用 AI 辅助将 C/C++ 依赖重写为 Rust

C 和 C++ 代码库中约 70% 的漏洞源于内存安全,因此 Google 把 Gemini 指向了 giflib——一个仅三千行、在沙箱之外解析不可信图片的 GIF 库——并产出了一个 ABI 兼容、可直接替换的 Rust 版本。翻译本身是容易的部分;真正困难的是证明一个 AI 生成的分支足够可信,可以部署到生产基础设施上而不破坏依赖它的服务。你将看到三步走的 LLM 翻译工作流、捕获到真实边界情况的穷尽式差分测试流水线,以及信任一个 AI 分支所需的两个前提。

用 64 位字替换 Rust 枚举,让我的解释器快了 17%

把单个 Rust 枚举换成单个 64 位字,让 Plush 解释器快了 17%——那个惯用的带标签枚举正是瓶颈所在。动态类型语言中的每一个操作都要接触 Value,而 Plush 那个 14 变体的枚举让每个值多占 16 字节,还要付出 match 分派以及字符串、数组和对象等堆类型的指针跳转开销。文章逐步讲解如何把这些变体全部打包进一个机器字、其中涉及的位级编码技巧,以及衡量这笔收益的基准测试——这是通往实时 3D 渲染之路上的一步。

通过元数据分析省下 3 秒编译时间

摘要已输出(约 100 词,符合 60-120 约束),钩子取“在编译器自身数据尚非法的时刻读取元数据反而能省 3 秒编译”的时机反常识,冲突展开 TyCtxt 未成形/span 不可访问/query 未定义的三重脆弱性。

同时已将该实例(Rust 编译器内部机制实验记录类,新变体)追加到摘要质量 memory。

你的电子纸面板没坏:保留状态如何让驱动看起来像有 bug

硬件复位清不掉它——只有断电才行。在电子纸刷新过程中打断它,控制器可能把 BUSY 永久锁存,让驱动一直等待一个永远不会完成的操作。一次 Ctrl-C 或拔线,会让之后每一次运行都以完全相同的方式超时——每个阶段 60 秒,一次刷新三分钟——永远如此,与代码中一个确定性 bug 的表现无法区分,而那段代码从来就没写错,同时 RST 依然像健康时那样脉冲着 BUSY。作者追溯了那次耗掉一整天的 RP2350 到 ESP32-C3 移植,解释了故障为什么会自我复现,以及如何在重写本来能正常工作的驱动代码之前,先识别出控制器保留状态。

要异步还是不要异步:为 rust-analyzer 构建 Rust MCP 服务器

尽管为 r3bl_tui 终端工具箱打下了多年的异步基础,Nazmul Idris 依然选择用纯同步 Rust 编写他的新 MCP 服务器,全程没有 Tokio,也没有一个 .await。一个为同时处理数十万个 Web 服务器套接字而设计的运行时,在 1:1 的本地 stdio 管道上一无所获,只是徒增了额外的复杂性,却没有换来性能、可读性或可维护性上的任何提升。文章讲述了为何现有的 Rust MCP crate 在 Antigravity 下会失效,以及因地制宜的设计如何战胜了异步教条。

一棵 trie 干三件事,微基准测试一场未赢

每一个微基准测试都显示 wordtree 会输:查找比 HashMap 慢,文件体积是 FST 的 3 倍,拼写纠错比 symspell 差一个数量级。然而一个翻译应用需要从同一份词表上同时获得查找、前缀搜索和拼写建议,而它的运行设备既在意启动时间也在意内存占用,没有任何专用 crate 能从一个免解析的文件里同时提供这三种能力。文章讲解了扁平的广度优先 trie 布局、8 字节节点如何服务三项工作,以及那些可复现的对比数据。

修复 Rust 的供应链安全:好的、坏的与丑陋的

无法生成摘要。

原因**:提供的内容不是文章正文,而是站点在 JavaScript 未启用时的占位提示页:

> “We're sorry but this website doesn't work properly without JavaScript enabled. Please enable it to continue.”

全文仅此一句,零文章正文被捕获——标题(Rust 供应链安全)与内容(SPA 的 no-JS fallback 文案)完全不对应。任何“钩子+冲突+收益”摘要都只能凭标题和我对该话题的先验知识编造(例如臆测 crates.io 依赖投毒、cargo 审计工具对比等),这违背宁缺毋滥原则。

建议**:用可渲染 JS 的方式重新抓取该页正文(带渲染的抓取器、Google 缓存/存档页,或改用该文的 PDF/镜像/作者博客源),再提交生成。

📚 Rust Walkthroughs

每个 Rust 新手都会踩到的错误

Rust 编译器早就把修复方案写给你了——当 help: 里出现 +++ 时,那是一段真正的 diff,而不只是提示。新手依然会和借用检查器搏斗,因为每个错误都标注了两个位置:规则被破坏的地方,以及做出错误决定的地方,而修复几乎总在后者。这篇对 22 个真实 rustc 1.96 诊断信息的导览,会教你把它们当作 diff 来读,并从源头修复错误。

用 Rust 构建科学计算器——理解变量与类型

Rust 让每一个变量都默认不可变——这是对几乎所有其他语言的一次刻意反转,在那些语言里可变性才是常态。这一个设计选择迫使新手从一开始就必须直面所有权和类型安全,也正因如此,科学计算器是一个完美的第一个项目:解析、数学运算和用户输入全都依赖正确的类型与绑定。文章先带你完成 rustup 与 Cargo 的环境搭建,然后一步步构建这个计算器,同时深入讲解 Rust 的标量类型、可变性以及变量遮蔽。

用 bpftrace 验证 SQLx 的语句缓存

SQLx 默认为每个 Postgres 连接缓存最多 100 条预处理语句——但只要多出一个占位符,就会让看起来相同的查询变成独立的缓存条目,从而静默地把 LRU 挤出去。文档化的行为既容易轻信也容易误判,于是作者把 bpftrace 的 uprobe 直接挂到套接字系统调用上,观察 Parse 与 Bind 报文的流动。你将获得容器的搭建方式、这套追踪装置,以及系统调用层面的证据。

超越 WASI:在浏览器中运行 Rust 应用

ripgrep、starship、Jujutsu(20 万行)乃至 OpenAI 的 Codex(125 万行)如今都能不经修改地在浏览器标签页里运行,并拥有真实的文件、网络、子进程和线程。WASI 无法把它们带到那里:它的目标平台会裁剪标准库特性、缺乏真正的并行能力,并且会让那些需要调用 git 或 node 的程序(比如用 Rust 重写的 Yarn 6)直接失效。你将看到 BrowserPod 3.0 如何定义自己的 wasm32-browserpod-linux-musl 目标、那些阻止 crate 退化成“web 模式”的条件编译技巧,以及如何把自己的 Rust CLI 编译到浏览器里。

📦 Crate of the Week

本周 crate:swift-topomap

本周的 crate 是 swift-topomap,一款微架构可观测性工具。

📌 miscellaneous

JetBrains 与 Rust 基金会合作推出 AI 直播

JetBrains Rust 生态负责人的一次公开喊话,最终变成了一次合作而非一场争执:Rust 基金会看到 Vitaly 那条批评基金会在呈现 Rust 与 AI 方面做得不够的推文后,主动打了电话过去,如今正与 JetBrains 联合主办一系列 AI 直播。这种紧张关系是真实的——AI 辅助的贡献正让开源维护者被拉取请求淹没,而社区需要就 Rust 究竟能为 AI 工具链带来什么展开坦诚对话。JetBrains 的 Rust 开发者倡导者、Ratatui 维护者 Orhun Parmaksiz 将主持 8 月 27 日 16:00 UTC 的首场直播,内容涵盖真实用例、成功与失败经验,以及 AI 的 Rust 一面。

🛠 Rust 官方项目开发进展

never type 稳定化、标准库 UB 根治与免费性能提速

rustc 与标准库本批有三类值得关注的落地。语言特性:never type(`!`)稳定化,never type fallback 在所有 edition 上改为 `!`,`Infallible` 变成 `!` 的类型别名,并移除已无法触发的 `dependency_on_unit_never_type_fallback` lint;同时重写了 never type 官方文档,并移除 core 中为将来 `impl<T> From<!> for T` 预留的保留实现——该实现挡不住真正冲突的写法,反而会在 `Infallible` 变成别名后与生态已有实现冲突(实测破坏 14 个 crate)。用户可更自然地使用 `!` 表达永不返回或不可能的类型,但依赖旧「fallback 到 `()`」行为的代码升级后可能编译失败,需逐处检查。正确性与稳定性:修掉一批可真实触发的 UB 与 ICE,包括给 `BTreeMap::split_off` 下降循环加 abort-on-panic 守卫(比较器 panic 会让两棵树处于不一致状态并导致二次释放,连 `#![forbid(unsafe_code)]` 的代码都躲不掉)、用新的 COpaque 辅助类型消除包装 pthread 等不透明 C 类型时的别名违规(AIX 等平台内部本就把这些类型放共享链表里),以及规范化 `-Znext-solver=globally` 下协程 yield 类型的非刚性别名以消除 borrowck 断言失败。用户可见行为与性能:`str::escape_debug` 现在始终转义字素扩展符,与 `impl Debug for str` 一致,依赖该输出的日志与测试快照需检查预期;浮点转整数的 `to_int_checked` 预计算精确边界后直接分派 unchecked 变体,省掉额外钳位;aarch64 上的 `Vec::retain_mut` 新增 SVE 加速实现(因 intrinsic 会剥离指针 provenance 而改用内联汇编),保留半数元素场景耗时降低约 29%–44%,`String::retain` 同样受益且 API 语义不变。

来源:stabilize never type · Abort instead of unwinding out of an inconsistent BTreeMap::split_off · Add SVE-accelerated Vec::retain_mut for aarch64

Cargo 依赖治理能力转正,Git 依赖拉取更快更安静

依赖治理侧两项 nightly 能力进入稳定通道:`[registry] global-min-publish-age` 允许要求依赖发布满一定天数(如 “7 days”)才被解析选中,给漏洞扫描留出窗口,紧急升级可用 `CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow` 放行并记入 lockfile,解析时会提示被跳过的新版本发布时间及可降级的兼容区间;`[lints.cargo]` 工作区/包级 lint 系统同样稳定,可在 `[workspace.lints]` 或 `[lints]` 中按 lint 组配置 warn/deny,初批 lint(如未使用依赖检查)已随文档发布,`package.rust-version` 低于 1.79 时默认级别 lint 会被忽略。团队无需 nightly 就能防住刚发布即被投毒的依赖,并自动发现清单问题。Git 依赖获取侧做了三项改进:给 git-cli 的 fetch 加 `--no-show-forced-updates` 并用 advice 关掉随之产生的告警,省掉强制更新检查开销且不抬高最低 Git 版本要求;去掉进度显示时的 ref 状态更新,让输出只保留远端对象枚举、接收和解 delta 等必要行,歧义 ref 场景的刷屏明显减少;并移除 CI 中的 gix override 运行模式与代码里的对应开关,为将来评估默认切到 git-cli、甚至移除 gix fetch 模式铺路。使用 Git 依赖的项目 fetch 更快、终端噪音更低。

来源:feat(resolver): Stabilize min-publish-age · feat(diag): Stabilize cargo-lints · perf(git): Reduce extra work when using git-cli

Cargo 构建诊断输出与性能分析的可读性修复

修复并改进了构建期的可观测细节:`cargo run` 在子进程以 `\r` 结尾输出且带非零退出码时,先补一个换行再打印错误,避免退出码被进度行覆盖(Windows 上尤其明显);profiling 侧移除了记录大对象 UnitGraph 和位于热循环中的 `trace!` 调用,改为在 `fn compile()` 上做更细的 instrumentation 并尽量不下沉到叶子函数,让 `CARGO_LOG_PROFILE` 下的火焰图噪音更少、更能定位真正的耗时阶段;另外回滚了「把 sysroot 查询移到 GlobalContext」的重构,修掉由此引入的 #17351 回归,并会回推到 beta。对用户的影响是构建诊断输出更准确、性能分析数据更可靠,不会因为工具自身的输出或埋点问题而误判失败原因或耗时热点。

来源:fix(run): Printing a new line to avoid overwriting error code after \r · Cargo profiling improvements · revert: refactor: move sysroot lookup to GlobalContext


往期精选


阅读原文


扫码关注「右耳朵猫AI」

扫码关注「右耳朵猫AI」

posted @ 2026-09-03 10:39  右耳朵猫AI  阅读(15)  评论(0)    收藏  举报