会议由 nikomatsakis 主持。会议记录由 nikomatsakis 编写。与会者:nikomatsakis, pnkfelix, Xanewok, matklad 笔记
Rust IDE
在上一次编译器/IDE 团队会议中,我们讨论了 Rust 中 IDE 支持的总体方向。
目前,作为 Rust 项目一部分开发的两个 IDE 是 Rust 语言服务器(RLS)和 rust-analyzer。前者目前随 Rust 发行版一起发布,而后者则作为“RLS 2.0”工作组的基础。
不幸的是,这两个项目是在没有太多代码共享的情况下独立开发的。我们希望改变这种情况,并找出如何统一这些努力。因此,我们进行了一系列会谈,旨在详细阐述设计空间,并为如何改进未来的情况制定提案。
这篇博客文章简要概述了我们最近的会议。
为什么要有 2 个 IDE?
rust-analyzer 的主要优点是更高的性能(因为完全懒加载的编译模型)和更丰富的功能集(由于更灵活的分析 API)。RLS 的主要优点是精度(它在底层使用 rustc
)。此外,RLS 是保存分析基础设施的主要消费者,这非常适合需要代码库静态视图的工具,例如 cargo-src 或 lsif。
保存分析
什么是“保存分析”?它是一种不稳定的格式,rustc
用它来记录有关编译代码的信息。它包含相当高级的信息。例如,对于源代码 crate 中的每个标识符,保存分析器会将此标识符映射到定义和用法列表。env RUSTFLAGS="-Zunstable-options -Zsave-analysis" cargo check
可用于指示 rustc
生成保存分析文件(JSON 格式)。由于保存分析是直接从 rustc 内部数据结构生成的,因此保证是正确的(除了 rustc 本身中的错误)。
查询模型
保存分析的根本问题在于,它是针对整个 crate 一次性计算的。这对于非平凡的 crate 来说非常慢,而且也很浪费。在任何给定时刻,实际上只需要一小部分分析信息。rust-analyzer 通过使用 salsa
查询进行代码分析来解决这个问题。结果是一个完全懒加载的整个 crate 图的编译模型。该模型类似于 rustc
内部使用的模型,但在“垂直”和“水平”方向上都更加懒加载。在垂直方向上,rustc
仅在解析和宏扩展之后才开始增量编译;rust-analyzer 在每个文件的基础上进行增量编译。在水平方向上,rustc
一次编译一个 crate;rust-analyzer 将查询用于整个 crate 图。
前进方向
我们目前的假设是,有可能整合这两种方法,而不会使工程工作量翻倍。具体来说,我们将向 rust-analyzer 添加一个选项,以使用保存分析来实现查找用法和重命名功能。这样,我们将获得最重要查询的精确结果,而不会减慢补全速度。但是,与 RLS 不同,rust-analyzer 将不会链接到 rustc,而是依赖 cargo 来运行编译器并生成保存分析数据。如果这种方法有效,我们将考虑冻结 RLS 并完全专注于 rust-analyzer。从长远来看,计划是统一保存分析回退路径和懒加载分析。
在并行进行 RLS/rust-analyzer 统一工作的同时,我们继续推进 rustc 库化,重点关注特征求解(通过 chalk)和类型推断。“库化”是我们一直用来指代将代码从 rustc 中提取到可重用库中的过程,这些库可以由 rustc 和 rust-analyzer 共享。目标是通过库化逐步减少 rustc 和 rust-analyzer 之间重复的代码量,最终目标是拥有一个单一的代码库,或者拥有绝大多数共享的逻辑。