1 use rustc::ty::{self, Ty, TyCtxt};
2 use rustc_error_codes::*;
3 use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId};
4 use rustc_span::{MultiSpan, Span};
6 impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
7 crate fn cannot_move_when_borrowed(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
8 struct_span_err!(self, span, E0505, "cannot move out of `{}` because it is borrowed", desc,)
11 crate fn cannot_use_when_mutably_borrowed(
17 ) -> DiagnosticBuilder<'cx> {
18 let mut err = struct_span_err!(
22 "cannot use `{}` because it was mutably borrowed",
26 err.span_label(borrow_span, format!("borrow of `{}` occurs here", borrow_desc));
27 err.span_label(span, format!("use of borrowed `{}`", borrow_desc));
31 crate fn cannot_act_on_uninitialized_variable(
36 ) -> DiagnosticBuilder<'cx> {
41 "{} of possibly-uninitialized variable: `{}`",
47 crate fn cannot_mutably_borrow_multiply(
54 old_load_end_span: Option<Span>,
55 ) -> DiagnosticBuilder<'cx> {
57 |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) };
58 let mut err = struct_span_err!(
62 "cannot borrow `{}`{} as mutable more than once at a time",
66 if old_loan_span == new_loan_span {
67 // Both borrows are happening in the same place
68 // Meaning the borrow is occurring in a loop
72 "mutable borrow starts here in previous \
77 if let Some(old_load_end_span) = old_load_end_span {
78 err.span_label(old_load_end_span, "mutable borrow ends here");
83 format!("first mutable borrow occurs here{}", via(old_opt_via)),
87 format!("second mutable borrow occurs here{}", via(opt_via)),
89 if let Some(old_load_end_span) = old_load_end_span {
90 err.span_label(old_load_end_span, "first borrow ends here");
96 crate fn cannot_uniquely_borrow_by_two_closures(
101 old_load_end_span: Option<Span>,
102 ) -> DiagnosticBuilder<'cx> {
103 let mut err = struct_span_err!(
107 "two closures require unique access to `{}` at the same time",
110 if old_loan_span == new_loan_span {
113 "closures are constructed here in different iterations of loop",
116 err.span_label(old_loan_span, "first closure is constructed here");
117 err.span_label(new_loan_span, "second closure is constructed here");
119 if let Some(old_load_end_span) = old_load_end_span {
120 err.span_label(old_load_end_span, "borrow from first closure ends here");
125 crate fn cannot_uniquely_borrow_by_one_closure(
128 container_name: &str,
134 previous_end_span: Option<Span>,
135 ) -> DiagnosticBuilder<'cx> {
136 let mut err = struct_span_err!(
140 "closure requires unique access to `{}` but {} is already borrowed{}",
147 format!("{} construction occurs here{}", container_name, opt_via),
149 err.span_label(old_loan_span, format!("borrow occurs here{}", old_opt_via));
150 if let Some(previous_end_span) = previous_end_span {
151 err.span_label(previous_end_span, "borrow ends here");
156 crate fn cannot_reborrow_already_uniquely_borrowed(
159 container_name: &str,
165 previous_end_span: Option<Span>,
166 second_borrow_desc: &str,
167 ) -> DiagnosticBuilder<'cx> {
168 let mut err = struct_span_err!(
172 "cannot borrow `{}`{} as {} because previous closure \
173 requires unique access",
180 format!("{}borrow occurs here{}", second_borrow_desc, opt_via),
184 format!("{} construction occurs here{}", container_name, old_opt_via),
186 if let Some(previous_end_span) = previous_end_span {
187 err.span_label(previous_end_span, "borrow from closure ends here");
192 crate fn cannot_reborrow_already_borrowed(
202 old_load_end_span: Option<Span>,
203 ) -> DiagnosticBuilder<'cx> {
205 |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) };
206 let mut err = struct_span_err!(
210 "cannot borrow `{}`{} as {} because {} is also borrowed \
221 // If `msg_new` is empty, then this isn't a borrow of a union field.
222 err.span_label(span, format!("{} borrow occurs here", kind_new));
223 err.span_label(old_span, format!("{} borrow occurs here", kind_old));
225 // If `msg_new` isn't empty, then this a borrow of a union field.
229 "{} borrow of `{}` -- which overlaps with `{}` -- occurs here",
230 kind_new, msg_new, msg_old,
233 err.span_label(old_span, format!("{} borrow occurs here{}", kind_old, via(msg_old)));
236 if let Some(old_load_end_span) = old_load_end_span {
237 err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old));
242 crate fn cannot_assign_to_borrowed(
247 ) -> DiagnosticBuilder<'cx> {
248 let mut err = struct_span_err!(
252 "cannot assign to `{}` because it is borrowed",
256 err.span_label(borrow_span, format!("borrow of `{}` occurs here", desc));
257 err.span_label(span, format!("assignment to borrowed `{}` occurs here", desc));
261 crate fn cannot_reassign_immutable(
266 ) -> DiagnosticBuilder<'cx> {
267 let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
268 struct_span_err!(self, span, E0384, "cannot assign {} `{}`", msg, desc,)
271 crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
272 struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
275 crate fn cannot_move_out_of(
277 move_from_span: Span,
278 move_from_desc: &str,
279 ) -> DiagnosticBuilder<'cx> {
280 struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,)
283 /// Signal an error due to an attempt to move out of the interior
284 /// of an array or slice. `is_index` is None when error origin
285 /// didn't capture whether there was an indexing operation or not.
286 crate fn cannot_move_out_of_interior_noncopy(
288 move_from_span: Span,
290 is_index: Option<bool>,
291 ) -> DiagnosticBuilder<'cx> {
292 let type_name = match (&ty.kind, is_index) {
293 (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
294 (&ty::Slice(_), _) => "slice",
295 _ => span_bug!(move_from_span, "this path should not cause illegal move"),
297 let mut err = struct_span_err!(
301 "cannot move out of type `{}`, a non-copy {}",
305 err.span_label(move_from_span, "cannot move out of here");
309 crate fn cannot_move_out_of_interior_of_drop(
311 move_from_span: Span,
312 container_ty: Ty<'_>,
313 ) -> DiagnosticBuilder<'cx> {
314 let mut err = struct_span_err!(
318 "cannot move out of type `{}`, which implements the `Drop` trait",
321 err.span_label(move_from_span, "cannot move out of here");
325 crate fn cannot_act_on_moved_value(
329 optional_adverb_for_moved: &str,
330 moved_path: Option<String>,
331 ) -> DiagnosticBuilder<'cx> {
332 let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default();
338 "{} of {}moved value{}",
340 optional_adverb_for_moved,
345 crate fn cannot_borrow_path_as_mutable_because(
350 ) -> DiagnosticBuilder<'cx> {
351 struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
354 crate fn cannot_mutate_in_immutable_section(
357 immutable_span: Span,
358 immutable_place: &str,
359 immutable_section: &str,
361 ) -> DiagnosticBuilder<'cx> {
362 let mut err = struct_span_err!(
366 "cannot {} `{}` in {}",
371 err.span_label(mutate_span, format!("cannot {}", action));
372 err.span_label(immutable_span, format!("value is immutable in {}", immutable_section));
376 crate fn cannot_borrow_across_generator_yield(
380 ) -> DiagnosticBuilder<'cx> {
381 let mut err = struct_span_err!(
385 "borrow may still be in use when generator yields",
387 err.span_label(yield_span, "possible yield occurs here");
391 crate fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> DiagnosticBuilder<'cx> {
396 "borrow may still be in use when destructor runs",
400 crate fn path_does_not_live_long_enough(
404 ) -> DiagnosticBuilder<'cx> {
405 struct_span_err!(self, span, E0597, "{} does not live long enough", path,)
408 crate fn cannot_return_reference_to_local(
412 reference_desc: &str,
414 ) -> DiagnosticBuilder<'cx> {
415 let mut err = struct_span_err!(
419 "cannot {RETURN} {REFERENCE} {LOCAL}",
420 RETURN = return_kind,
421 REFERENCE = reference_desc,
427 format!("{}s a {} data owned by the current function", return_kind, reference_desc),
433 crate fn cannot_capture_in_long_lived_closure(
438 ) -> DiagnosticBuilder<'cx> {
439 let mut err = struct_span_err!(
443 "closure may outlive the current function, \
445 which is owned by the current function",
448 err.span_label(capture_span, format!("{} is borrowed here", borrowed_path))
449 .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path));
453 crate fn thread_local_value_does_not_live_long_enough(
456 ) -> DiagnosticBuilder<'cx> {
457 struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",)
460 crate fn temporary_value_borrowed_for_too_long(&self, span: Span) -> DiagnosticBuilder<'cx> {
461 struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
464 fn struct_span_err_with_code<S: Into<MultiSpan>>(
469 ) -> DiagnosticBuilder<'tcx> {
470 self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code)
474 crate fn borrowed_data_escapes_closure<'tcx>(
478 ) -> DiagnosticBuilder<'tcx> {
483 "borrowed data escapes outside of {}",