use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder};
use syntax_pos::Span;
+use syntax::source_map::CompilerDesugaringKind;
use super::borrow_set::BorrowData;
use super::{Context, MirBorrowckCtxt};
span,
format!("value moved{} here, in previous iteration of loop", move_msg),
);
+ if Some(CompilerDesugaringKind::ForLoop) == span.compiler_desugaring_kind() {
+ if let Ok(snippet) = self.infcx.tcx.sess.source_map()
+ .span_to_snippet(span)
+ {
+ err.span_suggestion(
+ move_span,
+ "consider borrowing this to avoid moving it into the for loop",
+ format!("&{}", snippet),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
is_loop_move = true;
} else if move_site.traversed_back_edge {
err.span_label(
format!("move occurs due to use{}", move_spans.describe())
);
- self.explain_why_borrow_contains_point(context, borrow, None)
- .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+ self.explain_why_borrow_contains_point(
+ context,
+ borrow,
+ None,
+ ).add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", Some(borrow_span));
err.buffer(&mut self.errors_buffer);
}
});
self.explain_why_borrow_contains_point(context, borrow, None)
- .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+ .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
err.buffer(&mut self.errors_buffer);
}
));
}
- explanation
- .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc);
+ explanation.add_explanation_to_diagnostic(
+ self.infcx.tcx,
+ self.mir,
+ &mut err,
+ first_borrow_desc,
+ None,
+ );
err.buffer(&mut self.errors_buffer);
}
if let BorrowExplanation::MustBeValidFor { .. } = explanation {
} else {
- explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+ explanation.add_explanation_to_diagnostic(
+ self.infcx.tcx,
+ self.mir,
+ &mut err,
+ "",
+ None,
+ );
}
} else {
err.span_label(borrow_span, "borrowed value does not live long enough");
format!("value captured here{}", within),
);
- explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+ explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
}
err
_ => {}
}
- explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+ explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
err.buffer(&mut self.errors_buffer);
}
}
_ => {}
}
- explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+ explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
let within = if borrow_spans.for_generator() {
" by generator"
);
self.explain_why_borrow_contains_point(context, loan, None)
- .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+ .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
err.buffer(&mut self.errors_buffer);
}
mir: &Mir<'tcx>,
err: &mut DiagnosticBuilder<'_>,
borrow_desc: &str,
+ borrow_span: Option<Span>,
) {
match *self {
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
let message = match later_use_kind {
- LaterUseKind::TraitCapture => "borrow later captured here by trait object",
- LaterUseKind::ClosureCapture => "borrow later captured here by closure",
- LaterUseKind::Call => "borrow later used by call",
- LaterUseKind::FakeLetRead => "borrow later stored here",
- LaterUseKind::Other => "borrow later used here",
+ LaterUseKind::TraitCapture => "captured here by trait object",
+ LaterUseKind::ClosureCapture => "captured here by closure",
+ LaterUseKind::Call => "used by call",
+ LaterUseKind::FakeLetRead => "stored here",
+ LaterUseKind::Other => "used here",
};
- err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message));
+ if !borrow_span.map(|sp| sp.overlaps(var_or_use_span)).unwrap_or(false) {
+ err.span_label(
+ var_or_use_span,
+ format!("{}borrow later {}", borrow_desc, message),
+ );
+ }
}
BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
let message = match later_use_kind {