|
3 | 3 |
|
4 | 4 | use rustc_errors::{Applicability, Diag};
|
5 | 5 | use rustc_hir::intravisit::Visitor;
|
6 |
| -use rustc_hir::{CaptureBy, ExprKind, HirId, Node}; |
| 6 | +use rustc_hir::{CaptureBy, ExprKind, Node}; |
7 | 7 | use rustc_middle::bug;
|
8 | 8 | use rustc_middle::mir::*;
|
9 | 9 | use rustc_middle::ty::{self, Ty};
|
@@ -307,25 +307,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
307 | 307 | self.cannot_move_out_of(span, &description)
|
308 | 308 | }
|
309 | 309 |
|
310 |
| - fn suggest_clone_of_captured_var_in_move_closure( |
| 310 | + pub(in crate::diagnostics) fn suggest_clone_of_captured_var_in_move_closure( |
311 | 311 | &self,
|
312 | 312 | err: &mut Diag<'_>,
|
313 |
| - upvar_hir_id: HirId, |
314 | 313 | upvar_name: &str,
|
315 | 314 | use_spans: Option<UseSpans<'tcx>>,
|
316 | 315 | ) {
|
317 | 316 | let tcx = self.infcx.tcx;
|
318 |
| - let typeck_results = tcx.typeck(self.mir_def_id()); |
319 | 317 | let Some(use_spans) = use_spans else { return };
|
320 | 318 | // We only care about the case where a closure captured a binding.
|
321 | 319 | let UseSpans::ClosureUse { args_span, .. } = use_spans else { return };
|
322 | 320 | let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
|
323 |
| - // Fetch the type of the expression corresponding to the closure-captured binding. |
324 |
| - let Some(captured_ty) = typeck_results.node_type_opt(upvar_hir_id) else { return }; |
325 |
| - if !self.implements_clone(captured_ty) { |
326 |
| - // We only suggest cloning the captured binding if the type can actually be cloned. |
327 |
| - return; |
328 |
| - }; |
329 | 321 | // Find the closure that captured the binding.
|
330 | 322 | let mut expr_finder = FindExprBySpan::new(args_span, tcx);
|
331 | 323 | expr_finder.include_closures = true;
|
@@ -501,20 +493,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
501 | 493 | );
|
502 | 494 |
|
503 | 495 | let closure_span = tcx.def_span(def_id);
|
504 |
| - let mut err = self |
505 |
| - .cannot_move_out_of(span, &place_description) |
| 496 | + self.cannot_move_out_of(span, &place_description) |
506 | 497 | .with_span_label(upvar_span, "captured outer variable")
|
507 | 498 | .with_span_label(
|
508 | 499 | closure_span,
|
509 | 500 | format!("captured by this `{closure_kind}` closure"),
|
510 |
| - ); |
511 |
| - self.suggest_clone_of_captured_var_in_move_closure( |
512 |
| - &mut err, |
513 |
| - upvar_hir_id, |
514 |
| - &upvar_name, |
515 |
| - use_spans, |
516 |
| - ); |
517 |
| - err |
| 501 | + ) |
518 | 502 | }
|
519 | 503 | _ => {
|
520 | 504 | let source = self.borrowed_content_source(deref_base);
|
@@ -576,7 +560,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
576 | 560 | };
|
577 | 561 |
|
578 | 562 | if let Some(expr) = self.find_expr(span) {
|
579 |
| - self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span), None); |
| 563 | + self.suggest_cloning( |
| 564 | + err, |
| 565 | + move_from.as_ref(), |
| 566 | + place_ty, |
| 567 | + expr, |
| 568 | + self.find_expr(other_span), |
| 569 | + None, |
| 570 | + ); |
580 | 571 | }
|
581 | 572 |
|
582 | 573 | err.subdiagnostic(
|
@@ -613,6 +604,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
613 | 604 | if let Some(expr) = self.find_expr(use_span) {
|
614 | 605 | self.suggest_cloning(
|
615 | 606 | err,
|
| 607 | + original_path.as_ref(), |
616 | 608 | place_ty,
|
617 | 609 | expr,
|
618 | 610 | self.find_expr(span),
|
@@ -730,7 +722,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
730 | 722 | let place_desc = &format!("`{}`", self.local_names[*local].unwrap());
|
731 | 723 |
|
732 | 724 | if let Some(expr) = self.find_expr(binding_span) {
|
733 |
| - self.suggest_cloning(err, bind_to.ty, expr, None, None); |
| 725 | + let local_place: PlaceRef<'tcx> = (*local).into(); |
| 726 | + self.suggest_cloning(err, local_place, bind_to.ty, expr, None, None); |
734 | 727 | }
|
735 | 728 |
|
736 | 729 | err.subdiagnostic(
|
|
0 commit comments