特性工作组 2020 年第一次冲刺总结

2020 年 3 月 28 日 · Jack Huey 代表 特性工作组

本周二,特性工作组完成了 2020 年的第一次冲刺,持续了 6 周,从 2 月 11 日到 3 月 24 日。上次冲刺大约在一年前,但我们决定恢复这种形式,以帮助推进 Chalk 和 rustc 中与特性相关的工作。

什么是 wg-traits,我们做什么?

目标:为 Rust 特性系统创建一个高效、可扩展且可重用的 crate

特性工作组的总体目标是创建 Rust 特性系统的高性能、可扩展和简洁的实现。此实现不仅应能扩展到现有的 Rust 功能,还应能扩展到新的和即将推出的功能,例如

似乎这还不够,我们希望该实现也是可重用的,这意味着它不仅可以被 rustc 使用,还可以被 rust-analyzer 以及其他潜在的上下文使用。

这项工作是编译器团队的重大长期目标之一:库化。这指的是将编译器分解为可以独立学习、测试和开发的独立库的想法。

为了实现这些和未来的功能,我们的工作分为两个部分:1) 改进 rustc 现有的特性求解器。2) 设计和实现 Chalk 特性求解器,努力集成到 rustc 中。简而言之,Chalk 特性求解器是一个基于逻辑的特性求解器,旨在独立于 rustc 内部结构。除了比当前 rustc 特性求解实现更强大之外,Chalk 还可以用作编译器相关工作的库,例如 IDE 集成 (例如 rust-analyzer)。

进入 2020 年,我们(特性工作组)知道我们希望更有组织地开始推动 Chalk 完全集成到 rustc 中,通过清理 Chalk 代码库本身、修复错误、实现新功能,并最终将 Chalk 集成到 rustc 中。此外,我们致力于记录设计考虑因素和决策,以便现在和将来更好地访问。例如,我们现在发布了一本 Chalk ,虽然不完整,但试图记录 Chalk 内部结构,有点类似于 rustc 开发指南

关于 Chalk 在 rustc 中集成的说明

Chalk 的实验性集成在 rustc 中(使用 -Z chalk 标志)已经超过一年了,但是自从最初的实现以来,当 Chalk 本身完成了很多工作时,几乎没有进行任何工作。这最终意味着基于较旧的 Chalk 版本的初始实现与基于当前 Chalk 的实现看起来应该非常不同。基于这个原因,该实验性实现已被删除。

2020 年第一次冲刺

好的,在完成背景介绍后,让我们进入实际的 2020 年第一次冲刺。进入这次冲刺时,我们不太清楚我们的目标是什么。在这篇文章中,我们将分享本次冲刺期间完成的每一项工作的概述,实际上相当多!

功劳归于应得之人

非常感谢 :hearts: 参与这次冲刺的人员

wg-traits 技能树

我们的“技能树”是我们跟踪我们的 开发路线图的方式。它显示了我们正在努力实现的一些主要目标(例如,使 chalk 可用作独立库)以及我们必须完成的一些主要任务。您可以单击任务以转到 github 问题或其他解释。我们尝试在每次会议后更新它,以便我们了解我们在做什么以及为什么。

技能树结构受到了 这篇关于 WebAssembly 的博客文章的启发,该文章又从游戏中借用了这个术语。遗憾的是,当前生成技能树的工具还没有像 WASM 帖子中手绘艺术那样精美。如果有任何人有兴趣改进该工具的输出,那将是即将到来的冲刺的“延伸目标”之一!

Chalk 书 chalk-engine 章节

如前所述,为了记录 Chalk 内部结构,我们在去年年底开始出版一本 。在本次冲刺的开始,我们添加了一个关于 chalk-engine 本身的完整章节。这是 Chalk 的核心 crate,用于求解给定的一组 Goal。虽然总有更多内容可以记录,但我们希望这至少可以帮助人们(可能是新手)理解 Chalk 的内部工作原理。

支持 impl Trait 的基本工作

在 Rust 中,当前和将来,在某些地方可以指定 impl Trait 而不是特定的结构体。例如,函数的签名可能是 fn foo() -> impl Debug。将来可以使用 impl Trait 语法的另一个地方是使用 type Foo = impl Trait(目前在 type_alias_impl_trait 功能下)。这将允许您像使用具体类型一样使用 Foo。在本次冲刺期间,我们在允许这两者与 Chalk 一起工作方面取得了重大进展。我们将在即将到来的冲刺中进行后续工作,并希望实现支持。

为共享类型库创建提案

目前,rustc、rust-analyzer 和 chalk 各自使用不同的结构体集来表示 Rust 类型。这意味着当 rustc 或 rust-analyzer 希望调用 chalk 函数时,我们必须来回转换 Rust 类型的表示形式。目前这样还可以,但最终我们希望每个人都使用相同的表示形式,这样就不需要进行相互转换。但这有点棘手,因为 rustc(批量编译器)和 rust-analyzer (IDE) 的要求略有不同。在本次冲刺期间,我们编写了共享类型库的提案,并就该主题举行了设计会议。您可以在此处找到 该会议的记录,其中还包括该提案。

在即将到来的冲刺期间,我们将通过开始在 rustc 中进行一些初步的重构来跟进这项设计。

重构以传递 Interner

共享类型库的要求之一是它需要支持类型的 intern 和 arena 分配。Intern 类型意味着每次拥有等效类型时都重复使用相同的内存,而不是分配多个副本。Arena 分配是一种内存管理策略,在该策略中,您在不断增长的池中分配所有内存,然后一次释放整个池,而不是跟踪和释放单个分配。

Chalk 现有的类型库在实现时考虑到了简单性,但是它不能支持这两种用例。问题在于,为了支持 intern 和 arena 分配,您需要跟踪包含哈希映射、arena 和其他支持数据结构的 interner 变量,而 chalk 的 API 没有为此提供任何空间。在本次冲刺中,我们解决了这个问题,因此我们现在可以在整个 chalk 中传递 interner 值,这意味着我们可以更轻松地桥接到 rustc 和 rust-analyzer。

重构 chalk 如何表示绑定类型和生命周期

chalk 表示带有绑定变量的类型(例如,for<'a> fn(&'a u32) 中的 'a)的一些细节与 rustc 处理此类类型的方式不同。这使得从 rustc 桥接到 chalk 更加困难。我们发现我们最终想要的设计是 rustc 和 chalk 的混合体。在本次冲刺期间,我们完成了大部分 chalk 重构,在即将到来的冲刺中,我们将处理 rustc 方面的工作。

添加 tracing 对 Chalk 的支持的工作

tracing crate 提供了一个框架来收集基于事件的诊断信息。目前,在 Chalk 中,我们只有基本的日志记录支持。通过添加 tracing 支持,我们希望能够更精细地控制 Chalk 诊断。初始支持已接近完成,希望很快就能合并。

探索性 rustc 集成 MVP

如前所述,之前实验性的 Chalk 集成已从 rustc 中移除,因为它已过时。由于 Chalk 和 rustc 当前的 trait 求解器之间存在相当多的设计差异,其中一些很细微,因此并不总是清楚需要修改哪些具体内容才能使一切正常工作。我们已经开始编写实验性的 Chalk 集成。至少在开始阶段,目标是创建一个最小的实现,作为未来工作的基础。虽然该 pull request 还没有完全完成,但已经接近了,并且在揭示 Chalk 中阻碍进展的问题方面非常有帮助。

探索性递归求解器

Chalk 设计的一个有趣方面是,它将求解器策略与 trait 系统实现的其他部分分离开来。除了我们现有的求解器,即所谓的“按需 slg 求解器”之外,我们还在探索“递归求解器”设计。我们首先复活了已删除的该代码的旧版本,并一直在探索如何将其适应更新的想法。

Chalk 的小型清理

在过去的冲刺中,对 Chalk 进行了一些较小的清理工作,值得一提。它可以再次构建 rustc,通过 rustc 的 lint 检查。我们删除了一项不必要的依赖项(好吧,它在技术上是用于测试的)。最后,我们还使 Chalk 更具 panic 安全性。

2020 年第 2 次冲刺

我们计划在 3 月 31 日下周二开始 2020 年的下一次冲刺。我们将简要介绍几个目标

如何参与

如果您想参与其中,请在 rust-lang Zulip#wg-traits 流中留言。我们还有一个每周设计会议(在 Zulip 上举行),我们用它来同步进度并讨论棘手的问题。

Chalk rustc 集成 MVP

这会有点困难,但我们希望在这个冲刺中完成一个 Chalk-rustc 集成的“MVP”,我们可以用它来推动进一步的开发。这个 MVP 将是不健全和不完整的(例如,它可能无法正确执行借用检查器规则),但它将帮助我们发现极端情况并验证 Chalk 求解器的设计。为此,我们有许多具体任务

  • 扩展 Chalk 以支持内置 trait,如 SizedCopyClone
    • 有几个 trait 的精确规则没有表示为普通的 impl,而是需要库本身的特殊集成。Chalk 目前不支持这些 trait,因此我们需要对其进行扩展。
  • 合并现有分支
  • 将 rustc 类型转换为 Chalk 类型
    • 最终,我们希望 rustc 和 Chalk 共享同一个类型库,以便它们之间不需要桥接。但是创建这样的库需要一段时间。因此,在过渡期间,我们将编写代码,按需将 rustc 类型转换为 Chalk 类型。(与此同时,其他一些冲刺目标将是调整 rustc 类型,以便我们也朝着最终目标迈进。)

const 集成设计会议

如上一节所述,我们最初的 Chalk rustc 集成 MVP 不会支持 const。在此次冲刺期间,我们计划安排一次设计会议,专门详细讨论 const 的外观设计。实际的实现将留到以后的冲刺进行。

朝着对齐 rustc 和 Chalk 类型的方向发展

在此次冲刺期间,我们计划开始为 Rust 类型提取共享库,如之前提到的设计会议中所讨论的。这将涉及重构 rustc 的工作以及对 Chalk 的更改。(跟踪问题。

实现对 impl Trait 的基本支持

我们预计将在下一次冲刺的早期实现对 impl Trait 的基本支持。但是,有一些后续工作需要完成,以进一步完善实现。

探索性实现和研究

除了更具体的目标外,还在进行一些探索性工作

Chalk 性能工作

Chalk 的大部分工作都集中在设计上,并没有太多工作来优化性能。虽然这里的特定“最终目标”尚不清楚,但我们希望首先为 Chalk 创建一组内存、cpu 和时间基准。有了这个框架,我们可以诊断特定的性能问题并监控未来更改中的回归。其中一部分是将合并 tracing 支持。

改进技能树

技能树一直是帮助我们组织工作和跟踪状态和整体计划的有用工具。但是,当前输出并不完全是不言自明的,也不是特别有吸引力。最终目标是生成类似于 Lin 的手绘艺术品的图片。还有一些缺失的功能。如果有兴趣尝试提高输出质量或添加功能的人,那就太好了!skill-tree 位于其自己的github 存储库中,但只需访问 Zulip 上的 #wg-traits 流即可讨论它。