Skip to content

Commit

Permalink
Rollup merge of #122589 - wutchzone:121547, r=compiler-errors
Browse files Browse the repository at this point in the history
Fix diagnostics for async block cloning

Closes #121547

r? diagnostics
  • Loading branch information
matthiaskrgr committed Mar 26, 2024
2 parents ff8cdc9 + 2c433d0 commit 20770ac
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
16 changes: 13 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Expand Up @@ -4,6 +4,7 @@
#![allow(rustc::untranslatable_diagnostic)]

use either::Either;
use hir::ClosureKind;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan};
Expand Down Expand Up @@ -463,6 +464,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
{
// We already suggest cloning for these cases in `explain_captures`.
} else if let UseSpans::ClosureUse {
closure_kind:
ClosureKind::Coroutine(CoroutineKind::Desugared(_, CoroutineSource::Block)),
args_span: _,
capture_kind_span: _,
path_span,
} = move_spans
{
self.suggest_cloning(err, ty, expr, path_span);
} else if self.suggest_hoisting_call_outside_loop(err, expr) {
// The place where the the type moves would be misleading to suggest clone.
// #121466
Expand Down Expand Up @@ -621,7 +631,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}

// FIXME: We make sure that this is a normal top-level binding,
// but we could suggest `todo!()` for all uninitalized bindings in the pattern pattern
// but we could suggest `todo!()` for all uninitialized bindings in the pattern pattern
if let hir::StmtKind::Let(hir::LetStmt { span, ty, init: None, pat, .. }) =
&ex.kind
&& let hir::PatKind::Binding(..) = pat.kind
Expand Down Expand Up @@ -749,7 +759,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
true
}

/// In a move error that occurs on a call wihtin a loop, we try to identify cases where cloning
/// In a move error that occurs on a call within a loop, we try to identify cases where cloning
/// the value would lead to a logic error. We infer these cases by seeing if the moved value is
/// part of the logic to break the loop, either through an explicit `break` or if the expression
/// is part of a `while let`.
Expand Down Expand Up @@ -950,7 +960,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
{
// FIXME: We could check that the call's *parent* takes `&mut val` to make the
// suggestion more targeted to the `mk_iter(val).next()` case. Maybe do that only to
// check for wheter to suggest `let value` or `let mut value`.
// check for whether to suggest `let value` or `let mut value`.

let span = in_loop.span;
if !finder.found_breaks.is_empty()
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/borrowck/cloning-in-async-block-121547.rs
@@ -0,0 +1,11 @@
//@ edition:2021

async fn clone_async_block(value: String) {
for _ in 0..10 {
async { //~ ERROR: use of moved value: `value` [E0382]
drop(value);
//~^ HELP: consider cloning the value if the performance cost is acceptable
}.await
}
}
fn main() {}
22 changes: 22 additions & 0 deletions tests/ui/borrowck/cloning-in-async-block-121547.stderr
@@ -0,0 +1,22 @@
error[E0382]: use of moved value: `value`
--> $DIR/cloning-in-async-block-121547.rs:5:9
|
LL | async fn clone_async_block(value: String) {
| ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait
LL | for _ in 0..10 {
| -------------- inside of this loop
LL | / async {
LL | | drop(value);
| | ----- use occurs due to use in coroutine
LL | |
LL | | }.await
| |_________^ value moved here, in previous iteration of loop
|
help: consider cloning the value if the performance cost is acceptable
|
LL | drop(value.clone());
| ++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0382`.

0 comments on commit 20770ac

Please sign in to comment.