diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/move_errors.rs | 39 |
2 files changed, 27 insertions, 29 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 98dc898db23..d1dac1c7145 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -518,11 +518,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } = move_spans && can_suggest_clone { - self.suggest_cloning(err, ty, expr, Some(move_spans)); + self.suggest_cloning(err, place.as_ref(), ty, expr, Some(move_spans)); } else if self.suggest_hoisting_call_outside_loop(err, expr) && can_suggest_clone { // The place where the type moves would be misleading to suggest clone. // #121466 - self.suggest_cloning(err, ty, expr, Some(move_spans)); + self.suggest_cloning(err, place.as_ref(), ty, expr, Some(move_spans)); } } @@ -1224,6 +1224,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn suggest_cloning( &self, err: &mut Diag<'_>, + place: PlaceRef<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>, use_spans: Option<UseSpans<'tcx>>, @@ -1238,7 +1239,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } if self.implements_clone(ty) { - self.suggest_cloning_inner(err, ty, expr); + if self.in_move_closure(expr) { + if let Some(name) = self.describe_place(place) { + self.suggest_clone_of_captured_var_in_move_closure(err, &name, use_spans); + } + } else { + self.suggest_cloning_inner(err, ty, expr); + } } else if let ty::Adt(def, args) = ty.kind() && def.did().as_local().is_some() && def.variants().iter().all(|variant| { @@ -1505,7 +1512,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let hir::ExprKind::AddrOf(_, _, borrowed_expr) = expr.kind && let Some(ty) = typeck_results.expr_ty_opt(borrowed_expr) { - self.suggest_cloning(&mut err, ty, borrowed_expr, Some(move_spans)); + self.suggest_cloning(&mut err, place.as_ref(), ty, borrowed_expr, Some(move_spans)); } else if typeck_results.expr_adjustments(expr).first().is_some_and(|adj| { matches!( adj.kind, @@ -1518,7 +1525,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) }) && let Some(ty) = typeck_results.expr_ty_opt(expr) { - self.suggest_cloning(&mut err, ty, expr, Some(move_spans)); + self.suggest_cloning(&mut err, place.as_ref(), ty, expr, Some(move_spans)); } } self.buffer_error(err); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index b21d348183f..92ca868eb99 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -325,25 +325,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.cannot_move_out_of(span, &description) } - fn suggest_clone_of_captured_var_in_move_closure( + pub(in crate::diagnostics) fn suggest_clone_of_captured_var_in_move_closure( &self, err: &mut Diag<'_>, - upvar_hir_id: HirId, upvar_name: &str, use_spans: Option<UseSpans<'tcx>>, ) { let tcx = self.infcx.tcx; - let typeck_results = tcx.typeck(self.mir_def_id()); let Some(use_spans) = use_spans else { return }; // We only care about the case where a closure captured a binding. let UseSpans::ClosureUse { args_span, .. } = use_spans else { return }; let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; - // Fetch the type of the expression corresponding to the closure-captured binding. - let Some(captured_ty) = typeck_results.node_type_opt(upvar_hir_id) else { return }; - if !self.implements_clone(captured_ty) { - // We only suggest cloning the captured binding if the type can actually be cloned. - return; - }; // Find the closure that captured the binding. let mut expr_finder = FindExprBySpan::new(args_span, tcx); expr_finder.include_closures = true; @@ -396,7 +388,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .indentation_before(stmt.span) .unwrap_or_else(|| " ".to_string()); err.multipart_suggestion_verbose( - "clone the value before moving it into the closure", + "consider cloning the value before moving it into the closure", vec