Skip to content

Commit

Permalink
Auto merge of rust-lang#104321 - Swatinem:async-gen, r=oli-obk
Browse files Browse the repository at this point in the history
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
```
  • Loading branch information
bors committed Nov 24, 2022
2 parents ac6a77e + 1ebdcca commit 300d10f
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 5 deletions.
4 changes: 1 addition & 3 deletions clippy_lints/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/manual_async_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/author/blocks.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 300d10f

Please sign in to comment.