part of Support gen syntax (feature gen_blocks) #16156#21987
part of Support gen syntax (feature gen_blocks) #16156#21987asukaminato0721 wants to merge 1 commit intorust-lang:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds initial support for the gen / async gen syntax (blocks and functions) across HIR lowering, type inference, and type display, including wiring up an AsyncIterator lang item and adding regression tests.
Changes:
- Introduce new HIR expression variants for
gen {}/async gen {}and lowergen fn/async gen fnbodies into them. - Extend type inference / solver interop and type display to represent
genasimpl Iterator<Item = ...>andasync genasimpl AsyncIterator<Item = ...>. - Add
AsyncIteratorminicore + lang item plumbing and new inference/coercion tests.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/test-utils/src/minicore.rs | Adds minicore support for core::async_iter::AsyncIterator plus #[lang] wiring for Option/Poll. |
| crates/intern/src/symbol/symbols.rs | Registers new symbols used by the async iterator/lang item plumbing. |
| crates/hir/src/display.rs | Displays gen fn/async gen fn and strips wrapped return types similarly to async fn. |
| crates/hir-ty/src/tests/simple.rs | Adds inference tests for gen/async gen blocks and functions. |
| crates/hir-ty/src/tests/coercion.rs | Adds coercion tests for yield inside gen/async gen blocks. |
| crates/hir-ty/src/next_solver/interner.rs | Updates solver interner to recognize Gen/AsyncGen and map AsyncIterator lang item. |
| crates/hir-ty/src/mir/lower.rs | Explicitly marks gen/async gen blocks as not supported in MIR lowering. |
| crates/hir-ty/src/infer/mutability.rs | Includes Gen/AsyncGen in mutability inference traversal. |
| crates/hir-ty/src/infer/expr.rs | Implements inference + coroutine type lowering for Gen/AsyncGen blocks. |
| crates/hir-ty/src/infer/closure/analysis.rs | Includes Gen/AsyncGen in closure capture analysis traversal. |
| crates/hir-ty/src/display.rs | Displays coroutine types originating from gen/async gen as impl Iterator/AsyncIterator. |
| crates/hir-ty/src/diagnostics/unsafe_check.rs | Traverses Gen/AsyncGen blocks in unsafe diagnostics. |
| crates/hir-ty/src/diagnostics/expr.rs | Validates Gen/AsyncGen blocks like other block expressions. |
| crates/hir-expand/src/mod_path.rs | Adds known path for core::async_iter::AsyncIterator. |
| crates/hir-def/src/signatures.rs | Adds GEN flag and is_gen() on function signatures. |
| crates/hir-def/src/lang_item.rs | Adds AsyncIterator to the lang item table. |
| crates/hir-def/src/hir.rs | Adds Expr::Gen and Expr::AsyncGen HIR variants. |
| crates/hir-def/src/expr_store/scope.rs | Ensures scopes are computed for Gen/AsyncGen blocks. |
| crates/hir-def/src/expr_store/pretty.rs | Pretty-prints gen and async gen blocks. |
| crates/hir-def/src/expr_store/lower.rs | Lowers gen/async gen blocks and wraps gen fn/async gen fn bodies; wraps function return type in Iterator/AsyncIterator impl-trait. |
| crates/hir-def/src/expr_store/body.rs | Threads is_gen_fn into body lowering. |
| crates/hir-def/src/expr_store.rs | Traversal updates to treat Gen/AsyncGen as block-like expressions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let result = Pin::new(&mut generator).poll_next(&mut cx); | ||
| } | ||
| "#, | ||
| expect![[r#" | ||
| 91..97 'mut cx': Context<'?> | ||
| 112..239 '{ ...cx); }': () | ||
| 122..135 'mut generator': impl AsyncIterator<Item = i8> | ||
| 138..174 'async ... }': impl AsyncIterator<Item = i8> | ||
| 158..167 'yield 1i8': () | ||
| 164..167 '1i8': i8 | ||
| 184..190 'result': {unknown} | ||
| 193..201 'Pin::new': fn new<&'? mut impl AsyncIterator<Item = i8>>(&'? mut impl AsyncIterator<Item = i8>) -> Pin<&'? mut impl AsyncIterator<Item = i8>> | ||
| 193..217 'Pin::n...rator)': Pin<&'? mut impl AsyncIterator<Item = i8>> | ||
| 193..236 'Pin::n...ut cx)': Poll<Option<<impl AsyncIterator<Item = i8> as AsyncIterator>::Item>> | ||
| 202..216 '&mut generator': &'? mut impl AsyncIterator<Item = i8> | ||
| 207..216 'generator': impl AsyncIterator<Item = i8> | ||
| 228..235 '&mut cx': &'? mut Context<'?> | ||
| 233..235 'cx': Context<'?> |
There was a problem hiding this comment.
In this async gen block inference test, the binding result is expected to have type {unknown}, but the initializer expression is inferred as Poll<Option<<impl AsyncIterator<Item = i8> as AsyncIterator>::Item>> in the same snapshot. This looks like an inference/display gap for local bindings (it should likely resolve to Poll<Option<i8>>, consistent with the async_gen_fn_types_inferred test below). Consider updating the implementation so result gets a concrete type here, and then tighten the expectation accordingly so the test doesn't lock in {unknown}.
| let result = Pin::new(&mut generator).poll_next(&mut cx); | |
| } | |
| "#, | |
| expect![[r#" | |
| 91..97 'mut cx': Context<'?> | |
| 112..239 '{ ...cx); }': () | |
| 122..135 'mut generator': impl AsyncIterator<Item = i8> | |
| 138..174 'async ... }': impl AsyncIterator<Item = i8> | |
| 158..167 'yield 1i8': () | |
| 164..167 '1i8': i8 | |
| 184..190 'result': {unknown} | |
| 193..201 'Pin::new': fn new<&'? mut impl AsyncIterator<Item = i8>>(&'? mut impl AsyncIterator<Item = i8>) -> Pin<&'? mut impl AsyncIterator<Item = i8>> | |
| 193..217 'Pin::n...rator)': Pin<&'? mut impl AsyncIterator<Item = i8>> | |
| 193..236 'Pin::n...ut cx)': Poll<Option<<impl AsyncIterator<Item = i8> as AsyncIterator>::Item>> | |
| 202..216 '&mut generator': &'? mut impl AsyncIterator<Item = i8> | |
| 207..216 'generator': impl AsyncIterator<Item = i8> | |
| 228..235 '&mut cx': &'? mut Context<'?> | |
| 233..235 'cx': Context<'?> | |
| let result: core::task::Poll<Option<i8>> = Pin::new(&mut generator).poll_next(&mut cx); | |
| } | |
| "#, | |
| expect![[r#" | |
| 91..97 'mut cx': Context<'?> | |
| 112..264 '{ ...cx); }': () | |
| 122..135 'mut generator': impl AsyncIterator<Item = i8> | |
| 138..174 'async ... }': impl AsyncIterator<Item = i8> | |
| 158..167 'yield 1i8': () | |
| 164..167 '1i8': i8 | |
| 184..190 'result': Poll<Option<i8>> | |
| 223..231 'Pin::new': fn new<&'? mut impl AsyncIterator<Item = i8>>(&'? mut impl AsyncIterator<Item = i8>) -> Pin<&'? mut impl AsyncIterator<Item = i8>> | |
| 223..247 'Pin::n...rator)': Pin<&'? mut impl AsyncIterator<Item = i8>> | |
| 223..266 'Pin::n...ut cx)': Poll<Option<i8>> | |
| 232..246 '&mut generator': &'? mut impl AsyncIterator<Item = i8> | |
| 237..246 'generator': impl AsyncIterator<Item = i8> | |
| 258..265 '&mut cx': &'? mut Context<'?> | |
| 263..265 'cx': Context<'?> |
part of #16156
add basic supports for
gen { }async gen { }gen fnasync gen fnfix some type signature show.
add some tests.