1 use rustc
::ty
::{self, Ty, TyCtxt}
;
2 use rustc_errors
::{DiagnosticBuilder, DiagnosticId}
;
3 use syntax_pos
::{MultiSpan, Span}
;
5 impl<'cx
, 'tcx
> crate::borrow_check
::MirBorrowckCtxt
<'cx
, 'tcx
> {
6 crate fn cannot_move_when_borrowed(
10 ) -> DiagnosticBuilder
<'cx
> {
15 "cannot move out of `{}` because it is borrowed",
20 crate fn cannot_use_when_mutably_borrowed(
26 ) -> DiagnosticBuilder
<'cx
> {
27 let mut err
= struct_span_err
!(
31 "cannot use `{}` because it was mutably borrowed",
37 format
!("borrow of `{}` occurs here", borrow_desc
),
39 err
.span_label(span
, format
!("use of borrowed `{}`", borrow_desc
));
43 crate fn cannot_act_on_uninitialized_variable(
48 ) -> DiagnosticBuilder
<'cx
> {
53 "{} of possibly uninitialized variable: `{}`",
59 crate fn cannot_mutably_borrow_multiply(
66 old_load_end_span
: Option
<Span
>,
67 ) -> DiagnosticBuilder
<'cx
> {
69 if msg
.is_empty() { msg.to_string() }
else { format!(" (via `{}`
)", msg) };
70 let mut err = struct_span_err!(
74 "cannot borrow `{}`{}
as mutable more than once at a time
",
78 if old_loan_span == new_loan_span {
79 // Both borrows are happening in the same place
80 // Meaning the borrow is occurring in a loop
84 "mutable borrow starts here
in previous
\
89 if let Some(old_load_end_span) = old_load_end_span {
90 err.span_label(old_load_end_span, "mutable borrow ends here
");
95 format!("first mutable borrow occurs here{}
", via(old_opt_via)),
99 format!("second mutable borrow occurs here{}
", via(opt_via)),
101 if let Some(old_load_end_span) = old_load_end_span {
102 err.span_label(old_load_end_span, "first borrow ends here
");
108 crate fn cannot_uniquely_borrow_by_two_closures(
113 old_load_end_span: Option<Span>,
114 ) -> DiagnosticBuilder<'cx> {
115 let mut err = struct_span_err!(
119 "two closures require unique access to `{}` at the same time
",
122 if old_loan_span == new_loan_span {
125 "closures are constructed here
in different iterations of
loop"
128 err.span_label(old_loan_span, "first closure is constructed here
");
129 err.span_label(new_loan_span, "second closure is constructed here
");
131 if let Some(old_load_end_span) = old_load_end_span {
132 err.span_label(old_load_end_span, "borrow from first closure ends here
");
137 crate fn cannot_uniquely_borrow_by_one_closure(
140 container_name: &str,
146 previous_end_span: Option<Span>,
147 ) -> DiagnosticBuilder<'cx> {
148 let mut err = struct_span_err!(
152 "closure requires unique access to `{}` but {} is already borrowed{}
",
159 format!("{} construction occurs here{}
", container_name, opt_via),
161 err.span_label(old_loan_span, format!("borrow occurs here{}
", old_opt_via));
162 if let Some(previous_end_span) = previous_end_span {
163 err.span_label(previous_end_span, "borrow ends here
");
168 crate fn cannot_reborrow_already_uniquely_borrowed(
171 container_name: &str,
177 previous_end_span: Option<Span>,
178 second_borrow_desc: &str,
179 ) -> DiagnosticBuilder<'cx> {
180 let mut err = struct_span_err!(
184 "cannot borrow `{}`{}
as {} because previous closure
\
185 requires unique access
",
192 format!("{}borrow occurs here{}
", second_borrow_desc, opt_via),
196 format!("{} construction occurs here{}
", container_name, old_opt_via),
198 if let Some(previous_end_span) = previous_end_span {
199 err.span_label(previous_end_span, "borrow from closure ends here
");
204 crate fn cannot_reborrow_already_borrowed(
214 old_load_end_span: Option<Span>,
215 ) -> DiagnosticBuilder<'cx> {
216 let via = |msg: &str|
217 if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg
) };
218 let mut err
= struct_span_err
!(
222 "cannot borrow `{}`{} as {} because {} is also borrowed \
233 // If `msg_new` is empty, then this isn't a borrow of a union field.
234 err
.span_label(span
, format
!("{} borrow occurs here", kind_new
));
235 err
.span_label(old_span
, format
!("{} borrow occurs here", kind_old
));
237 // If `msg_new` isn't empty, then this a borrow of a union field.
241 "{} borrow of `{}` -- which overlaps with `{}` -- occurs here",
242 kind_new
, msg_new
, msg_old
,
247 format
!("{} borrow occurs here{}", kind_old
, via(msg_old
)),
251 if let Some(old_load_end_span
) = old_load_end_span
{
252 err
.span_label(old_load_end_span
, format
!("{} borrow ends here", kind_old
));
257 crate fn cannot_assign_to_borrowed(
262 ) -> DiagnosticBuilder
<'cx
> {
263 let mut err
= struct_span_err
!(
267 "cannot assign to `{}` because it is borrowed",
271 err
.span_label(borrow_span
, format
!("borrow of `{}` occurs here", desc
));
274 format
!("assignment to borrowed `{}` occurs here", desc
),
279 crate fn cannot_reassign_immutable(
284 ) -> DiagnosticBuilder
<'cx
> {
285 let msg
= if is_arg
{
286 "to immutable argument"
288 "twice to immutable variable"
294 "cannot assign {} `{}`",
300 crate fn cannot_assign(&self, span
: Span
, desc
: &str) -> DiagnosticBuilder
<'cx
> {
301 struct_span_err
!(self, span
, E0594
, "cannot assign to {}", desc
)
304 crate fn cannot_move_out_of(
306 move_from_span
: Span
,
307 move_from_desc
: &str,
308 ) -> DiagnosticBuilder
<'cx
> {
313 "cannot move out of {}",
318 /// Signal an error due to an attempt to move out of the interior
319 /// of an array or slice. `is_index` is None when error origin
320 /// didn't capture whether there was an indexing operation or not.
321 crate fn cannot_move_out_of_interior_noncopy(
323 move_from_span
: Span
,
325 is_index
: Option
<bool
>,
326 ) -> DiagnosticBuilder
<'cx
> {
327 let type_name
= match (&ty
.sty
, is_index
) {
328 (&ty
::Array(_
, _
), Some(true)) | (&ty
::Array(_
, _
), None
) => "array",
329 (&ty
::Slice(_
), _
) => "slice",
330 _
=> span_bug
!(move_from_span
, "this path should not cause illegal move"),
332 let mut err
= struct_span_err
!(
336 "cannot move out of type `{}`, a non-copy {}",
340 err
.span_label(move_from_span
, "cannot move out of here");
344 crate fn cannot_move_out_of_interior_of_drop(
346 move_from_span
: Span
,
347 container_ty
: Ty
<'_
>,
348 ) -> DiagnosticBuilder
<'cx
> {
349 let mut err
= struct_span_err
!(
353 "cannot move out of type `{}`, which implements the `Drop` trait",
356 err
.span_label(move_from_span
, "cannot move out of here");
360 crate fn cannot_act_on_moved_value(
364 optional_adverb_for_moved
: &str,
365 moved_path
: Option
<String
>,
366 ) -> DiagnosticBuilder
<'cx
> {
367 let moved_path
= moved_path
368 .map(|mp
| format
!(": `{}`", mp
))
369 .unwrap_or_default();
375 "{} of {}moved value{}",
377 optional_adverb_for_moved
,
382 crate fn cannot_borrow_path_as_mutable_because(
387 ) -> DiagnosticBuilder
<'cx
> {
392 "cannot borrow {} as mutable{}",
398 crate fn cannot_mutate_in_match_guard(
404 ) -> DiagnosticBuilder
<'cx
> {
405 let mut err
= struct_span_err
!(
409 "cannot {} `{}` in match guard",
413 err
.span_label(mutate_span
, format
!("cannot {}", action
));
414 err
.span_label(match_span
, String
::from("value is immutable in match guard"));
418 crate fn cannot_borrow_across_generator_yield(
422 ) -> DiagnosticBuilder
<'cx
> {
423 let mut err
= struct_span_err
!(
427 "borrow may still be in use when generator yields",
429 err
.span_label(yield_span
, "possible yield occurs here");
433 crate fn cannot_borrow_across_destructor(
436 ) -> DiagnosticBuilder
<'cx
> {
441 "borrow may still be in use when destructor runs",
445 crate fn path_does_not_live_long_enough(
449 ) -> DiagnosticBuilder
<'cx
> {
454 "{} does not live long enough",
459 crate fn cannot_return_reference_to_local(
463 reference_desc
: &str,
465 ) -> DiagnosticBuilder
<'cx
> {
466 let mut err
= struct_span_err
!(
470 "cannot {RETURN} {REFERENCE} {LOCAL}",
472 REFERENCE
=reference_desc
,
478 format
!("{}s a {} data owned by the current function", return_kind
, reference_desc
),
484 crate fn cannot_capture_in_long_lived_closure(
489 ) -> DiagnosticBuilder
<'cx
> {
490 let mut err
= struct_span_err
!(
494 "closure may outlive the current function, \
496 which is owned by the current function",
499 err
.span_label(capture_span
, format
!("{} is borrowed here", borrowed_path
))
502 format
!("may outlive borrowed value {}", borrowed_path
),
507 crate fn thread_local_value_does_not_live_long_enough(
510 ) -> DiagnosticBuilder
<'cx
> {
515 "thread-local variable borrowed past end of function",
519 crate fn temporary_value_borrowed_for_too_long(
522 ) -> DiagnosticBuilder
<'cx
> {
527 "temporary value dropped while borrowed",
531 fn struct_span_err_with_code
<S
: Into
<MultiSpan
>>(
536 ) -> DiagnosticBuilder
<'tcx
> {
537 self.infcx
.tcx
.sess
.struct_span_err_with_code(sp
, msg
, code
)
541 crate fn borrowed_data_escapes_closure
<'tcx
>(
545 ) -> DiagnosticBuilder
<'tcx
> {
550 "borrowed data escapes outside of {}",