Skip to content

Commit 300d10f

Browse files
committed
Auto merge of rust-lang#104321 - Swatinem:async-gen, r=oli-obk
Avoid `GenFuture` shim when compiling async constructs Previously, async constructs would be lowered to "normal" generators, with an additional `from_generator` / `GenFuture` shim in between to convert from `Generator` to `Future`. The compiler will now special-case these generators internally so that async constructs will *directly* implement `Future` without the need to go through the `from_generator` / `GenFuture` shim. The primary motivation for this change was hiding this implementation detail in stack traces and debuginfo, but it can in theory also help the optimizer as there is less abstractions to see through. --- Given this demo code: ```rust pub async fn a(arg: u32) -> Backtrace { let bt = b().await; let _arg = arg; bt } pub async fn b() -> Backtrace { Backtrace::force_capture() } ``` I would get the following with the latest stable compiler (on Windows): ``` 4: async_codegen::b::async_fn$0 at .\src\lib.rs:10 5: core::future::from_generator::impl$1::poll<enum2$<async_codegen::b::async_fn_env$0> > at /rustc/897e37553bba8b42751c67658967889d11ecd120\library\core\src\future\mod.rs:91 6: async_codegen::a::async_fn$0 at .\src\lib.rs:4 7: core::future::from_generator::impl$1::poll<enum2$<async_codegen::a::async_fn_env$0> > at /rustc/897e37553bba8b42751c67658967889d11ecd120\library\core\src\future\mod.rs:91 ``` whereas now I get a much cleaner stack trace: ``` 3: async_codegen::b::async_fn$0 at .\src\lib.rs:10 4: async_codegen::a::async_fn$0 at .\src\lib.rs:4 ```
2 parents ac6a77e + 1ebdcca commit 300d10f

File tree

3 files changed

+3
-5
lines changed

3 files changed

+3
-5
lines changed

clippy_lints/src/doc.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,7 @@ fn lint_for_missing_headers(
427427
let body = cx.tcx.hir().body(body_id);
428428
let ret_ty = typeck.expr_ty(body.value);
429429
if implements_trait(cx, ret_ty, future, &[]);
430-
if let ty::Opaque(_, subs) = ret_ty.kind();
431-
if let Some(gen) = subs.types().next();
432-
if let ty::Generator(_, subs, _) = gen.kind();
430+
if let ty::Generator(_, subs, _) = ret_ty.kind();
433431
if is_type_diagnostic_item(cx, subs.as_generator().return_ty(), sym::Result);
434432
then {
435433
span_lint(

clippy_lints/src/manual_async_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>)
177177
if let Some(args) = cx
178178
.tcx
179179
.lang_items()
180-
.from_generator_fn()
180+
.identity_future_fn()
181181
.and_then(|def_id| match_function_call_with_def_id(cx, block_expr, def_id));
182182
if args.len() == 1;
183183
if let Expr {

tests/ui/author/blocks.stdout

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kin
4545
&& expr1 = &cx.tcx.hir().body(body_id).value
4646
&& let ExprKind::Call(func, args) = expr1.kind
4747
&& let ExprKind::Path(ref qpath) = func.kind
48-
&& matches!(qpath, QPath::LangItem(LangItem::FromGenerator, _))
48+
&& matches!(qpath, QPath::LangItem(LangItem::IdentityFuture, _))
4949
&& args.len() == 1
5050
&& let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = args[0].kind
5151
&& let FnRetTy::DefaultReturn(_) = fn_decl1.output

0 commit comments

Comments
 (0)