Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Rewrite closure-of-async to async-closure
  • Loading branch information
compiler-errors committed Aug 9, 2024
commit e172dd27fd454645f90d5f4c8e98c1dab0f54924
30 changes: 27 additions & 3 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,30 @@ impl Expr {
}
}

pub fn peel_uwu(&self) -> &Expr {
let mut expr = self;
loop {
match &expr.kind {
ExprKind::Block(blk, None) => {
if blk.stmts.len() == 1
&& let StmtKind::Expr(blk) = &blk.stmts[0].kind
{
expr = blk;
} else {
break;
}
}
ExprKind::Paren(paren) => {
expr = paren;
}
_ => {
break;
}
}
}
expr
}

pub fn peel_parens(&self) -> &Expr {
let mut expr = self;
while let ExprKind::Paren(inner) = &expr.kind {
Expand Down Expand Up @@ -1614,15 +1638,15 @@ pub struct QSelf {
}

/// A capture clause used in closures and `async` blocks.
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Ord, PartialOrd)]
pub enum CaptureBy {
/// `move` keyword was not specified.
Ref,
/// `move |x| y + x`.
Value {
/// The span of the `move` keyword.
move_kw: Span,
},
/// `move` keyword was not specified.
Ref,
}

/// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
Expand Down
59 changes: 47 additions & 12 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,18 +219,53 @@ impl<'hir> LoweringContext<'_, 'hir> {
*fn_decl_span,
*fn_arg_span,
),
None => self.lower_expr_closure(
binder,
*capture_clause,
e.id,
hir_id,
*constness,
*movability,
fn_decl,
body,
*fn_decl_span,
*fn_arg_span,
),
None => {
let peeled = body.peel_uwu();
if let ast::ExprKind::Gen(
gen_capture_clause,
block,
gen_kind @ ast::GenBlockKind::Async,
span,
) = &peeled.kind
{
let coroutine_kind = match gen_kind {
GenBlockKind::Async => CoroutineKind::Async { span: *span, closure_id: peeled.node_id(), return_impl_trait_id: self.next_node_id() },
GenBlockKind::Gen => CoroutineKind::Gen { span: *span, closure_id: peeled.node_id(), return_impl_trait_id: self.next_node_id() },
GenBlockKind::AsyncGen => CoroutineKind::AsyncGen { span: *span, closure_id: peeled.node_id(), return_impl_trait_id: self.next_node_id() },
};
let id = self.next_node_id();
self.lower_expr_coroutine_closure(
binder,
capture_clause.max(*gen_capture_clause),
e.id,
hir_id,
coroutine_kind,
fn_decl,
&ast::Expr {
id,
span: *span,
kind: ExprKind::Block(block.clone(), None),
attrs: thin_vec![],
tokens: None,
},
*fn_decl_span,
*fn_arg_span,
)
} else {
self.lower_expr_closure(
binder,
*capture_clause,
e.id,
hir_id,
*constness,
*movability,
fn_decl,
body,
*fn_decl_span,
*fn_arg_span,
)
}
}
},
ExprKind::Gen(capture_clause, block, genblock_kind, decl_span) => {
let desugaring_kind = match genblock_kind {
Expand Down
26 changes: 2 additions & 24 deletions tests/ui/async-await/async-closures/wrong-fn-kind.stderr
Original file line number Diff line number Diff line change
@@ -1,24 +1,3 @@
error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
--> $DIR/wrong-fn-kind.rs:17:20
|
LL | needs_async_fn(move || async move {
| -------------- -^^^^^^
| | |
| _____|______________this closure implements `async FnOnce`, not `async Fn`
| | |
| | required by a bound introduced by this call
LL | |
LL | | println!("{x}");
| | - closure is `async FnOnce` because it moves the variable `x` out of its environment
LL | | });
| |_____- the requirement to implement `async Fn` derives from here
|
note: required by a bound in `needs_async_fn`
--> $DIR/wrong-fn-kind.rs:5:27
|
LL | fn needs_async_fn(_: impl async Fn()) {}
| ^^^^^^^^^^ required by this bound in `needs_async_fn`

error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/wrong-fn-kind.rs:9:20
|
Expand All @@ -35,7 +14,6 @@ LL |
LL | x += 1;
| - mutable borrow occurs due to use of `x` in closure

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

Some errors have detailed explanations: E0525, E0596.
For more information about an error, try `rustc --explain E0525`.
For more information about this error, try `rustc --explain E0596`.