Rust 编译器错误信息的演变
Rust 编译器错误信息的演变
2025年5月16日 | Reddit 讨论
我最近参加了 RustWeek (非常棒),Alex Crichton (关于 Rust 的历史) 和 Pietro Albini (关于错误信息的重要性) 的演讲启发我对 Rust 编译器信息随时间演变的方式做了一些考古研究。
我写了一个脚本,下载了所有稳定的 Rust 版本,一直追溯到 1.01,对一组包含错误的小程序执行每个稳定版本的编译器,并收集编译器的标准(错误)输出。
下面的小部件可视化了错误信息随时间的演变。您可以使用选择框来检查不同的 Rust 程序以查看它们的错误: Moved variable Wrong field Missing implementation Swapped arguments Wrong argument type Borrow check error Missing where bound Unused variable
#![allow(unused)]
struct S(u32);
fn main() {
let s = S(0);
let s2 = s;
println!("{}", s.0);
}
1.0.0
1.80.0
1.0.0
:9:20: 9:23 error: use of moved value: s.0
:9 println!("{}", s.0); ^~~ note: in expansion of format_args! :2:25: 2:56 note: expansion site :1:1: 2:62 note: in expansion of print! :3:1: 3:54 note: expansion site :1:1: 3:58 note: in expansion of println! :9:5: 9:25 note: expansion site :7:9: 7:11 note: s
moved here because it has type S
, which is moved by default :7 let s2 = s; ^~ :7:9: 7:11 help: use ref
to override error: aborting due to previous error
有几个有趣的地方需要注意:
- 首先,错误信息非常棒。如果您以前使用过 Rust,这可能并不令人惊讶。即使是 Rust
1.0.0
也包含了相当可靠的错误报告,并且随着时间的推移变得更好。 - Rust
1.2.0
引入了数字错误代码。 - Rust
1.26.0
引入了彩色错误信息。 听起来像是一个小小的变化,但是你可以看到它带来了多大的改进!它还添加了rustc --explain <error-code>
提示。 - 错误信息有时会在不同的 Rust 版本中来回变化,这有点有趣。 例如,
error: aborting due to 2 previous errors
在1.19.0
中切换到...previous error(s)
,然后在1.20.0
中又切换回...2 previous errors
,这似乎是1.19.0
中的一个意外更改。 有时差异仅在于一个空格,这在上面的可视化中甚至不可见。 - 错误范围也在 rustc 版本之间不断改进。 我最喜欢的例子是
Wrong field
程序在1.87.0
中的更改。
但我认为,最有趣的是这些消息本身的演变过程,这表明必须付出很多努力才能使它们变得非常好。 对于某些人来说,这些消息似乎是从编译过程中自动派生出来的,并且我们“免费”获得它们,但事实并非如此。 这是由数百名个人贡献者在十多年的时间里进行的持续设计、实施、审查和测试工作的结果。 感谢所有为 Rust 编译器工作并为这些出色的错误信息做出贡献的人!
如果您想在比我在此处显示的程序更多的程序上进行测试,可以在此处2查看我的脚本。
如果您有自己最喜欢的 Rust 编译器错误信息示例,请在 Reddit 上与他人分享!
- 实际上,即使某些最早的版本早于
rustup
,也可以仅使用rustup
来做到这一点(至少在 x64 Linux 上)。 这有多酷?↩ - 有一段时间,我考虑使该小部件具有交互性,以便您可以编写任何 Rust 代码,并在浏览器中直接查看其编译器错误的演变,但这基本上意味着我将不得不为近一百个不同的编译器版本重新实现 Rust Playground,这似乎……对于一篇博客文章来说太多了:) ↩