Fix diagnostics for async block cloning

This commit is contained in:
Daniel Sedlak 2024-03-16 11:50:02 +01:00
parent 020bbe46bd
commit 0c7f8b0f89
3 changed files with 43 additions and 0 deletions

View File

@ -4,6 +4,7 @@
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use either::Either; use either::Either;
use hir::ClosureKind;
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan}; use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan};
@ -463,6 +464,15 @@ fn visit_pat(&mut self, p: &'hir hir::Pat<'hir>) {
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans } else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
{ {
// We already suggest cloning for these cases in `explain_captures`. // 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) { } else if self.suggest_hoisting_call_outside_loop(err, expr) {
// The place where the the type moves would be misleading to suggest clone. // The place where the the type moves would be misleading to suggest clone.
// #121466 // #121466

View File

@ -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() {}

View File

@ -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`.