首页
/ 解读 rustc 已停用错误码 E0211:类型不匹配的四种历史场景与修复(rustc_error_codes 归档文档)

解读 rustc 已停用错误码 E0211:类型不匹配的四种历史场景与修复(rustc_error_codes 归档文档)

2026-09-06 18:24:09作者:沈韬淼Beryl

本指南围绕当前仓库 compiler/rustc_error_codes/src/error_codes/E0211.md 展开。该文档是 rustc 官方错误码归档中的一份历史档案:错误码 E0211("类型不符合使用处要求")已不再被编译器输出,但文档被完整保留,用于记录它当年所涵盖的四类类型错误场景、当时的报错形态与修复方法。读完本文,你将理解这套错误码归档机制为什么不允许删除已停用条目,并能从 E0211 的历史报错中反推 Rust 编译器在 intrinsic、main 入口、match 模式与显式 self 参数上的类型规则。

E0211 是什么:一份"已不再输出"的历史错误码档案

该文档的第一行就明确声明:

Note: this error code is no longer emitted by the compiler.

E0211 曾经的语义是:使用的函数或类型不满足其使用处的类型要求("You used a function or type which doesn't fit the requirements for where it was used")。由于 rustc 的诊断体系持续演进,这类笼统的报错后来被拆分并替换成了更具体、更精确的诊断,因此编译器不再发出 E0211,但它作为"数字"被永久保留。

这一"只增不减"的约束写在与错误码同 crate 的注册宏注释中,见 compiler/rustc_error_codes/src/lib.rs

  • 所有错误码说明文档统一存放于 error_codes/EXXXX.md,必须遵循 RFC 1567 规定的格式;
  • 禁止从错误码注册列表中删除条目;若某个错误不再输出,只需在对应 Markdown 文件头部加注说明(如 E0001.md 的处理方式),并清理掉不再能编译的代码示例;
  • 该注册列表内容还会被 src/tools/tidy 中的 check_error_codes_docs 检查,改动宏语法需要同步更新 tidy。

因此在注册宏的错误码列表中,0211 依然被保留(见 lib.rs)。这意味着即使它不再由编译器实际发出,rustc --explain E0211 之类的查询路径仍然能定位到这份文档,供开发者查阅历史诊断语义。文档的这类归档处理与 E0001 等条目一致,共同构成了 rustc 一套"错误码编号永不回收、历史永久可考"的知识库机制。

E0211 覆盖的四类历史报错场景

文档用一段 compile_fail 代码集中呈现了当年会触发 E0211 的四类"函数或类型不符合使用要求"的典型案例。

场景一:#[rustc_intrinsic] intrinsic 函数声明了错误的类型

#![feature(intrinsics)]
#![allow(internal_features)]

#[rustc_intrinsic]
unsafe fn unreachable(); // error: intrinsic has wrong type

即:标记了 #[rustc_intrinsic] 的 intrinsic 函数,其函数签名必须与 rustc 内置 intrinsic 的真实定义(返回类型为 !)一致。缺少返回类型 ! 时,编译器判定该 intrinsic "类型错误"。

修复方式是检查函数定义、补全正确签名:

#![feature(intrinsics)]
#![allow(internal_features)]

#[rustc_intrinsic]
unsafe fn unreachable() -> !; // ok!

这里的 #![feature(intrinsics)] 用于打开不稳定特性门控,而 #![allow(internal_features)] 用于在显式启用内部特性时抑制额外的 lint 提示——该组合在 rustc 自身的测试与文档示例中非常典型。

场景二:main 函数的签名不合规

fn main() -> i32 { 0 }
// error: main function expects type: `fn() {main}`: expected (), found i32

main 函数在 Rust 中有特殊的约定入口语义。文档明确给出了它的唯一合法形式:

fn main();

main 从不接收参数,也从不返回任何值(返回类型隐式为 ())。因此上例中 fn main() -> i32 { 0 } 在当年会因返回类型不匹配而触发 E0211。

需要说明的是,文档此处描述的是 E0211 尚在输出年代的行为。现代 rustc 对 main 入口类型的校验逻辑同样位于类型检查(typeck)阶段,但报错已收敛为对返回类型、参数等各自独立、带修复建议的诊断,而不再归并为笼统的 E0211(这正与该错误码"no longer emitted"的归档注记一致)。

场景三:match 分支范围模式的端点类型与被匹配类型不一致

let x = 1u8;
match x {
    0u8..=3i8 => (),
    // error: mismatched types in range: expected u8, found i8
    _ => ()
}

规则是:match 中所有模式都必须与被匹配值的类型保持一致。这里被匹配的 xu8,范围模式 0u8..=3i8 的结束端点却是 i8,类型不一致,于是报错。

修复方式是把端点类型统一为 u8

let x = 1u8;

match x {
    0u8..=3u8 => (), // ok!
    _ => ()
}

这段历史案例也侧面反映了范围模式(range pattern)在类型层面的严格要求:同一范围的两个端点必须使用与被匹配表达式相同的类型,编译器不会在 u8/i8 之间做隐式转换。

场景四:显式 self 参数使用了不被支持的所有权类型

use std::rc::Rc;
struct Foo;

impl Foo {
    fn x(self: Rc<Foo>) {}
    // error: mismatched self type: expected `Foo`: expected struct
    //        `Foo`, found struct `alloc::rc::Rc`
}

在 Rust 中,显式 self 参数(explicit self parameter)可用的类型是受限的。文档列出当年仅允许的四类:

  • Self(按值)
  • &Self(共享引用)
  • &mut Self(独占可变引用)
  • Box<Self>(堆分配盒指针)

Rc<Foo>&Rc<Self> 这类"自定义/任意 self 类型"并不在允许集合内,因而触发 E0211。注意报错信息中 alloc::rc::Rc 表明 std::rc::Rc 在库内部即 alloc crate 中的同一类型,只是路径不同。

修复方式是把 self 改成被支持的类型:

struct Foo;

impl Foo {
    fn x(self: Box<Foo>) {} // ok!
}

需要提示读者:现代 Rust 通过不稳定特性 arbitrary_self_types 扩展了可用 self 类型集合,使 Rc<Self>Arc<Self> 等写法在相应门控下成为可能,因此这一历史限制在当前编译器版本下已不再以 E0211 的形式出现——但理解"self 类型需受编译器约束"这一原则,对阅读涉及 core/alloc 内部实现与类型系统的代码仍有价值。

从 E0211 中沉淀的四条 Rust 类型规则

把 E0211 拆开看,它本质上是对四个独立类型约束的"大杂烩",每一条在今天依然是 Rust 语义的一部分,只是由更精确的诊断来承担:

场景 底层类型规则 修复要点
intrinsic 声明 内置 intrinsic 的函数签名必须与编译器内置定义精确一致 核对返回类型等签名要素,如 unreachable() -> !
main 入口 main 不接受参数、不返回非单元类型 签名收敛为 fn main()
范围模式 范围端点的类型须与被 match 值的类型一致 统一端点类型字面量,如 0u8..=3u8
显式 self Self/&Self/&mut Self/Box<Self> 可用 改用合法 self 类型

如何在仓库中查阅这份归档及配套源码

如果你正在阅读或维护 rustc 的错误码体系,可以按以下路径继续深入当前仓库:

小结

E0211 是一枚"已退役"的错误码,它的文档价值不在于让读者去复现报错,而在于以浓缩的代码样例记录了 rustc 对 intrinsic、main 入口、match 范围模式和显式 self 参数的严格类型要求。同时,E0211.md 的存在本身就是 rustc 错误码维护策略的一个样本:编号永不回收、历史文档永续归档、停用仅在文档头部显式标注。理解这一机制,可以帮助你在面对任意 E0xxx 报错时,快速判断它是现行诊断还是历史档案,并顺着 error_codes 目录与 lib.rs 的注册宏追溯到第一手资料。

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