尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Rust 编译器错误 E0670 深度解析:Rust 2015 中禁止使用 `async fn` 及迁移方案
Rust 编译器错误 E0670 深度解析Rust 2015 中禁止使用async fn及迁移方案【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rust导读Rust 编译器错误代码 E0670 是初学者在从 Rust 2015 edition 迁移到新版本时最常遇到的一个编译期错误其核心信息为Rust 2015 does not permit the use ofasync fn。本文以 compiler/rustc_error_codes/src/error_codes/E0670.md 官方错误文档为骨架结合 rustc 解析器源码与 UI 测试用例完整讲解该错误的触发条件、底层检测逻辑以及通过 Cargo 或直接调用 rustc 两种方式切换到新 edition 的实操方案。读完本文你将能够独立定位此类错误、理解编译器内部如何按 edition 差异化检查语法并正确完成项目迁移。E0670 错误概览错误信息原文E0670 的错误信息非常简短官方文档给出的完整描述为Rust 2015 does not permit the use ofasync fn.其附带的错误代码示例也是触发该错误的最简形式async fn foo() {} // error[E0670]: async fn is not permitted in Rust 2015对应的修复指引为切换到 Rust 2018 或更高版本 edition 后即可使用async fn。一个完整的真实报错输出在 2015 edition 下编译上述代码rustc 会输出类似如下的完整诊断引用自仓库 UI 测试的期望输出 tests/ui/async-await/edition-deny-async-fns-2015.stderrerror[E0670]: async fn is not permitted in Rust 2015 -- edition-deny-async-fns-2015.rs:3:1 | LL | async fn foo() {} | ^^^^^ to use async fn, switch to Rust 2018 or later | help: pass --edition 2024 to rustc note: for more on editions, read https://doc.rust-lang.org/edition-guide注意其中的细节主错误标签labelto use async fn, switch to Rust 2018 or later直接指示用户升级 edition帮助信息help根据编译方式自动给出具体命令例如直接调用 rustc 时是pass --edition 2024 to rustc当前仓库对应版本中 2024 为最新稳定 edition而通过 Cargo 构建时会改为set edition 2024 in Cargo.toml备注note指引阅读官方 edition 指南。为什么 Rust 2015 不允许async fnasync/await语法是在 Rust 2018 edition 中正式引入并稳定的语言特性Rust 2015 时代只存在基于 nightly 的实验性异步实现尚无稳定的async fn语法。Rust 通过edition版本代机制管理语言演进edition 允许编译器在保持向后兼容的同时为新语法保留关键字与语法空间。async在 2015 edition 中并非保留关键字因此在 2015 下解析async fn会直接被视为非法语法并报出 E0670而不是静默降级为其他语义。这一设计在 rustc 源码中体现为按 edition 差异化检查解析器在识别到async标记后会检查该标记所在代码是否属于 2015 edition若是则立即发出 E0670 诊断详见下文编译器源码实现一节。哪些位置会触发 E0670async fn并非只能在顶层函数中使用它出现在 Rust 2015 代码的任何位置都会报错。仓库中的 UI 测试 tests/ui/async-await/edition-deny-async-fns-2015.rs标注// edition:2015即强制以 2015 edition 编译系统地覆盖了所有触发场景共产生 9 处 E0670位置代码示例是否报错顶层自由函数async fn foo() {}✅ 报错普通函数体内的嵌套函数fn baz() { async fn foo() {} }✅ 报错异步函数内部的嵌套函数async fn async_baz() { async fn bar() {} }✅ 报错impl块中的方法impl Foo { async fn foo() {} }✅ 报错trait中的方法trait Bar { async fn foo() {} }✅ 报错宏展开产生的项accept_item! { async fn foo() {} }✅ 报错impl块经宏展开accept_item! { impl Foo { async fn bar() {} } }✅ 报错闭包内的嵌套函数let f \|\| { async fn bar() {} };✅ 报错从测试可以看到E0670 的检查覆盖所有语法上下文包括宏展开后的代码——因为宏展开结果会作为新语法树重新参与解析async fn项同样被 edition 检查捕获。这意味着迁移到 2018 时即使是通过宏生成的异步函数也必须满足 edition 要求。编译器源码实现E0670 是如何被触发的诊断结构定义E0670 的诊断结构定义在 compiler/rustc_parse/src/diagnostics.rs#L2202-L2209#[derive(Diagnostic)] #[diag(async fn is not permitted in Rust 2015, code E0670)] pub(crate) struct AsyncFnIn2015 { #[primary_span] #[label(to use async fn, switch to Rust 2018 or later)] pub span: Span, #[subdiagnostic] pub help: HelpUseLatestEdition, }其中HelpUseLatestEdition是一个枚举型子诊断compiler/rustc_parse/src/diagnostics.rs#L3709-L3728它会根据编译方式自动选择提示文案#[derive(Subdiagnostic)] pub(crate) enum HelpUseLatestEdition { #[help(set edition \{$edition}\ in Cargo.toml)] #[note(for more on editions, read https://doc.rust-lang.org/edition-guide)] Cargo { edition: Edition }, #[help(pass --edition {$edition} to rustc)] #[note(for more on editions, read https://doc.rust-lang.org/edition-guide)] Standalone { edition: Edition }, }其构造逻辑通过rustc_session::utils::was_invoked_from_cargo()判断当前 rustc 是否由 Cargo 调用由 Cargo 调用时提示修改Cargo.toml否则提示在命令行传--edition。这就是为什么同一错误在不同构建方式下会给出不同修复建议。解析阶段的 edition 检查E0670 在语法解析阶段而非类型检查阶段就被抛出检测点在函数声明解析器 compiler/rustc_parse/src/parser/function.rs#L435-L443if let Some(coroutine_marker) coroutine_marker let CoroutineKind::Async coroutine_marker.kind coroutine_marker.span.is_rust_2015() { self.dcx().emit_err(diagnostics::AsyncFnIn2015 { span: coroutine_marker.span, help: diagnostics::HelpUseLatestEdition::new(), }); }关键逻辑解读解析器先通过parse_coroutine_marker识别async以及gen等标记然后检查coroutine_marker.span.is_rust_2015()——即该标记所处的代码区域是否属于 2015 edition只有同时满足是async标记且位于 2015 edition 代码两个条件才发出 E0670。Span::is_rust_2015()意味着该检查精确到代码区域粒度即便整个 crate 声明为 2018 edition某些经宏生成或#[path]引入的、标记为 2015 edition 的 span 片段同样会被拦截。这也解释了为何宏展开的项也会报错——宏定义处的 edition 会被传播到展开后的 span 上。解决方案切换到 Rust 2018 或更高版本 editionRust edition 的稳定版本序列为 2015 → 2018 → 2021 → 2024。要修复 E0670只需将代码所属 edition 提升到 2018 或更高当前仓库对应的最新稳定 edition 为 2024。根据项目的构建方式有两种做法方式一通过 Cargo 构建推荐编辑项目根目录的Cargo.toml在[package]段中设置[package] name my_async_project version 0.1.0 edition 2024 # 或 2021 / 2018改完后直接重新cargo build即可。编译器自动检测到这是 Cargo 调用帮助信息会显示set edition 2024 in Cargo.toml。方式二直接调用 rustc不经过 Cargo、直接编译单个文件时在命令行追加--edition参数rustc --edition 2024 main.rs对应帮助信息为pass --edition 2024 to rustc。此方式适合快速验证单文件代码项目级开发仍建议在Cargo.toml中声明 edition。迁移后的验证示例// 切换到 2018 edition 后以下代码可正常编译 async fn foo() - u32 { 42 } fn main() { let fut foo(); // foo 返回一个 Future // 实际运行需要 executor如 async-std / tokio配合 .await println!(async fn accepted); }注意修复 E0670 只解决了语法层面的 edition 门槛。async fn调用后返回的是未执行pending的Future真正运行它还需要搭配异步运行时runtime并通过.await或block_on驱动——这属于 async 编程的后续话题与 E0670 本身无关。相关错误与同类检查E0671已被编译器移除的错误与 E0670 相邻的 compiler/rustc_error_codes/src/error_codes/E0671.md 目前已在文档开头注明this error code is no longer emitted by the compiler其原含义是const 参数不能依赖类型参数现由 E0770 覆盖。这提醒读者错误码文档可能滞后于编译器实现若某个错误码提示不再发出应以最新编译器行为为准。其他受 2015 edition 限制的 async 语法E0670 只是2015 不支持 async系列检查之一。在 compiler/rustc_parse/src/diagnostics.rs 中同文件还定义了AsyncBlockIn2015async块仅允许在 2018、AsyncMoveBlockIn2015async move块、AsyncUseBlockIn2015以及AsyncBoundModifierIn2015asynctrait 约束等诊断结构。也就是说Rust 2015 代码中不仅async fn被禁止async {}块、async move {}块以及asynctrait bound 同样会被拒绝。迁移到 2018 edition 时这些语法会一并解锁。如何验证与深入学习阅读官方错误文档compiler/rustc_error_codes/src/error_codes/E0670.md 是本错误的权威说明入口查看 UI 测试完整覆盖 9 种触发场景的用例在 tests/ui/async-await/edition-deny-async-fns-2015.rs其精确期望输出含每种场景的完整诊断信息在 tests/ui/async-await/edition-deny-async-fns-2015.stderr运行测试可在仓库根目录执行./x test tests/ui/async-await/edition-deny-async-fns-2015.rs验证编译器行为调试源码从解析器检测点 compiler/rustc_parse/src/parser/function.rs#L435-L443 入手配合诊断结构 compiler/rustc_parse/src/diagnostics.rs#L2202-L2209 理解完整链路。小结E0670 是 edition 机制作用于语法层的一个典型示例async fn作为 2018 edition 引入的特性在 2015 代码中任何位置出现都会触发编译错误。其检测发生在 rustc 解析阶段通过Span::is_rust_2015()按代码区域精确判定并依据构建方式Cargo 或裸 rustc给出差异化的修复提示。修复方法非常简单——将Cargo.toml中的edition或 rustc 的--edition参数提升到 2018/2021/2024 即可同时async块、async move块等系列语法也会一并解锁。【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rust创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Selenium Ruby 绑定维护指南:为 Chromium DevTools Protocol 添加新版本支持并发布 selenium-devtools Gem

Selenium Ruby 绑定维护指南:为 Chromium DevTools Protocol 添加新版本支持并发布 selenium-devtools Gem

Selenium Ruby 绑定维护指南:为 Chromium DevTools Protocol 添加新版本支持并发布 selenium-devtools Gem 【免费下载链接】selenium A browser automation framework and ecosystem. 项目地址: https://gitcode.com/GitHub_Trending/se/selenium selenium-…

📅 2026/9/10 20:01:53
2026年电池争霸:二代刀片与犀牛电池技术对比解析

2026年电池争霸:二代刀片与犀牛电池技术对比解析

2026年元旦刚过,新能源市场的战火不是从某款新车的发布会烧起来的,而是从两块电池点燃的:一边是奇瑞在2025年秋天高调放出的犀牛电池,另一边是比亚迪已经装车汉L、唐L的二代刀片。这两套电池体系,将在2026年分别决定两…

📅 2026/9/10 20:01:53
Xposed框架Hook原理与安卓逆向实战指南

Xposed框架Hook原理与安卓逆向实战指南

1. Xposed框架入门指南 作为安卓系统最强大的Hook框架之一,Xposed让无数开发者又爱又恨。我第一次接触Xposed是在2015年开发一个自动化工具时,当时为了绕过某个应用的签名校验,折腾了整整三天才搞明白模块的开发逻辑。如今八年过去&#xff0…

📅 2026/9/10 20:01:53
MORE NEWS

更多资讯

📰

基于YOLOv8的FPS自动瞄准系统实现与性能优化解析

简介:基于YOLOv8的FPS类游戏自动瞄准系统毕业设计项目,集合了可运行的完整源码与答辩演示文稿PPT,主要面向计算机相关专业正在准备大作业、毕业设计的学生,以及希望通过实战项目提升深度学习和目标检测技能的学习者;项…

📰

Python大数据架构在在线考试系统中的应用实践

1. 项目概述:当大数据遇上在线考试系统去年参与某高校在线考试平台重构项目时,我深刻体会到传统考试系统在面对万人级并发时有多么脆弱。考试开始前5分钟的系统崩溃,监考老师手动记录考生名单的混乱场景至今难忘。这正是我们选择Python大数据…

📰

Langfuse 实时聚合实战:ClickHouse 增量物化视图(Incremental MV)最佳实践

Langfuse 实时聚合实战:ClickHouse 增量物化视图(Incremental MV)最佳实践 【免费下载链接】langfuse 🪢 Open source AI engineering platform: LLM evals, observability, metrics, prompt management, playground, datasets. I…

📰

openai-agents-python 追踪体系深度解析:Span 生命周期、实现原理与自定义扩展

openai-agents-python 追踪体系深度解析:Span 生命周期、实现原理与自定义扩展 【免费下载链接】openai-agents-python A lightweight, powerful framework for multi-agent workflows 项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python …

📰

airi 项目中的 VueUse useTimeoutPoll:实现“任务完成后“再轮询的定时拉取方案

airi 项目中的 VueUse useTimeoutPoll:实现"任务完成后"再轮询的定时拉取方案 【免费下载链接】airi 💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds,…

📰

打造带长期记忆的 AI Agent:Zep 记忆后端 + AutoGen 编排 + Ollama/Qwen 3 本地模型实战(Zep Memory Assistant)

打造带长期记忆的 AI Agent:Zep 记忆后端 AutoGen 编排 Ollama/Qwen 3 本地模型实战(Zep Memory Assistant) 【免费下载链接】ai-engineering-hub In-depth tutorials on LLMs, RAGs and real-world AI agent applications. 项目地址: ht…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬