首页
/ Rust 编译器项目贡献指南:从 CONTRIBUTING.md 到子树同步与 LLM 使用规范的完整实践

Rust 编译器项目贡献指南:从 CONTRIBUTING.md 到子树同步与 LLM 使用规范的完整实践

2026-09-05 11:51:28作者:仰钰奇

本文为 Rust(rust-lang/rust)项目的贡献者指南技术解析。它以仓库根目录的 CONTRIBUTING.md 为主体骨架,完整覆盖项目规定的三条贡献入口、subtree/submodule 的改动归属规则、LLM 使用政策与求助/报 bug 流程,并结合仓库中真实存在的 josh-sync.toml 子树配置、rustc-dev-guide 源码、triagebot.toml 评审组配置等实现细节进行纵深扩充。读完后,你将能准确判断任何一次改动应该提交到哪个仓库、如何使用 r?/@rustbot 等机器人命令推进评审,以及 LLM 辅助贡献的边界在哪里。

一、贡献体系的三大入口

CONTRIBUTING.md 开篇即给出三条核心指引,它们对应 Rust 生态中贡献不同类型的目标仓库:

  1. 求助入口:最佳起步方式是在官方 Zulip 的 #new members 频道提问。文档明确区分了"自学文档"与"提问"两个场景——文档教你自查,Zulip 才是"ask for help"的正确场所。
  2. 编译器/工具链贡献:对应 rustc-dev-guide(Rust 编译器开发指南)。在本仓库中,该指南的完整源码就内嵌于 src/doc/rustc-dev-guide 目录,其贡献流程章节即 contributing.md
  3. 标准库贡献:对应 std-dev-guide(标准库开发者指南),其源码位于 library/ 目录下各 crate(如 library/stdlibrary/corelibrary/alloc)。

CONTRIBUTING.md 对 rustc-dev-guide 的定位是:"帮助你理解 rustc——Rust 编译器——如何工作,以及帮助新贡献者参与到 rustc 开发中",并建议在贡献前先通读该指南。指南涵盖生态中的各类机器人(bots)、开发工具、bootstrapping(自举构建)、编译器架构、源码表示(source code representation)等内容。从仓库结构看,这些内容对应 src/doc/rustc-dev-guide/src/SUMMARY.md 中列出的各章节,而自举系统本身的实现就在 src/bootstrap 目录(包含 bootstrap.pyconfigure.py 等入口)。

二、Subtree 与 Submodule:改动应该提交到哪里

这是 CONTRIBUTING.md 中最容易踩坑、也最具实操价值的章节。Rust 主仓库大量代码并非"原生",而是从独立仓库同步过来的,贡献时若提交错仓库,PR 会被直接拒绝或无法合入。

规则原文

文档给出两条硬性规则:

  • Submodule(子模块):改动必须针对子模块对应的独立仓库,而不是主 rust-lang/rust 仓库。
  • Subtree(子树):如果改动不需要落回主仓库(例如:一次不伴随编译器变更的 rustc-dev-guide 修改),优先向子树自身的仓库发 PR

从源码印证:如何用 josh-sync.toml 识别子树

仓库中每棵子树的根目录都放置了一个 josh-sync.toml 文件,声明了"本目录 ↔ 独立仓库"的同步映射。全仓库共存在 5 处,这构成了判断"此处是否子树"的权威依据:

子树路径 同步配置 上游独立仓库
library/compiler-builtins/josh-sync.toml org = "rust-lang"repo = "compiler-builtins"path = "library/compiler-builtins" rust-lang/compiler-builtins
library/stdarch/josh-sync.toml 同类声明 rust-lang/stdarch
src/doc/rustc-dev-guide/josh-sync.toml org = "rust-lang"repo = "rustc-dev-guide"path = "src/doc/rustc-dev-guide" rust-lang/rustc-dev-guide
src/tools/miri/josh-sync.toml 使用 josh filter 语法:filter = ":rev(<commit>:prefix=src/tools/miri):/src/tools/miri" rust-lang/miri
src/tools/rust-analyzer/josh-sync.toml 同类声明 rust-analyzer 独立仓库

从配置文件结构看,存在两种同步风格:compiler-builtins 等使用简单的 org/repo/path 三元组整体映射;而 miri 使用 josh 的 filter 表达式,指定了锚定到特定 rev 的路径前缀映射prefix=src/tools/miri),说明子树同步可以精细到"只取独立仓库中某一目录"的粒度。这也解释了为何 miri、rust-analyzer 这类体量庞大的工具能以子树形式内嵌在主仓库中参与同一 CI,同时保留独立 issue tracker 和独立 PR 流。

实操结论:当你要修改 miri 的行为时,优先在 miri 的独立仓库发 PR,改动经 josh 同步后回流到本仓库的 src/tools/miri;只有当改动必须与编译器本体改动原子性地同时出现时,才需要在主仓库一并提交。CONTRIBUTING.md 中 rustc-dev-guide 的例子("不伴随编译器变更的指南修改")正是该规则的典型场景。

三、LLM 政策:机器辅助贡献的边界与最佳实践

CONTRIBUTING.md 设有独立的 "LLM policy" 章节,说明 rust-lang/rust 对"贡献中如何使用大语言模型"有成文政策,政策全文托管在官方 Forge 站点(LLM usage policy)。需要区分两个文档层级:

  • 政策(canonical):以 Forge 上的 LLM usage policy 为准,规定 LLM 允许/禁止的使用方式;
  • 实践指南:仓库内 llm-guidance.md 明确自述"本节是 LLM 协作指南及 moderation 政策的摘要,不是政策本身;两者冲突时以 Forge 为准"。

该指南进一步按角色拆分为两篇子文档(均位于 src/doc/rustc-dev-guide/src/llm-guidance/ 目录):

  • writing.md:面向用 LLM 写代码的贡献者;
  • reviewing.md:面向审查 LLM 生成的代码用 LLM 辅助审查的评审者。

这一"政策 + 分角色指南"的三层结构值得其他大型开源项目借鉴:政策解决合规问题,指南解决效率问题,且按"写代码的人"和"审代码的人"分流,避免单一文档两头不讨好。

四、求助与 Bug 报告

4.1 获取帮助

CONTRIBUTING.md 指明 Rust 有两个求助平台:internals 论坛与官方 Zulip(rust-zulip),并推荐优先使用 Zulip。文档强调这两个平台不仅是提问场所,也是"找到 mentor"的渠道;具体的提问方法论被指向 rustc-dev-guide 的 "Asking Questions" 章节(即 getting-started 章节 中的相应小节)。结合第一节的 #new members 频道建议,新贡献者的求助路径实际上是分层的:新人频道 → 主题频道(如 #t-compiler)→ 论坛。

4.2 Bug 报告与 ICE

CONTRIBUTING.md 特别提到编译器场景下最常见的求助来源:"编译器错误信息让你来这里了吗?"——即 ICE(Internal Compiler Error,编译器内部错误)。报告 ICE 时需参照 dev-guide 的 "Bug reports" 章节并通过仓库的 issue 模板提交。

dev-guide 的 contributing.md 给出了完整的 bug 报告纪律,值得逐条继承:

  1. nightly 用户先确认:如果你在使用 nightly 频道,先在最新工具链上验证 bug 是否仍然存在——它可能已经修好了;
  2. 先搜已有 issue:搜索现有 issue 是"额外分",不保证有效,且重复报告不会被责怪;
  3. 标题要有区分度:包含触发条件、所用语言特性或错误信息片段,例如文档给出的范式:"impossible case reached on lifetime inference for impl Trait in return position";
  4. 安全类问题走单独渠道:若公开报告本身构成安全风险,应走官方安全漏洞报告流程而非公开 issue。

五、PR 全流程:r?、CI、@bors r+ 与机器人协作

虽然根目录 CONTRIBUTING.md 将 PR 细节指向 dev-guide,但该流程是本仓库贡献的"主干操作",此处结合 src/doc/rustc-dev-guide/src/contributing.md 完整梳理。

5.1 提前提议(MCP)与性能验证

  • Major Change Proposal(MCP):大型改动(重大重构、重要类型变更、编译器行为的重要变化)需走 MCP 流程,它是比 RFC 更轻量的反馈机制。文档的忠告很直白:"拿不准就去 Zulip 问,把大量心血投入一个最终合不进的 PR 是巨大的浪费"。
  • perf run:怀疑改动影响性能时(无论正负),可请求一次 "perf run"——机器人会用包含你改动的编译器编译一组 benchmark 并生成对比报告。

5.2 指定评审人:r? 与 adhoc_groups

在 PR 描述或评论中写 r? @username 可指定评审人,否则 @rustbot 会按你改动的文件自动随机分配。更精细的用法是指定团队组:

r? rust-lang/diagnostics

可用的组名清单即 triagebot.toml[assign.adhoc_groups] 段定义的名单。查看该配置文件可印证其规模:adhoc_groups 下逐组列出了各团队的具体维护者成员(例如 compiler_leadslibs 等组各含多名成员),r? rust-lang/<group> 就是从中随机指派一位。对跨团队改动(如同时触碰编译器与标准库),文档强烈建议先与 compiler team 在 Zulip 讨论,把大型 PR 拆分为一系列可独立评审的小 PR

5.3 评审状态机:S-waiting-on-review / S-waiting-on-author

评审人多为志愿者,因此仓库用标签维护 PR 的"球在谁手上":

  • 遇到 merge conflict 或评审人要求修改时,PR 被标记 S-waiting-on-author
  • 修改完成后运行:
@rustbot ready

将其改回 S-waiting-on-review。作者与评审人都有义务在阶段切换时调用对应命令(@rustbot author / @rustbot review)保持标签准确。若两周无人评审,可找 Triage WG(Zulip 的 #t-release/triage)协助——该 WG 会定期巡检所有等待评审超过两周的 PR。

5.4 CI、tidy 与合并队列

  • CI 的基准是 main 而非你的基点:CI 将你的补丁直接打在当前 main 上测试,因此分支过旧时即使没有显式 merge conflict 也可能意外失败。只在必要时更新分支(有冲突、上游 CI 损坏阻塞了你的绿色 PR、或维护者要求),更新后用 git push --force-with-lease 并留简短说明。
  • 提交前跑 tidy
./x test tidy --bless

CI 同样会运行 tidy,不通过则失败。文档还建议配置 git hooks 在每次 push 前自动执行。

  • 无 merge-commit 政策:遇到冲突必须 rebase 而非 merge;PR 中出现 merge commit 会被打上 has-merge-commits 标签,清除后需手动 @rustbot label -has-merge-commits
  • 合并只有机器人路径:评审通过后评审人留下:
@bors r+

PR 进入 merge queue,由 @bors 在所有支持平台上跑全量测试后合入 main——"PR 永远不会被手工合并"。小改动可见到 @bors r+ rollup 变体,表示该改动应与其他 PR 打包(roll up)测试合并以提速。

  • 关 issue 的时机讲究:一般把 closes #123 放在 PR 描述而非 commit message(rebase 会"刷屏"该 issue);但若是被接受回移植到 beta/stable 的回归修复(带 beta-accepted/stable-accepted 标签),不要使用自动关闭关键词,应写如 Fixes (after beta backport) #NNN.,等 [beta]/[stable] 回移植 PR 合入后再手动关 issue。

六、不同贡献类型对应的工作区域速查

结合本仓库目录结构,可将贡献类型映射到具体代码区域(路径均以仓库根目录为起点):

贡献类型 主要工作区域 说明
编译器 pass/类型推断/借用检查 compiler/ 下对应 crate rustc_borrowckrustc_hir_typeckrustc_infer 等,改动前应先读 rustc-dev-guide 对应架构章节
MIR 优化 compiler/rustc_mir_transform 附带 tests/mir-opt/ 下的 .mir/.diff 期望文件
标准库 library/ stdcoreallocstdarch 为子树,优先走上游仓库
编译器内嵌汇编/代码生成测试 tests/assembly-llvmtests/codegen-llvm FileCheck 风格的汇编断言测试
UI 诊断测试 tests/ui .rs 源码 + .stderr 期望输出成对出现
Miri / rust-analyzer src/tools/mirisrc/tools/rust-analyzer 子树,PR 优先发往各自独立仓库
文档(指南类) src/doc/ rustc-dev-guide 子树优先发往独立仓库;doc.rust-lang.org 的源文件在此目录下
CI/构建系统 src/cisrc/bootstrap 容器定义、脚本与自举逻辑

七、提交前自检清单

  1. 改动落在子树/子模块内吗?若是,优先向对应独立仓库发 PR(对照第二节的 josh-sync.toml 清单);
  2. 是否已通读 rustc-dev-guide 中与该改动相关的章节?大型改动是否已走 MCP 或与 compiler team 预先沟通?
  3. ./x test tidy --bless 是否通过?分支是否基于最新 main(rebase 而非 merge)?
  4. 指定评审人的 r? @userr? rust-lang/<group> 是否已写入,组名是否核对过 triagebot.tomladhoc_groups
  5. 若使用了 LLM 辅助,是否已按 Forge LLM 政策声明,并对照 llm-guidance/writing.md 完成自查?
  6. issue 引用是否按"正常改动用 closes #N、回移植改动改用 Fixes (after beta backport) #N"的规则书写?

总结

CONTRIBUTING.md 虽然篇幅不长,但它是整个贡献体系的路由文件:把"向谁问"(Zulip / rustc-dev-guide / std-dev-guide)、"往哪提"(主仓库 vs 子树独立仓库)、"用什么工具"(LLM 政策)、"怎么报 bug"(ICE 流程)四个问题各归其位。而仓库本身提供的 josh-sync.toml 子树清单、triagebot.toml 评审组配置、dev-guide 源码与 llm-guidance 双角色指南,则把这份路由落实为可验证、可执行的工程事实——贡献者在动手写第一行代码之前,就能据此判断自己的 PR 该长什么样、提交到哪里、以及如何让机器人与评审人以最低摩擦推进到 @bors r+

登录后查看全文
热门项目推荐
相关项目推荐