From 1ebdcca8b97feca67ce077a2bad87e7655bc774a Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Fri, 18 Nov 2022 22:56:22 +0100 Subject: [PATCH] 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. --- clippy_lints/src/doc.rs | 4 +--- clippy_lints/src/manual_async_fn.rs | 2 +- tests/ui/author/blocks.stdout | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 4557e4328..ae5f9424b 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -427,9 +427,7 @@ fn lint_for_missing_headers( let body = cx.tcx.hir().body(body_id); let ret_ty = typeck.expr_ty(body.value); if implements_trait(cx, ret_ty, future, &[]); - if let ty::Opaque(_, subs) = ret_ty.kind(); - if let Some(gen) = subs.types().next(); - if let ty::Generator(_, subs, _) = gen.kind(); + if let ty::Generator(_, subs, _) = ret_ty.kind(); if is_type_diagnostic_item(cx, subs.as_generator().return_ty(), sym::Result); then { span_lint( diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index 5c6a342b3..6a98df499 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -177,7 +177,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) if let Some(args) = cx .tcx .lang_items() - .from_generator_fn() + .identity_future_fn() .and_then(|def_id| match_function_call_with_def_id(cx, block_expr, def_id)); if args.len() == 1; if let Expr { diff --git a/tests/ui/author/blocks.stdout b/tests/ui/author/blocks.stdout index 9de0550d8..c6acf24c2 100644 --- a/tests/ui/author/blocks.stdout +++ b/tests/ui/author/blocks.stdout @@ -45,7 +45,7 @@ if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kin && expr1 = &cx.tcx.hir().body(body_id).value && let ExprKind::Call(func, args) = expr1.kind && let ExprKind::Path(ref qpath) = func.kind - && matches!(qpath, QPath::LangItem(LangItem::FromGenerator, _)) + && matches!(qpath, QPath::LangItem(LangItem::IdentityFuture, _)) && args.len() == 1 && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = args[0].kind && let FnRetTy::DefaultReturn(_) = fn_decl1.output