类型团队更新和路线图

2024 年 6 月 26 日 · lcnr 代表 类型团队

自从最初的博客文章宣布类型团队及其最初的目标以来,已经过去一年多了。有关团队是什么、为什么成立以及我们先前声明的总体目标的详细信息,请查看该博客文章。简而言之,类型团队的职权范围扩展到 Rust 语言和编译器中涉及类型系统的部分,例如类型检查、trait 求解和借用检查。我们的短期和长期目标有效地致力于使类型系统健全、一致、可扩展和快速。

在深入细节之前,值得分享一个快速要点:过去一年,该团队非常成功。通常,很难衡量影响,尤其是在长期路线图目标难以量化进展,并且各种短期目标要么达成要么未达成的情况下。但是,有一个清晰的统计数据在某种程度上表明了该团队的进展:在过去一年左右的时间里,超过 50 个面向用户的更改已落地,每个更改都通过 FCP 获得类型团队共识的单独批准。

这些更改位于语言设计和实现之间的边界,而类型团队(它是语言和编译器团队的子团队)的存在意味着 Rust 项目不仅有足够的带宽来做出这些决定,而且我们还有足够的人员具备类型系统的知识和经验来做出明智的决定,从而整体上改进语言。

类型团队的优先事项

为了评估我们过去一年的进展和未来的路线图,让我们从最重要的优先事项开始。我们将在本文的其余部分中引用它们。为了实现我们的目标,我们需要一个健康的维护者团队,他们拥有专业知识和能力来响应问题并实施复杂的更改。

类型系统应该是健全的

Rust 的主要承诺之一是,仅使用安全代码时不会出现未定义的行为。您可能会惊讶地发现,目前存在已知的类型系统错误,这些错误破坏了这些保证。这些问题中的大多数是由熟悉编译器内部工作原理的人员通过明确地寻找它们而发现的,并且我们通常不希望用户意外地遇到这些错误。无论如何,我们非常关心修复它们,并致力于实现完全健全且理想情况下经过验证的类型系统。

类型系统应该是一致的

类型系统应该易于推理。我们应该尽可能避免粗糙的边缘和特殊情况。我们希望尽可能保持实现和面向用户的行为简单。在可能的情况下,我们希望考虑整体设计,而不是提供局部的有针对性的修复。这对于建立对类型系统健全性的信任以及允许更简单的 Rust 心智模型是必要的。

类型系统应该是可扩展的

Rust 仍在发展,我们将需要扩展类型系统以支持未来的新语言特性。这要求类型系统是可扩展和易于理解的。语言的设计不应为了规避当前类型系统实现的缺点而进行调整。我们应该与其他团队和用户合作,以确保我们了解他们的问题,并在我们的实现和设计中考虑可能的未来扩展。

类型系统应该很快

我们关心 Rust 的编译时间,并希望考虑我们的设计对编译时间的影响。我们应该寻找有效的方法来加速现有实现,通过改进缓存或在适用的情况下添加快速路径。我们还应该了解未来类型系统添加对编译时间的影响,并在可能的情况下提出性能更高的解决方案。

更新

在过去的一年里,我们一直非常活跃,并取得了一些重大进展。还有一些非技术更新,我们想分享一下。

组织更新

首先,热烈欢迎自公告发布以来加入团队的两名新成员:@BoxyUwU@aliemjay@BoxyUwU 一直在 const generics 上做了大量工作,并为下一代 trait 求解器的设计做出了重大贡献。@aliemjay 一直在对 opaque 类型 - impl Trait - 和借用检查进行一些非常细微的改进。他们都是团队的宝贵补充。

我们还在去年 10 月,紧接着 EuroRust 之前组织了另一次类型团队的面对面会议。我们讨论了团队的现状,研究了当前的实现挑战和正在进行的工作,并审查和更新了上次会议的路线图。其中大部分内容将在本文中介绍。

最后,正如 RFC 中讨论的那样,我们希望领导者定期轮换,主要目的是帮助分担领导工作的负担和经验。因此,@nikomatsakis 将卸任,@lcnr 将加入与 @jackh726 一起担任联合领导。

路线图进展和主要里程碑

下一代 trait 求解器

下一代 trait 求解器上已经进行了大量工作。该倡议在去年年底发布了单独的更新。虽然我们本来希望在几个月前稳定其在一致性中的使用,但这暴露了额外的行为回归和小故障,导致了延迟。我们正在努力解决这些问题,并打算尽快合并稳定 PR。我们即将能够使用新的求解器在所有地方启用编译标准库和编译器,之后我们将能够运行 crater 来找出剩余的问题。我们预计会出现大量次要问题和与现有实现的行为差异,因此这里仍有很多工作要做。还有一些开放的设计问题,我们必须在稳定新实现之前解决。

Async 和 impl Trait

@compiler-errors@spastorino 的大力努力下,我们在 1.75 版本中稳定了 traits 中的 async-fn (AFIT) 和 traits 中的返回位置 impl Trait (RPITIT)。@cjgillot 大大改进了生成器(因此也是异步函数)在类型系统中的表示方式1。这使我们能够在没有太多额外工作的情况下支持递归 async 函数2

在设计下一代 trait 求解器时,我们发现了旧的 trait 求解器在使用类型别名 impl Trait (TAIT) 实现中的问题和未来兼容性挑战。我们目前正在重新设计和实现。 @oli-obk 正在领导这项工作。这也影响了 RPIT 的边缘情况,迫使我们小心避免意外中断。TAIT 存在一些开放的语言设计问题,因此我们计划稳定关联类型位置 impl Trait (ATPIT),因为它避免了这些语言设计问题,同时仍然弥补了表达上的差距。

a-mir-formality

过去一年,我们在 a-mir-formality 上取得的进展有限,主要是因为我们能够分配给这项工作的时间比预期的要少。我们已将其作为共同归纳 trait 的直观方法的基础,这对于解决许多剩余的不健全问题是必要的。

修复健全性问题

我们修复了多个长期存在的不健全问题,请参阅 已关闭问题的完整列表。其中最值得注意的是 #80176。这个细微的问题导致我们接受 trait 实现中的方法,这些方法的函数签名具有 trait 定义中不存在的 outlives 要求。然后在调用 trait 方法时从未证明这些要求。由于有些 crates 意外地依赖于这种模式,即使它们的使用没有利用这种不健全性,我们首先合并了一个未来兼容性 lint,然后在几个版本后将其移动为硬错误。

我们还花时间对剩余的未解决问题进行分类,并将它们纳入我们的长期计划中。剩余的大部分问题都因为下一代 trait 求解器而受阻,因为修复它们依赖于共同归纳 trait 语义和隐含界限的改进。有一些剩余的问题现在至少可以部分修复,我们打算在进行过程中解决它们。最后,还有一些问题我们仍然没有找到最佳方法,需要进一步考虑。

展望未来

在过去的一年里,我们取得了显著的进展,但我们并未止步!本节涵盖了我们 2024 年剩余时间的目标。对于每个项目,我们还链接到了我们在 Rust 项目的实验性新路线图流程中提出的项目目标。

-Znext-solver

我们最大的目标是默认情况下在所有地方使用下一代 trait 求解器,并完全替换现有的实现。我们目前正在最终确定其在一致性检查中的使用的稳定化。这应该已经修复了多个不健全的问题,并修复了当前实现的许多较小的问题和不一致之处。有关更多详细信息,请参阅稳定化报告。

我们还在努力将其实现提取到编译器本身之外的单独库中。我们希望在今年年底与 rust-analyzer 共享 trait 求解器。他们目前使用不再积极维护的chalk。在 rust-analyzer 中使用下一代 trait 求解器应该为求解器带来大量的额外测试,同时通过积极影响性能和正确性来改善 IDE 体验。

我们计划在编译器的其他领域逐步推出求解器,直到我们能够在 2025 年底完全删除现有实现。此切换本身将修复多个不健全的问题,并将解锁大量的未来工作。它将普遍清理类型系统的许多粗糙边缘,例如高阶类型中的关联类型。只有当我们专门使用新实现时,才能修复许多不健全的问题。

a-mir-formality

我们计划今年更积极地开发 a-mir-formality,以便在我们的设计过程中使用它。使用它来建模类型系统的部分内容已经产生了令人难以置信的影响,我们希望在此基础上继续发展。我们正在通过允许它用于实际的 Rust 代码片段并添加模糊测试支持,来更有效地测试 a-mir-formality。这将使我们对类型系统的模型获得更多信心,并将指导其未来的发展。

我们计划今年完全形式化类型系统的某些组件。一致性是相当独立的,非常微妙,并且对健全性至关重要。这在过去阻止了我们对其进行重大改进。我们还计划形式化协同归纳 trait 语义,这很难推理,并且对于修复许多长期存在的不健全问题是必要的。

语言变更和 Polonius

我们计划在今年为 TAIT 和 ATPIT 的稳定化做好不透明类型的内部实现准备。我们还希望在今年对我们在一致性检查中处理关联类型的方式进行重大改进。

我们的另一个目标是让Polonius,下一代借用检查器,在 nightly 版本上可用,这将使我们能够在 2025 年稳定它,一旦我们有时间进行更多的优化和测试。

我们还计划支持其他语言特性的开发,例如 async-closures,它是异步项目目标的一部分,以及 dyn-trait 向上转型,我们希望它能在不久的将来稳定下来。

路线图

2024 年底

  • 下一代 trait 求解器
    • 在一致性中稳定
    • 被 rust-analyzer 使用
  • ATPIT 稳定
  • a-mir-formality
    • 支持模糊测试和测试 Rust 代码片段
    • 完成一致性和协同归纳 trait 语义的模型
  • 完整的 Polonius 实现在 nightly 版本上可用

2025 年底

  • 默认情况下在所有地方使用下一代 trait 求解器
  • TAIT 稳定
  • Polonius 稳定

2027 年底

  • 下一代 trait 求解器
    • 支持在 for<'a> 上进行协同归纳和(隐式)where-bounds
    • 启用完美的派生
  • a-mir-formality 完全建模 Rust 的健全性关键部分
  • 所有已知的类型系统不健全问题都已修复
  1. https://github.com/rust-lang/rust/issues/107421 中稳定

  2. https://github.com/rust-lang/rust/issues/117703 中稳定