
Rust 精确捕获use...语法错误 E0799 详解仅允许类型与常量参数【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rustE0799 是 rustc 编译器在解析impl Trait精确捕获precise capturinguse...语法时遇到非类型/常量参数如函数名、局部变量、生命周期等所触发的编译错误。本文以 E0799 官方错误说明 为骨架结合编译器源码与测试用例剖析该错误的触发条件、底层解析逻辑与修复方法。错误速览E0799 是什么当代码在use...精确捕获列表中使用了既不是类型参数、也不是常量参数的名称时rustc 会报出 E0799error[E0799]: expected type or const parameter, found function hello error[E0799]: expected type or const parameter, found local variable x其完整诊断消息定义在 rustc_hir_analysis/src/diagnostics/precise_captures.rs#[diag(expected {$kind} parameter in use... precise captures list, found {$found})] pub(crate) struct BadPreciseCapture { #[primary_span] pub span: Span, pub kind: static str, pub found: String, }即在use...列表中期望出现类型参数或常量参数实际却发现了其他种类的名称。官方错误示例解析官方文档给出以下错误代码示例fn bad1() - impl Sized usemain {} fn bad2(x: ()) - impl Sized usex {} fn main() {}bad1中main是一个函数而非类型参数或常量参数bad2中x是函数参数局部变量同样不是类型参数或常量参数。两者都会触发 E0799。只有类型参数、常量参数以及Self才允许出现在use...精确捕获列表中。触发 E0799 的三种典型场景综合官方文档与仓库测试 tests/ui/impl-trait/precise-capturing/bad-params.rs该测试覆盖了 E0799 的完整触发面对应期望输出见 bad-params.stderr可归纳出三类触发场景场景一捕获了函数名fn hello() - impl Sized usehello {}输出error[E0799]: expected type or const parameter, found function hello -- bad-params.rs:13:32 | LL | fn hello() - impl Sized usehello {} | ^^^^^ not a type or const parameter场景二捕获了局部变量函数参数fn arg(x: ()) - impl Sized usex {}输出error[E0799]: expected type or const parameter, found local variable x -- bad-params.rs:16:35 | LL | fn arg(x: ()) - impl Sized usex {} | ^ not a type or const parameter场景三在 impl 块中捕获Self别名而非参数struct MyType; impl MyType { fn self_is_not_param() - impl Sized useSelf {} }输出error[E0799]: Self cant be captured in use... precise captures list, since it is an alias该诊断同样来自 precise_captures.rs 中的PreciseCaptureSelfAlias。原因在于在impl块内部Self并不是泛型参数而是当前实现类型MyType的别名其标签信息明确指出“Self不是泛型参数而是对实现类型的别名”。注意区分文档中“包括Self”指的是类型定义/ trait 场景下Self作为隐式类型参数可以被捕获而在impl块场景下Self是别名捕获它反而会触发 E0799。此外若在普通函数中直接书写useSelf则会先触发 E0411Self仅可在 impl、trait 与类型定义中使用而非 E0799。底层原理rustc 如何判定“非法捕获”E0799 的产生并非在类型检查阶段随机判断而是名称解析name resolution阶段的路径来源PathSource校验机制直接决定的。名称解析阶段的校验在 compiler/rustc_resolve/src/late.rs 中use...列表中的每一项都会被解析为PathSource::PreciseCapturingArg并按命名空间分类校验PathSource::PreciseCapturingArg(ValueNS) { matches!(res, Res::Def(DefKind::ConstParam, _)) } // We allow SelfTyAlias here so we can give a more descriptive error later. PathSource::PreciseCapturingArg(TypeNS) matches!( res, Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } ), PathSource::PreciseCapturingArg(MacroNS) false,可见校验规则非常明确命名空间允许的解析结果说明值命名空间ValueNSConstParam常量参数仅常量参数类型命名空间TypeNSTyParam类型参数、SelfTyParamSelf类型参数、SelfTyAliasSelf别名类型参数与Self宏命名空间MacroNS无恒为false宏一律不允许当上述校验失败时has_unexpected_resolution true即名称存在但种类不符error_code方法会将该路径映射到 E0799(PathSource::PreciseCapturingArg(..), true) E0799, (PathSource::PreciseCapturingArg(..), false) E0800,这正是 E0799 与 E0800 的分工所在E0799名称解析到了某个实体但该实体不是类型/常量参数has_unexpected_resolution trueE0800名称完全不存在于当前作用域has_unexpected_resolution false。两者同属于use...精确捕获的参数校验体系前者是“找到了但类型不对”后者是“根本找不到”。类型检查阶段的补充诊断到了类型检查HIR analysis阶段rustc_hir_analysis/src/diagnostics/precise_captures.rs中的BadPreciseCapture结构体负责产出“expected ... found ...”格式的最终错误消息而PreciseCaptureSelfAlias则专门处理impl块中Self别名被捕获的特殊情形同样归属 E0799。哪些参数可以合法捕获E0799 的反面——合法捕获列表——包含以下内容在use...中类型参数fn fooT() - impl Sized useT常量参数fn fooconst N: usize() - impl Sized useNSelf类型参数在 trait 或类型定义等Self作为隐式泛型参数的场景下如 trait 方法fn method() - impl Sized useSelf。若遗漏了某个本应被捕获的泛型参数rustc 会给出其他精确捕获相关诊断例如ParamNotCaptured“impl Trait必须在use...中提及所有在作用域内的{$kind}参数”、SelfTyNotCaptured、LifetimeNotCaptured等——这些均位于同一诊断文件 precise_captures.rs 中与 E0799 共同构成精确捕获语法的完整错误诊断体系。相关的更多正例与反例测试可继续查看 tests/ui/impl-trait/precise-capturing/ 目录下的其他用例。修复方法触发 E0799 通常意味着use...列表中写入了不该出现的名称。修复思路如下捕获函数名/局部变量删除该项或替换为实际需要捕获的泛型参数。例如fn bad1T() - impl Sized useT {}在impl块中捕获Self别名删除useSelf改用显式类型参数如将Self泛型化或在不需要精确捕获时直接省略use...子句。确认名称确实在作用域内若名称根本不存在对应 E0800则需先声明对应的类型参数或常量参数。小结要点说明错误含义use...中出现了非类型/常量参数触发场景捕获函数名、局部变量、宏、impl块中的Self别名诊断位置名称解析阶段 rustc_resolve/src/late.rs 的PreciseCapturingArg路径校验消息模板rustc_hir_analysis/src/diagnostics/precise_captures.rs 的BadPreciseCapture/PreciseCaptureSelfAlias相关错误码E0800名称不存在、E0411Self位置非法合法捕获类型参数、常量参数、作为类型参数的Self【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rust创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考