使用 cargo-bisect-rustc 二分查找 Rust 编译器回归

2019 年 12 月 18 日 · Santiago Pastorino 代表 编译器团队

假设你刚刚更新了 Rust 编译器版本,尝试编译你的应用程序时发现了一个之前不存在的错误。这很可能是由于编译器中的回归造成的。我们刚刚发布了 cargo-bisect-rustc,一个能让你轻松准确地找到回归何时发生的工具。

cargo-bisect-rustc 会自动下载 rustc 构建产物,并用它们测试你提供的项目,直到找到回归。至少,它会确定触发回归的 nightly 发布版本;但如果回归发生在最近 168 天内,它甚至能找出确切的 PR,这通常对于帮助我们修复问题非常有益。

cargo-bisect-rustc 最初由 Mark Rousskov 创建。我最近对其进行了扩展,使其更易于使用。

要安装该工具,请运行

cargo install cargo-bisect-rustc

查找回归

我们将使用这个“旧的”已报告的 rustc 回归作为示例

我们的应用程序只包含这个文件

pub struct Slice<'a, T>(&'a [T]);

impl<'a, T: 'a> Slice<'a, T> {
    pub const EMPTY: Self = Slice ({
        let v: &[T] = &[];
        v
    });
}

fn main() {
    let s = Slice(&[1, 2]);
    assert!(s.0 != Slice::EMPTY.0);
}

然后我们运行 cargo bisect-rustc --end=2019-10-02

由于这个 bug 在 2019-10-03 修复,我们使用 2019-10-02 作为结束点。对于这个特定的例子,鉴于这个 bug 在 2019-10-03 修复,我们需要提供结束点,我们使用 2019-10-02 作为结束点。如果你不提供结束点,它会假定结束点是今天的 nightly 版本或你当前安装的 nightly 版本。如果你不提供起始点(就像我们这样做),它会通过回溯时间来尝试找到一个。如果你知道一个失败的起始点,直接提供它会更快。

默认情况下,它会在项目中运行 cargo build 并检查是否失败。找到一个发生回归的 nightly 版本后,它会自动搜索引入回归的提交。

让我们看看这个工具是如何工作的

工具开始下载各种 nightly 编译器,尝试找到程序能正常工作的日期...

checking nightly-2019-10-02
std for x86_64-unknown-linux-gnu: 172.87 MB / 172.87 MB [===============================================================================================================================================================] 100.00 % 10.67 MB/s uninstalling nightly-2019-10-02
checking nightly-2019-09-30
...

一旦找到了一个失败点和一个工作点,它就开始二分查找...

std for x86_64-unknown-linux-gnu: 173.43 MB / 173.43 MB [===============================================================================================================================================================] 100.00 % 12.82 MB/s uninstalling nightly-2019-09-29
tested nightly-2019-09-29, got No
searched toolchains nightly-2019-09-28 through nightly-2019-09-30
regression in nightly-2019-09-30

找到一个 nightly 版本后,它开始搜索进入该 nightly 构建的 PR...

looking for regression commit between 2019-09-30 and 2019-09-29
fetching commits from 488381ce9ef0ceabe83b73127c659e5d38137df0 to 8431f261dd160021b6af85916f161a13dd101ca0
...
searched toolchains 488381ce9ef0ceabe83b73127c659e5d38137df0 through 8431f261dd160021b6af85916f161a13dd101ca0
regression in 0bbab7d99dde8620604fb265706dc8bff20345a7

最后,当它找到导致编译器出错的 PR 时,会生成一份你可以复制粘贴的 bug 报告!

==================================================================================
= Please open an issue on Rust's github repository                               =
= https://github.com/rust-lang/rust/issues/new                                   =
= Below you will find a text that would serve as a starting point of your report =
==================================================================================

# Regression found in the compiler

searched nightlies: from nightly-2019-09-28 to nightly-2019-09-30
regressed nightly: nightly-2019-09-30
searched commits: from https://github.com/rust-lang/rust/commit/488381ce9ef0ceabe83b73127c659e5d38137df0 to https://github.com/rust-lang/rust/commit/8431f261dd160021b6af85916f161a13dd101ca0
regressed commit: https://github.com/rust-lang/rust/commit/0bbab7d99dde8620604fb265706dc8bff20345a7
source code: URL OF A REPOSITORY THAT REPRODUCES THE ERROR

## Instructions

Please give the steps for how to build your repository (platform, system dependencies, etc.)
## Error

<details><summary>COLLAPSIBLE ERROR STACKTRACE</summary>
<p>

```bash
$ Paste the error the compiler is giving
```

</p></details>

这告诉我们回归始于 0bbab7d99dde8620604fb265706dc8bff20345a7,你可以查看 git log 找到 PR。在这个例子中是 #64470

行动号召:试试这个工具

请试用这个工具,如果你发现更新应用程序后构建失败,很可能你遇到了回归。正如你在工具执行结束时所见,如果找到了回归,该工具会给你一份报告,你可以将其粘贴到 Rust 仓库的 GitHub Issue 中。

行动号召:参与 cargo-bisect-rustc 的开发

这个工具还有很多可以改进的地方,也有很多 bug 需要修复。有很多报告的 Issue 都很容易修复,去看看吧。你也可以联系我们。你可以在 Zulip 的 #t-compiler/cargo-bisect-rustc 流中找到我以及其他编译器贡献者和成员。如果你还没注册,可以在那里注册,随时提问,或者如果你不知道从哪里开始,甚至可以直接给我发私信。