1
Fork 0
rust/compiler/rustc_hir/src
bors dc641039d2 Auto merge of #117703 - compiler-errors:recursive-async, r=lcnr
Support async recursive calls (as long as they have indirection)

Before #101692, we stored coroutine witness types directly inside of the coroutine. That means that a coroutine could not contain itself (as a witness field) without creating a cycle in the type representation of the coroutine, which we detected with the `OpaqueTypeExpander`, which is used to detect cycles when expanding opaque types after that are inferred to contain themselves.

After `-Zdrop-tracking-mir` was stabilized, we no longer store these generator witness fields directly, but instead behind a def-id based query. That means there is no technical obstacle in the compiler preventing coroutines from containing themselves per se, other than the fact that for a coroutine to have a non-infinite layout, it must contain itself wrapped in a layer of allocation indirection (like a `Box`).

This means that it should be valid for this code to work:

```
async fn async_fibonacci(i: u32) -> u32 {
    if i == 0 || i == 1 {
        i
    } else {
        Box::pin(async_fibonacci(i - 1)).await
          + Box::pin(async_fibonacci(i - 2)).await
    }
}
```

Whereas previously, you'd need to coerce the future to `Pin<Box<dyn Future<Output = ...>>` before `await`ing it, to prevent the async's desugared coroutine from containing itself across as await point.

This PR does two things:
1. Only report an error if an opaque expansion cycle is detected *not* through coroutine witness fields.
    * Instead, if we find an opaque cycle through coroutine witness fields, we compute the layout of the coroutine. If that results in a cycle error, we report it as a recursive async fn.
4. Reworks the way we report layout errors having to do with coroutines, to make up for the diagnostic regressions introduced by (1.). We actually do even better now, pointing out the call sites of the recursion!
2024-01-09 07:20:50 +00:00
..
arena.rs Remove unused arena kinds in rustc_hir and rustc_middle. 2023-11-20 15:05:26 +11:00
def.rs Give VariantData::Struct named fields, to clairfy recovered. 2023-12-20 00:07:34 +00:00
def_path_hash_map.rs Do not store stable crate id in on-disk hash map. 2023-12-24 17:22:48 +00:00
definitions.rs Do not store stable crate id in on-disk hash map. 2023-12-24 17:22:48 +00:00
diagnostic_items.rs Replace some instances of FxHashMap/FxHashSet with stable alternatives (mostly in rustc_hir and rustc_ast_lowering) 2023-12-18 21:03:32 +01:00
hir.rs Auto merge of #117703 - compiler-errors:recursive-async, r=lcnr 2024-01-09 07:20:50 +00:00
hir_id.rs Replace no_ord_impl with orderable. 2023-11-22 18:38:17 +11:00
intravisit.rs Remove hir::Guard 2024-01-05 10:56:59 +00:00
lang_items.rs Use IntoAsyncIterator in for await loop desugaring 2023-12-22 11:01:06 -08:00
lib.rs Remove unused feature. 2023-11-20 16:20:45 +11:00
pat_util.rs Replace some instances of FxHashMap/FxHashSet with stable alternatives (mostly in rustc_hir and rustc_ast_lowering) 2023-12-18 21:03:32 +01:00
stable_hash_impls.rs Only compute the crate hash when necessary. 2023-03-08 09:30:22 +11:00
target.rs Fix enforcement of generics for associated items 2023-12-15 16:17:28 +00:00
tests.rs Replace two create_default_session_if_not_set_then uses. 2023-11-02 19:35:04 +11:00
weak_lang_items.rs Rewrite implementation of #[alloc_error_handler] 2022-10-31 16:32:57 +00:00