diff options
| author | Arpad Borsos <swatinem@swatinem.de> | 2022-11-18 22:56:22 +0100 |
|---|---|---|
| committer | Arpad Borsos <swatinem@swatinem.de> | 2022-11-24 10:04:27 +0100 |
| commit | 9f36f988ad873f5d34cd9c08e4903c597ffc9532 (patch) | |
| tree | 48825cd5da62cbc7f585c6c991a3b8e25d01dd20 /compiler/rustc_const_eval/src/transform | |
| parent | fd815a5091eb4d49cd317f8ad272f17b7a5f550d (diff) | |
| download | rust-9f36f988ad873f5d34cd9c08e4903c597ffc9532.tar.gz rust-9f36f988ad873f5d34cd9c08e4903c597ffc9532.zip | |
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.
Diffstat (limited to 'compiler/rustc_const_eval/src/transform')
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/check.rs | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 36956f5dd6d..4564a6c4f2f 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -449,8 +449,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { | Rvalue::CopyForDeref(..) | Rvalue::Repeat(..) | Rvalue::Discriminant(..) - | Rvalue::Len(_) - | Rvalue::Aggregate(..) => {} + | Rvalue::Len(_) => {} + + Rvalue::Aggregate(ref kind, ..) => { + if let AggregateKind::Generator(def_id, ..) = kind.as_ref() { + if let Some(generator_kind) = self.tcx.generator_kind(def_id.to_def_id()) { + if matches!(generator_kind, hir::GeneratorKind::Async(..)) { + self.check_op(ops::Generator(generator_kind)); + } + } + } + } Rvalue::Ref(_, kind @ BorrowKind::Mut { .. }, ref place) | Rvalue::Ref(_, kind @ BorrowKind::Unique, ref place) => { @@ -889,14 +898,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } - // `async` blocks get lowered to `std::future::from_generator(/* a closure */)`. - let is_async_block = Some(callee) == tcx.lang_items().from_generator_fn(); - if is_async_block { - let kind = hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block); - self.check_op(ops::Generator(kind)); - return; - } - if !tcx.is_const_fn_raw(callee) { if !tcx.is_const_default_method(callee) { // To get to here we must have already found a const impl for the |
