尧图精选

Rust 错误 E0789 详解:`rustc_allowed_through_unstable_modules` 必须与 `[stable]` 成对出现

🕒 发布时间:2026/9/10 13:04:49 📁 来源:尧图网络
Rust 错误 E0789 详解rustc_allowed_through_unstable_modules必须与#[stable]成对出现【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rust本篇文章深入解析 rustc 编译器内部错误码E0789的触发条件、底层实现与修复方法。该错误与编译器内部属性#[rustc_allowed_through_unstable_modules]密切相关仅在 rustc 编译器与标准库自身使用#[stable]/#[unstable]稳定性标记staged API的场景中出现普通用户代码不会触发。读完本文你将理解该属性在稳定性检查体系中的定位、E0789 的产生链路以及如何正确配对属性避免该错误并能结合仓库源码与测试用例验证其行为。错误码 E0789 是什么E0789 是 rustc 编译器内部错误码其完整诊断信息定义在 compiler/rustc_error_codes/src/error_codes/E0789.md 中。该文档开篇明确说明This error code is internal to the compiler and will not be emitted with normal Rust code.即E0789 是编译器内部错误普通 Rust 代码不会触发它。它只在 rustc 自身与标准库standard library的构建过程中当稳定性属性使用不当时才会被报告。该错误的本质是内部属性rustc_allowed_through_unstable_modules必须被用在带有#[stable]属性的条目item上否则编译器就报出 E0789。触发场景稳定性属性的配对关系staged API 与稳定性标记体系要理解 E0789首先需要了解 Rust 的 staged API分阶段 API机制。标准库和编译器内部通过#[stable(feature ..., since ...)]与#[unstable(feature ..., issue ...)]属性来管理 API 的稳定性这依赖于staged_api特性。编译器内部属性以rustc_前缀开头则依赖rustc_attrs特性这些特性都是 perma-unstable永久不稳定的绝不允许在编译器与标准库之外使用。这些内部属性在 compiler/rustc_feature/src/builtin_attrs.rs 中注册rustc_allowed_through_unstable_modules与staged_api、rustc_attrs同属内部属性列表并在 compiler/rustc_attr_ir/src/data_structures.rs 中被统一表示为Stability这一属性种类——该注释明确写着它同时代表#[stable]、#[unstable]与#[rustc_allowed_through_unstable_modules]可见三者共享同一套稳定性数据结构。稳定的条目不能出现在不稳定模块中默认情况下当一个条目带有#[stable]属性时包裹它的模块也必须带有#[stable]属性否则该条目会变成de facto事实上不稳定的——因为用户要使用它就必须先经过一个不稳定的路径。#[rustc_allowed_through_unstable_modules]正是为解决这一问题而存在的变通方案workaround它允许一个已稳定的条目逃逸escape出其不稳定的父模块。典型场景是历史上一些条目如core::intrinsics::transmute在路径稳定性检查加入之前就意外地通过不稳定路径被稳定化为保持向后兼容而使用该属性放行。E0789 的产生缺少配对的#[stable]E0789 在该属性单独出现、没有配套的#[stable]属性时被触发。下面给出仓库文档中的原始错误示例注意其中#[stable]被注释掉了// NOTE: both of these attributes are perma-unstable and should *never* be // used outside of the compiler and standard library. #![feature(rustc_attrs)] #![feature(staged_api)] #![allow(internal_features)] #![unstable(feature foo_module, reason ..., issue 123)] #[rustc_allowed_through_unstable_modules( message deprecation message, module stable_module, )] // #[stable(feature foo, since 1.0)] struct Foo; // ^^^ error: rustc_allowed_through_unstable_modules attribute must be // paired with a stable attribute编译这段代码会得到error[E0789]: rustc_allowed_through_unstable_modules attribute must be paired with a stable attribute其中message与module参数是必需的分别表示迁移提示文案与建议用户迁移到的新模块路径具体规则见下文源码解析。源码级解析错误在哪里被抛出1. 属性解析阶段收集并校验配对E0789 的实际抛出处位于 compiler/rustc_attr_parsing/src/diagnostics.rs#[derive(Diagnostic)] #[diag(rustc_allowed_through_unstable_modules attribute must be paired with a stable attribute, code E0789)] pub(crate) struct RustcAllowedUnstablePairing { #[primary_span] pub span: Span, }而触发该诊断的逻辑在 compiler/rustc_attr_parsing/src/attributes/stability.rs 的finalize阶段fn finalize(mut self, cx: FinalizeContext_, _) - OptionAttributeKind { if let Some(atum) self.allowed_through_unstable_modules { if let Some(( Stability { level: StabilityLevel::Stable { ref mut allowed_through_unstable_modules, .. }, .. }, _, )) self.stability { *allowed_through_unstable_modules Some(atum); } else { cx.dcx() .emit_err(diagnostics::RustcAllowedUnstablePairing { span: cx.target_span }); } } // ... }从源码结构可以清晰看到校验逻辑属性解析器首先收集条目上出现的rustc_allowed_through_unstable_modules参数atum在finalize阶段检查该条目是否同时带有#[stable]属性即StabilityLevel::Stable有#[stable]把(message, module)二元组写入稳定级中保存*allowed_through_unstable_modules Some(atum)配对成功没有#[stable]立即通过dcx().emit_err(...)抛出 E0789 错误。2. 参数解析规则message与module缺一不可在同一文件的 属性解析模板 中该属性被定义为列表形式message ..., module ...( [sym::rustc_allowed_through_unstable_modules], template!(List: [r#message ..., module ...#]), unstable!(staged_api), |this, cx, args| { // 依次解析 name-value 对 match name.name { sym::message { /* 记录 message */ } sym::module { /* 记录 module */ } _ { cx.adcx().expected_specific_argument(name.span, [sym::message, sym::module]); } } // ... let allowed_through_unstable_modules try { (message?, module?) }; if allowed_through_unstable_modules.is_none() { cx.emit_err(diagnostics::RustcAtumMissingParams { span: cx.attr_span }); } this.allowed_through_unstable_modules allowed_through_unstable_modules; }, ),关键约束均有源码依据message与module两个参数都是必需的任何一个缺失try { (message?, module?) }求值失败会报出RustcAtumMissingParams诊断rustc_allowed_through_unstable_modulesattribute must havemessageandmoduleparams定义在 diagnostics.rs不允许重复键同一个键出现两次会触发duplicate_key诊断不允许未知键出现message/module之外的键会触发expected_specific_argument诊断该属性本身依赖staged_api特性门控unstable!(staged_api)。3. 路径检查阶段运行时的放行逻辑配对成功后该属性在稳定性检查 pass 中发挥作用。核心逻辑位于 compiler/rustc_passes/src/stability.rs 的visit_path当路径指向的条目本身是稳定的item_is_allowed编译器会进一步检查路径的父模块段是否稳定path.segments.iter().rev().skip(1)跳过最后一段避免重复检查如果该条目带有allowed_through_unstable_modules即配对成功的(message, module)则对父模块段改用eval_stability_allow_unstable直接评估stability.rs若评估结果为不允许如模块已迁移或用户路径不对则发出弃用deprecated警告并借助RustcAtumSuggestion诊断给出迁移提示引导用户从module参数指定的新路径导入。源码注释也直接印证了该属性的历史定位stability.rsWe include special cases via#[rustc_allowed_through_unstable_modules]for items that were accidentally stabilized through unstable paths before this check was added, such ascore::intrinsics::transmute.即该属性是给在此检查加入之前、通过不稳定路径被意外稳定化的条目例如core::intrinsics::transmute保留的特殊例外。正确用法与修复方式修复 E0789补上#[stable]属性修复方式即是为条目同时标注#[stable]与#[rustc_allowed_through_unstable_modules]#![feature(rustc_attrs)] #![feature(staged_api)] #![allow(internal_features)] #![unstable(feature foo_module, reason ..., issue 123)] #[stable(feature foo, since 1.0)] #[rustc_allowed_through_unstable_modules( message deprecation message, module stable_module, )] struct Foo;注意顺序与要点#[stable]是前提message与module参数必须同时给出module参数填写建议用户迁移到的新稳定模块路径字符串形式message参数填写展示给用户的迁移提示文案该属性只能在编译器与标准库内部使用依赖 perma-unstable 的rustc_attrs、staged_api特性。仓库中的真实使用范例仓库测试用例 tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs 给出了该属性的标准写法#![crate_type lib] #![feature(staged_api)] #![feature(rustc_attrs)] #![stable(feature stable_test_feature, since 1.2.0)] #[unstable(feature unstable_test_feature, issue 1)] pub mod unstable_module { #[stable(feature stable_test_feature, since 1.2.0)] #[rustc_allowed_through_unstable_modules( message use the new path instead, module stable, )] pub trait OldStableTraitAllowedThoughUnstable {} #[stable(feature stable_test_feature, since 1.2.0)] pub trait NewStableTraitNotAllowedThroughUnstable {} }对比之下同模块内未加该属性的NewStableTraitNotAllowedThroughUnstable在从外部通过不稳定路径导入时会被正常拦截并报出E0658: use of unstable library feature。行为验证测试用例与预期输出仓库的编译测试 tests/ui/stability-attribute/allowed-through-unstable.rs 用// aux-build机制构建上述辅助 crate然后分别导入两个 traitextern crate allowed_through_unstable_core; use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstable; //~WARN use of deprecated import through accidentally stabilized module unstable_module use allowed_through_unstable_core::unstable_module::NewStableTraitNotAllowedThroughUnstable; //~ ERROR use of unstable library feature unstable_test_feature预期的.stderr输出见 allowed-through-unstable.stderr精确展示了两种行为的差异对带该属性的OldStableTraitAllowedThoughUnstable只产生一条warning默认#[warn(deprecated)]提示use of deprecated import through accidentally stabilized module并给出help: use the new path instead的迁移建议对不带该属性的NewStableTraitNotAllowedThroughUnstable直接产生error E0658使用不稳定特性unstable_test_feature编译失败。这一对照充分说明rustc_allowed_through_unstable_modules的效果是把硬性错误E0658降级为可修复的弃用警告同时保留对历史路径的兼容并通过module参数引导用户迁移到新路径。相关错误码与延伸阅读E0658use of unstable library feature即未放行时从不稳定路径访问稳定条目会触发的错误同一测试用例中有对照输出E0717rustc_promotable属性必须与rustc_const_unstable/rustc_const_stable配对属于同类的内部属性配对校验定义于 diagnostics.rs稳定性检查的完整 pass 位于 compiler/rustc_passes/src/stability.rs路径检查与放行逻辑集中在其visit_path实现中完整的错误码文档目录位于 compiler/rustc_error_codes/src/error_codes/可用rustc --explain E0789在本地查看该错误说明。小结E0789 是编译器内部错误普通用户代码不会触发它只在 rustc 与标准库内部当#[rustc_allowed_through_unstable_modules]与#[stable]配对缺失时出现该属性的作用是允许稳定条目从意外稳定化的不稳定父模块路径中被访问并把硬错误降级为带迁移提示的弃用警告修复方式是为条目同时标注#[stable]与#[rustc_allowed_through_unstable_modules(message ..., module ...)]两个参数缺一不可源码证据链完整属性注册在 builtin_attrs.rs配对校验在 attributes/stability.rs诊断定义在 diagnostics.rs路径放行逻辑在 rustc_passes/src/stability.rs并有 tests/ui/stability-attribute/allowed-through-unstable.rs 系列测试用例验证其行为。【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rust创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →