Rust Glancer
摘要
Rust Glancer 是一个新的 Rust LSP 服务器,它使用的 RAM 显著少于 rust-analyzer 等替代品,这在一篇评估其特性和潜力的博客文章中讨论过。
<header>
<h1>Rust Glancer</h1>
<time class="meta" datetime="2026-08-21">2026年8月21日</time>
</header>
<p><a href="https://rust-glancer.github.io/blog/hello-world/">Rust Glancer</a>,一个功能性的 Rust LSP 服务器,使用的 RAM 少两个数量级,非常酷。去看看吧!这篇文章最初是 lobste.rs 上的一条评论,但我认为最好更突出地发布它。但不要期待精炼的写作!</p>
<p>一些想法:</p>
<figure class="blockquote">
<blockquote><p>rust-analyzer 使用 rowan 进行语法树表示</p>
</blockquote>
</figure>
<p>是的,rowan 很糟糕 :P 我真的在考虑</p>
<ul>
<li>
增量解析,
</li>
<li>
增量、DOM 变更风格的重构,
</li>
</ul>
<p>Rowan 在这方面做得很好。但那只是 1% 的用例。99% 的用例是你那 6666 个依赖中的所有代码,你永远不会去看,但需要至少浅浅地分析一下。即使对于主要目标是重构的增量工具,主要的 AST 结构应该只是一个数组列表。可能在某个时候会有一篇真正的文章关于这个,见
<a href="https://youtu.be/G93oYL1ry70" class="url">https://youtu.be/G93oYL1ry70</a> 作为预告。</p>
<figure class="blockquote">
<blockquote><p>Rust 工作区确实有很多必须索引的信息:成千上万的函数、结构体、特质、它们之间的关系、函数体及其中的语句等。每一个都需要分析和记忆,如果你想拥有“查找此结构体的所有引用”之类的东西,你真的无法作弊。</p>
</blockquote>
</figure>
<p>如果我理解正确,Rust Glancer 想要处理每个函数体。我认为<em>那</em>部分或许可以做到延迟(但不是增量!)且开销很小?索引所有项,但对于函数,只处理当前打开的文件?这可能结合两个世界的优点。</p>
<p>与 Rust Rover 比较内存使用会很有趣。除了 IDE GUI 本身,我预计 RR 会更紧凑。</p>
<figure class="blockquote">
<blockquote><p>有些功能可能不太会被支持,例如构建脚本 / 通过过程宏调用支持过程宏</p>
</blockquote>
</figure>
<p>我可能在合理化/记错事情,但据我回忆,正是在添加过程宏时,这个东西开始变得异常庞大。展开过程宏很慢,因为我们运行的是真实代码,我们无法真正使用正常的 IDE 技巧。而且过程宏生成大量代码。有一次我测量过,大约 30% 的 rust-analyzer 二进制大小归因于 JSON 解析代码。如果没人看到代码,它不会伤害任何人,对吧?</p>
<p>这里一个潜在的方法是采用 Sorbet 的技巧,根本不运行元编程,而是有一个插件接口来“解释”它本应产生的<em>效果</em>。我们不运行 serde,而是添加一个空体的 <code class="display">imp Serialize for T {}</code> 的 shim。</p>
<figure class="blockquote">
<blockquote><p>我不确定为什么,但在 rust-analyzer 中我观察到当代理编辑代码时,内联提示可能会错位</p>
</blockquote>
</figure>
<p>Rust analyzer 的核心数据模型非常执着于始终观察代码的一致快照,并尽最大努力确保语言客户端和服务器具有共享的、严格可序列化的世界视图。遗憾的是,<a href="https://github.com/Microsoft/language-server-protocol/issues/584">LSP 不允许这是<em>正确的</em>,只允许启发式正确</a>,不像旧的 Dart Analyzer 协议,它具有可靠的数据同步。</p>
<p>然而,我们的文件监视实现是草率的!首先,有两种后端:我们可以要求编辑器为我们监视,或者我们可以使用服务器端监视。尝试更改<a href="https://rust-analyzer.github.io/book/configuration.html#files.watcher">此选项</a>看看是否有帮助?但是,是的,我记得我们的原生监视器 API 基本上是竞争条件,我没有做那些混乱的平台特定工作来使其正确。</p>
<hr>
<p>但我主要想写的,以及为什么我从舒适的 lobste.rs 文本区域移动到 Emacs 缓冲区的奢华舒适中,是因为现在 rust-analyzer 有点像那个画了一半的马的模因,只不过它只是马的头半部分。</p>
<p>IntelliJ 的一个大想法是它的 PSI API(本质上是带有已解析类型的 AST)实际上是一个接口,并且有多个提供者。在典型用法中,至少有三个后端在起作用:</p>
<ul>
<li>
对于在编辑器中打开的、用户积极修改的文件,PSI 由具体语法树支持。
</li>
<li>
对于项目其余文件,PSI 由所谓的 Stub 树支持,这是一种紧凑的磁盘上表示,只存储文件的“外部可见”部分(所以没有函数体)。如果用户导航到新文件,其 PSI 会透明地从存根切换到语法树。
</li>
<li>
对于依赖项,PSI 通常由编译的 .class 文件支持,由 javac 生成。如果你导航到那里,IDE 会为你反编译东西!超级酷!
</li>
</ul>
<p><em>这</em>就是我认为此类事情应该工作的方式。rust analyzer<em>不应该</em>使用 salsa 来处理你仍然没有查看的所有 6666 个依赖项。它应该只使用 rustc 的 .rmeta 文件,只有当用户开始弄乱他们的 <code class="display">~/.cargo/registry/src</code> 文件夹时,才透明地切换到 salsa。</p>
<p>对此的前提是定义访问 Rust 代码的抽象 API。这总是计划,并且我们在某个时候确实开始做了:</p>
<p><a href="https://hackmd.io/ytd82QNiT_Ku2XFr1EAtiQ" class="url">https://hackmd.io/ytd82QNiT_Ku2XFr1EAtiQ</a></p>
<figure class="blockquote">
<blockquote><p>rmeta-transparent – 源代码可能对某些 crate 不可用,API 应该支持预编译的 rmeta 文件作为输入。</p>
</blockquote>
</figure>
<p>但我不认为那项工作曾经完成过。</p>
<p>这在我看来仍然是这里最容易摘的西瓜——将世界分为拱形的增量冰山尖端,和大部分只读的、磁盘上的、紧凑的、黑暗的、潮湿的供应链攻击温床。</p>
<p>这样的概览分析器架构会很棒,我认为!</p>
查看缓存全文
缓存时间: 2026/08/22 03:36
# Rust Glancer
来源:https://matklad.github.io/2026/08/21/rust-glancer.html
2026年8月21日 Rust Glancer (https://rust-glancer.github.io/blog/hello-world/) 是一个为Rust设计的函数式LSP服务器,其内存占用量比现有方案低两个数量级,令人印象深刻。快去看看吧!这篇文章最初是发在 lobste.rs 的评论区,但我觉得还是应该以更正式的方式发表出来。不过别指望文笔有多精致!
一些想法:
> rust-analyzer 使用 rowan 来表示语法树
确实,rowan 可以说一无是处 :P 我当初主要考虑的是:
- 增量解析,
- 类似DOM修改的增量重构。
Rowan 在这些场景下表现尚可。但这类用例只占1%。而99%的使用场景涉及你那6666个依赖项中的所有代码——你永远也不会去查看它们,但至少需要进行浅层的静态分析。即使对于以重构为主要目标的增量工具,其核心的AST结构也应该只是数组的列表。或许将来我会专门写篇文章来探讨这个话题,参考这个预告视频https://youtu.be/G93oYL1ry70。
> Rust工作空间确实包含大量需要索引的信息:成千上万的函数、结构体、特征(trait),以及它们之间的关系、函数体及其内部语句等。这些都需要分析和记忆,如果你想要实现诸如"查找该结构体的所有引用"之类的功能,很难取巧。
如果我的理解正确,Rust Glancer 试图处理每个函数体。我认为*这部分*或许可以设计为惰性处理(但不能增量!),而且开销不大?即索引所有条目,但对于函数,仅分析当前打开的文件?这或许能兼顾两方面的优势。
与Rust Rover对比内存使用情况会很有意思。除去IDE图形界面本身的开销,我预计Rust Rover会更紧凑。
> 某些特性可能难以支持,例如通过过程宏调用实现的构建脚本/过程宏支持。
可能我在合理化或记忆有误,但我记得正是在处理过程宏的时候,系统开始变得异常臃肿。展开过程宏非常耗时,因为我们是在执行真正的代码,无法采用常规IDE的取巧手段。而且过程宏会生成大量代码。有一次我测量过,rust-analyzer二进制文件中约30%的大小都归因于JSON解析代码。既然没人会去看这些生成的代码,那应该没问题吧?
这里的一个潜在方案是借鉴Sorbet的做法:完全不运行元编程,而是提供一个插件接口来"解释"*如果运行*会产生什么效果。例如不实际运行serde,而是添加一个空的`impl Serialize for T {}`存根。
> 不知为何,在rust-analyzer中我观察到当智能体编辑代码时,内联提示可能会错位
Rust analyzer的核心数据模型*极其*严格地保持代码视图的一致性快照,并尽最大努力确保语言客户端和服务器拥有共享且严格串行化的世界视图。可惜的是LSP(语言服务器协议)并不能保证这种正确性,只能依赖启发式近似(https://github.com/Microsoft/language-server-protocol/issues/584),不像更早的Dart Analyzer协议那样具备可靠的数据同步机制。
不过我们的文件监听实现确实有问题!首先有两种后端:可以请求编辑器帮我们监听,也可以使用服务端监听。试试修改这个选项(https://rust-analyzer.github.io/book/configuration.html#files.watcher)看看是否改善?但据我回忆,我们原生监听器的API存在根本性的竞态条件问题,而我没有完成那些繁琐的平台特定修正工作。
---
但我主要想写的,也是为什么我从舒适的lobste.rs文本框转移到Emacs缓冲区这个奢华环境的原因在于:现在的rust-analyzer有点像那个半成品的马梗图,只不过这里只有马的头部部分。
IntelliJ的一个核心理念是:其PSI API(本质上是带有已解析类型的AST)实际上是个接口,存在多种实现方式。在典型使用场景中,至少涉及三种后端:
- 对于编辑器中打开且用户正在积极修改的文件,PSI由具体语法树提供支持。
- 对于项目中的其他文件,PSI由所谓的"Stub Tree"提供支持——这是一种紧凑的磁盘存储表示,仅保存文件的"对外可见"部分(即不含函数体)。当用户导航到新文件时,其PSI会从stub透明地切换到语法树。
- 对于依赖项,PSI通常由javac编译产生的.class文件提供支持。当你导航到那里时,IDE会自动为你反编译内容!非常酷!
*这*才是我认为此类系统应有的工作方式。rust analyzer*不应该*用salsa来处理你从未查看过的那6666个依赖项。它应该直接使用rustc的.rmeta文件,只有在用户开始操作`~/.cargo/registry/src`目录时,才透明地切换到salsa模式。
实现这一点的前提是定义访问Rust代码的抽象API。这始终是我们的计划,而且我们确实曾着手开始:
https://hackmd.io/ytd82QNiT_Ku2XFr1EAtiQ
> rmeta-transparent – 某些crate可能没有源代码,API应支持预编译的rmeta文件作为输入。
但我不确定这项工作是否最终完成。
在我看来,这仍然是目前最容易实现的突破口——将世界划分为两类:尖端的增量处理冰山一角,以及大部分只读、存在于磁盘上、紧凑、隐蔽且湿润的供应链攻击温床。
我认为这种"一览式分析器"架构将是非常优秀的方案!
相似文章
rust-glancer:一个专注于低内存使用的 Rust 替代 LSP
介绍 rust-glancer,一个专注于低内存使用的 Rust 替代语言服务器协议实现,特色是重启后立即索引以及在老硬件上更好的性能。
Gossamer:一种具有真实goroutines和无暂停内存的Rust风格语言
Gossamer是一种受Rust启发的新编程语言,具有真实goroutines、基于引用计数和区域的无暂停确定性内存管理,以及配备LLVM编译的字节码虚拟机。它旨在提供富有表现力的语法,无需借用检查器或垃圾回收暂停。
@mylifcc: LiteLLM 正式迁移到 Rust 了! AI Gateway 迎来史诗级性能升级: 单请求开销降低 150 倍(~0.05ms vs Python 7.5ms) 吞吐量提升 15 倍 内存占用降低 11 倍(峰值仅 32MB) 单个 …
LiteLLM已从Python迁移到Rust,性能大幅提升:请求开销降低150倍至0.05ms,吞吐量提升15倍,内存占用降低11倍至32MB。
@tom_doerr: 基于 Rust 的模块化 GraphRAG 实现,支持 WebGPU 加速。https://github.com/automataIA/graphrag-rs…
一种模块化、高性能的 GraphRAG(基于图的检索增强生成)Rust 实现,支持 WebGPU 加速,并提供三种部署架构:仅服务器、仅 WASM(客户端)以及混合模式。
我做了一个感觉像GPT-Live的东西,但你可以在Rust中自己运行
一个基于Rust的工具,复制了GPT-Live的体验,用户可以在本地运行。