1
Fork 0

Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors

Implement `gen` blocks in the 2024 edition

Coroutines tracking issue https://github.com/rust-lang/rust/issues/43122
`gen` block tracking issue https://github.com/rust-lang/rust/issues/117078

This PR implements `gen` blocks that implement `Iterator`. Most of the logic with `async` blocks is shared, and thus I renamed various types that were referring to `async` specifically.

An example usage of `gen` blocks is

```rust
fn foo() -> impl Iterator<Item = i32> {
    gen {
        yield 42;
        for i in 5..18 {
            if i.is_even() { continue }
            yield i * 2;
        }
    }
}
```

The limitations (to be resolved) of the implementation are listed in the tracking issue
This commit is contained in:
bors 2023-10-29 00:03:52 +00:00
commit 2cad938a81
75 changed files with 1096 additions and 148 deletions

View file

@ -260,7 +260,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
Async::No => closure_def,
}
}
ExprKind::Async(_, _) => self.create_def(expr.id, DefPathData::ClosureExpr, expr.span),
ExprKind::Gen(_, _, _) => self.create_def(expr.id, DefPathData::ClosureExpr, expr.span),
_ => self.parent_def,
};

View file

@ -1083,7 +1083,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for rib in ribs {
match rib.kind {
RibKind::Normal
| RibKind::ClosureOrAsync
| RibKind::FnOrCoroutine
| RibKind::Module(..)
| RibKind::MacroDefinition(..)
| RibKind::ForwardGenericParamBan => {
@ -1156,7 +1156,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for rib in ribs {
let has_generic_params: HasGenericParams = match rib.kind {
RibKind::Normal
| RibKind::ClosureOrAsync
| RibKind::FnOrCoroutine
| RibKind::Module(..)
| RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym
@ -1240,7 +1240,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for rib in ribs {
let has_generic_params = match rib.kind {
RibKind::Normal
| RibKind::ClosureOrAsync
| RibKind::FnOrCoroutine
| RibKind::Module(..)
| RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym

View file

@ -177,8 +177,8 @@ pub(crate) enum RibKind<'a> {
/// upvars).
AssocItem,
/// We passed through a closure. Disallow labels.
ClosureOrAsync,
/// We passed through a function, closure or coroutine signature. Disallow labels.
FnOrCoroutine,
/// We passed through an item scope. Disallow upvars.
Item(HasGenericParams),
@ -215,7 +215,7 @@ impl RibKind<'_> {
pub(crate) fn contains_params(&self) -> bool {
match self {
RibKind::Normal
| RibKind::ClosureOrAsync
| RibKind::FnOrCoroutine
| RibKind::ConstantItem(..)
| RibKind::Module(_)
| RibKind::MacroDefinition(_)
@ -231,7 +231,7 @@ impl RibKind<'_> {
RibKind::Normal | RibKind::MacroDefinition(..) => false,
RibKind::AssocItem
| RibKind::ClosureOrAsync
| RibKind::FnOrCoroutine
| RibKind::Item(..)
| RibKind::ConstantItem(..)
| RibKind::Module(..)
@ -924,9 +924,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
debug!("(resolving function) entering function");
// Create a value rib for the function.
self.with_rib(ValueNS, RibKind::ClosureOrAsync, |this| {
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
// Create a label rib for the function.
this.with_label_rib(RibKind::ClosureOrAsync, |this| {
this.with_label_rib(RibKind::FnOrCoroutine, |this| {
match fn_kind {
FnKind::Fn(_, _, sig, _, generics, body) => {
this.visit_generics(generics);
@ -4287,7 +4287,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
..
}) => {
self.with_rib(ValueNS, RibKind::Normal, |this| {
this.with_label_rib(RibKind::ClosureOrAsync, |this| {
this.with_label_rib(RibKind::FnOrCoroutine, |this| {
// Resolve arguments:
this.resolve_params(&fn_decl.inputs);
// No need to resolve return type --
@ -4304,7 +4304,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
})
});
}
// For closures, ClosureOrAsyncRibKind is added in visit_fn
// For closures, RibKind::FnOrCoroutine is added in visit_fn
ExprKind::Closure(box ast::Closure {
binder: ClosureBinder::For { ref generic_params, span },
..
@ -4321,8 +4321,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
);
}
ExprKind::Closure(..) => visit::walk_expr(self, expr),
ExprKind::Async(..) => {
self.with_label_rib(RibKind::ClosureOrAsync, |this| visit::walk_expr(this, expr));
ExprKind::Gen(..) => {
self.with_label_rib(RibKind::FnOrCoroutine, |this| visit::walk_expr(this, expr));
}
ExprKind::Repeat(ref elem, ref ct) => {
self.visit_expr(elem);