又来了?感觉我们才刚做完一次……6 周前 😉。无论如何,这次冲刺的大部分内容是前两次的延续:努力使 Chalk 功能完整,并最终在 rustc 中使用它进行 trait 求解。
如果有人以前没看过此类总结,如果你对 trait 工作组感到好奇,可以在这里找到摘要。
功劳归属
一如既往,非常感谢所有参与本次冲刺的人员
- Wilco Kusee
- Florian Diebold
- Jack Huey
- Charles Lew
- Niko Matsakis
- Nathan Whitaker
- Adam Bratschi-Kaye
- super-tuple
- David Ross
- Zahari Dichev
- Mikhail Babenko
- Mark Drobnak
- Aaron Hill
- Pavan Kumar Sunkara
- Nathan Corbyn
- Matthew Jasper
- Bastian Kauschke
Chalk crate 清理和每周发布
自成立以来,Chalk 在其 crate 的结构方面经历了很多更改,这对于任何规模合理的项目来说都是正常的。在本次冲刺中,我们花时间稍微清理了一下 crate 的结构。最好简单概述一下我们最终的结果。更全面的概述可以在Chalk 书籍中找到。
chalk-derive
- 定义派生 proc 宏chalk-ir
- 一个基本的“类型库”,将来可能会在 rustc、Chalk 和 rust-analyzer 之间共享chalk-solve
- 定义chalk-ir
中类型的 Rust 语义chalk-engine
- 实现 SLG 求解器chalk-recursive
- 实现递归求解器chalk-parse
- 用于测试,将类似 Rust 的语法解析为chalk-ir
和chalk-solve
类型chalk-integration
- 用于测试,提供用于测试的有用类型chalk
- 用于测试,提供 REPL
在此次冲刺期间,我们还设置了 Chalk crate 的定期每周发布。虽然目前这些都是 0.*.0
的补丁版本,但它为未来的稳定版本建立基础设施,并提供在 rustc 和 rust-analyzer 中使用的已发布的 crate。将来,当 Chalk 开发更加稳定时,我们希望将其切换为手动发布。我们还计划设置 bors 以确保 master
始终构建并通过测试。
努力在 rustc 中支持 GAT
Chalk 早就支持 GAT;在 Chalk 术语中,GAT 是其他一切的自然扩展。但是,rustc 中的 GAT 比较困难,并且在过去的几年中一直处于停滞状态,主要重点是使 Chalk 做好准备。但是,最近在 rustc 中进行了一些工作,以使 GAT 在当前的 rustc trait 系统下工作。
提取表示类型的共享库
作为一个长期目标,我们希望有一天能在 Chalk 和 rustc 之间共享一个类型库。此外,此类型库可以用于其他项目,例如 rust-analyzer。在 Chalk 方面,添加了更多类型(例如闭包和枚举)和更多 trait(例如 Fn
系列和 Unsize
)。此外,还完成了一些工作以反方向发展:使 rustc 更接近 Chalk,例如 实习 Predicate
,以及 引入 ForAll
谓词。
.chalk
文件进行调试
编写 作为 Chalk 测试的一部分,我们可以编写类似 Rust 的“程序”,这些程序被解析为 Chalk 类型。重要的是,这些程序比它们降低到的类型简洁得多。作为更好地进行调试工作的一部分,我们实现了一个反方向的系统:能够从底层类型生成类似 Rust 的程序。这对于例如调试 rustc 尝试编译的给定代码的错误非常有用。此外,它还可以用于生成具有性能问题的案例的程序。
impl Trait
支持
改进 在上次冲刺中,我们实现了初始的 impl Trait
支持,以处理类似 type Foo<T> = impl Bar
的简单情况。在此次冲刺中,我们开始添加对更复杂情况的更多支持,例如 type Foo<T>: Debug = impl Bar where T: Debug
。此外,还完成了一些设计工作来支持检查它们是否格式正确。
扩展 Chalk 以支持 Rust 语义
这个目标与“提取共享类型库”有点重叠,但它不是关于表示类型本身,而是更多关于表达这些类型的语义。例如,考虑以下程序
trait Foo: Sized {
fn foo(self) {}
}
impl Foo for u32 {}
impl Foo for String {}
fn main() {
let x = 0;
x.foo();
}
在当前冲刺之前,Chalk 无法正确处理此问题;它不知道你可以在 0
上调用 foo
。实际上,为了能够正确编译此程序,编译器必须知道 0
永远不可能是 String
。考虑一下如果你将 String
的 impl 更改为 u64
会发生什么:rustc 不知道你希望 0
是 u32
还是 u64
。这基本上是 Chalk 在本次冲刺之前看到此程序的方式。但是,Chalk 现在可以正确处理这种情况。
处理 rustc 集成中的生命周期约束
因此,作为 trait 求解的一部分,Chalk 和 rustc 有时可能会发现一个生命周期需要比另一个生命周期更长,或者一个类型必须比一个生命周期更长。例如,
trait Foo<'a, 'b, T> where 'a: 'b, T: 'a {}
Chalk 不会单独解决这些生命周期约束,而是将它们传递回 rustc。在此次冲刺中,我们添加了在 Chalk 中表达这些 where 子句的功能。
其他工作
在此次冲刺中完成了很多较小的工作,这些工作实际上不适合单独的目标。Chalk 在其建议中变得更聪明了。我们引入了用于日志记录的 tracing
。我们为递归求解器做了一些设计工作。当然,还有大量的内部重构和清理。当然,rustc 集成也跟上了最新版本的 Chalk 功能并进行了更新。
暑假
今年到目前为止很忙!自 2 月初开始第一次冲刺以来,我们取得了巨大的进步。但是,与过去的几次冲刺不同,我们不会立即开始下一次冲刺。相反,我们将休息几个月,并在 9 月重新开始。在那之前,我们不会在 Zulip 上举行每周会议,也不会有任何确定的目标。这部分是因为一些成员可能会休假。而且,代码倦怠非常真实,偶尔休息一下会有所帮助。与此同时,还剩下一些需要完成/清理的项目。
如果你有兴趣帮忙,请不要气馁!Zulip 应该仍然相当活跃,所以请随时光临!