2 struct_span_err, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
4 use rustc_middle::ty::{self, Ty, TyCtxt};
7 impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
8 pub(crate) fn cannot_move_when_borrowed(
12 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
13 struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,)
16 pub(crate) fn cannot_use_when_mutably_borrowed(
22 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
23 let mut err = struct_span_err!(
27 "cannot use {} because it was mutably borrowed",
31 err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_desc));
32 err.span_label(span, format!("use of borrowed {}", borrow_desc));
36 pub(crate) fn cannot_act_on_uninitialized_variable(
41 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
46 "{} of possibly-uninitialized variable: `{}`",
52 pub(crate) fn cannot_mutably_borrow_multiply(
59 old_load_end_span: Option<Span>,
60 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
62 |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
63 let mut err = struct_span_err!(
67 "cannot borrow {}{} as mutable more than once at a time",
71 if old_loan_span == new_loan_span {
72 // Both borrows are happening in the same place
73 // Meaning the borrow is occurring in a loop
77 "{}{} was mutably borrowed here in the previous iteration of the loop{}",
83 if let Some(old_load_end_span) = old_load_end_span {
84 err.span_label(old_load_end_span, "mutable borrow ends here");
89 format!("first mutable borrow occurs here{}", via(old_opt_via)),
93 format!("second mutable borrow occurs here{}", via(opt_via)),
95 if let Some(old_load_end_span) = old_load_end_span {
96 err.span_label(old_load_end_span, "first borrow ends here");
102 pub(crate) fn cannot_uniquely_borrow_by_two_closures(
107 old_load_end_span: Option<Span>,
108 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
109 let mut err = struct_span_err!(
113 "two closures require unique access to {} at the same time",
116 if old_loan_span == new_loan_span {
119 "closures are constructed here in different iterations of loop",
122 err.span_label(old_loan_span, "first closure is constructed here");
123 err.span_label(new_loan_span, "second closure is constructed here");
125 if let Some(old_load_end_span) = old_load_end_span {
126 err.span_label(old_load_end_span, "borrow from first closure ends here");
131 pub(crate) fn cannot_uniquely_borrow_by_one_closure(
134 container_name: &str,
140 previous_end_span: Option<Span>,
141 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
142 let mut err = struct_span_err!(
146 "closure requires unique access to {} but {} is already borrowed{}",
153 format!("{} construction occurs here{}", container_name, opt_via),
155 err.span_label(old_loan_span, format!("borrow occurs here{}", old_opt_via));
156 if let Some(previous_end_span) = previous_end_span {
157 err.span_label(previous_end_span, "borrow ends here");
162 pub(crate) fn cannot_reborrow_already_uniquely_borrowed(
165 container_name: &str,
171 previous_end_span: Option<Span>,
172 second_borrow_desc: &str,
173 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
174 let mut err = struct_span_err!(
178 "cannot borrow {}{} as {} because previous closure \
179 requires unique access",
186 format!("{}borrow occurs here{}", second_borrow_desc, opt_via),
190 format!("{} construction occurs here{}", container_name, old_opt_via),
192 if let Some(previous_end_span) = previous_end_span {
193 err.span_label(previous_end_span, "borrow from closure ends here");
198 pub(crate) fn cannot_reborrow_already_borrowed(
208 old_load_end_span: Option<Span>,
209 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
211 |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
212 let mut err = struct_span_err!(
216 "cannot borrow {}{} as {} because {} is also borrowed as {}{}",
226 // If `msg_new` is empty, then this isn't a borrow of a union field.
227 err.span_label(span, format!("{} borrow occurs here", kind_new));
228 err.span_label(old_span, format!("{} borrow occurs here", kind_old));
230 // If `msg_new` isn't empty, then this a borrow of a union field.
234 "{} borrow of {} -- which overlaps with {} -- occurs here",
235 kind_new, msg_new, msg_old,
238 err.span_label(old_span, format!("{} borrow occurs here{}", kind_old, via(msg_old)));
241 if let Some(old_load_end_span) = old_load_end_span {
242 err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old));
247 pub(crate) fn cannot_assign_to_borrowed(
252 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
253 let mut err = struct_span_err!(
257 "cannot assign to {} because it is borrowed",
261 err.span_label(borrow_span, format!("borrow of {} occurs here", desc));
262 err.span_label(span, format!("assignment to borrowed {} occurs here", desc));
266 pub(crate) fn cannot_reassign_immutable(
271 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
272 let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
273 struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc)
276 pub(crate) fn cannot_assign(
280 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
281 struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
284 pub(crate) fn cannot_move_out_of(
286 move_from_span: Span,
287 move_from_desc: &str,
288 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
289 struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,)
292 /// Signal an error due to an attempt to move out of the interior
293 /// of an array or slice. `is_index` is None when error origin
294 /// didn't capture whether there was an indexing operation or not.
295 pub(crate) fn cannot_move_out_of_interior_noncopy(
297 move_from_span: Span,
299 is_index: Option<bool>,
300 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
301 let type_name = match (&ty.kind(), is_index) {
302 (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
303 (&ty::Slice(_), _) => "slice",
304 _ => span_bug!(move_from_span, "this path should not cause illegal move"),
306 let mut err = struct_span_err!(
310 "cannot move out of type `{}`, a non-copy {}",
314 err.span_label(move_from_span, "cannot move out of here");
318 pub(crate) fn cannot_move_out_of_interior_of_drop(
320 move_from_span: Span,
321 container_ty: Ty<'_>,
322 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
323 let mut err = struct_span_err!(
327 "cannot move out of type `{}`, which implements the `Drop` trait",
330 err.span_label(move_from_span, "cannot move out of here");
334 pub(crate) fn cannot_act_on_moved_value(
338 optional_adverb_for_moved: &str,
339 moved_path: Option<String>,
340 ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
341 let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default();
347 "{} of {}moved value{}",
349 optional_adverb_for_moved,
354 pub(crate) fn cannot_borrow_path_as_mutable_because(
359 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
360 struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
363 pub(crate) fn cannot_mutate_in_immutable_section(
366 immutable_span: Span,
367 immutable_place: &str,
368 immutable_section: &str,
370 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
371 let mut err = struct_span_err!(
375 "cannot {} {} in {}",
380 err.span_label(mutate_span, format!("cannot {}", action));
381 err.span_label(immutable_span, format!("value is immutable in {}", immutable_section));
385 pub(crate) fn cannot_borrow_across_generator_yield(
389 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
390 let mut err = struct_span_err!(
394 "borrow may still be in use when generator yields",
396 err.span_label(yield_span, "possible yield occurs here");
400 pub(crate) fn cannot_borrow_across_destructor(
403 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
408 "borrow may still be in use when destructor runs",
412 pub(crate) fn path_does_not_live_long_enough(
416 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
417 struct_span_err!(self, span, E0597, "{} does not live long enough", path,)
420 pub(crate) fn cannot_return_reference_to_local(
424 reference_desc: &str,
426 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
427 let mut err = struct_span_err!(
431 "cannot {RETURN} {REFERENCE} {LOCAL}",
432 RETURN = return_kind,
433 REFERENCE = reference_desc,
439 format!("{}s a {} data owned by the current function", return_kind, reference_desc),
445 pub(crate) fn cannot_capture_in_long_lived_closure(
451 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
452 let mut err = struct_span_err!(
456 "{} may outlive the current function, \
458 which is owned by the current function",
462 err.span_label(capture_span, format!("{} is borrowed here", borrowed_path))
463 .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path));
467 pub(crate) fn thread_local_value_does_not_live_long_enough(
470 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
471 struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",)
474 pub(crate) fn temporary_value_borrowed_for_too_long(
477 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
478 struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
481 #[rustc_lint_diagnostics]
482 fn struct_span_err_with_code<S: Into<MultiSpan>>(
485 msg: impl Into<DiagnosticMessage>,
487 ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
488 self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code)
492 pub(crate) fn borrowed_data_escapes_closure<'tcx>(
496 ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
501 "borrowed data escapes outside of {}",