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(
15 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
16 self.infcx
.tcx
.sess
.create_err(crate::session_diagnostics
::MoveBorrow
{
25 pub(crate) fn cannot_use_when_mutably_borrowed(
31 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
32 let mut err
= struct_span_err
!(
36 "cannot use {} because it was mutably borrowed",
40 err
.span_label(borrow_span
, format
!("{} is borrowed here", borrow_desc
));
41 err
.span_label(span
, format
!("use of borrowed {}", borrow_desc
));
45 pub(crate) fn cannot_mutably_borrow_multiply(
52 old_load_end_span
: Option
<Span
>,
53 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
55 |msg
: &str| if msg
.is_empty() { "".to_string() }
else { format!(" (via {}
)", msg) };
56 let mut err = struct_span_err!(
60 "cannot borrow {}{}
as mutable more than once at a time
",
64 if old_loan_span == new_loan_span {
65 // Both borrows are happening in the same place
66 // Meaning the borrow is occurring in a loop
70 "{}{} was mutably borrowed here
in the previous iteration of the
loop{}
",
76 if let Some(old_load_end_span) = old_load_end_span {
77 err.span_label(old_load_end_span, "mutable borrow ends here
");
82 format!("first mutable borrow occurs here{}
", via(old_opt_via)),
86 format!("second mutable borrow occurs here{}
", via(opt_via)),
88 if let Some(old_load_end_span) = old_load_end_span {
89 err.span_label(old_load_end_span, "first borrow ends here
");
95 pub(crate) fn cannot_uniquely_borrow_by_two_closures(
100 old_load_end_span: Option<Span>,
101 ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
102 let mut err = struct_span_err!(
106 "two closures require unique access to {} at the same time
",
109 if old_loan_span == new_loan_span {
112 "closures are constructed here
in different iterations of
loop",
115 err.span_label(old_loan_span, "first closure is constructed here
");
116 err.span_label(new_loan_span, "second closure is constructed here
");
118 if let Some(old_load_end_span) = old_load_end_span {
119 err.span_label(old_load_end_span, "borrow from first closure ends here
");
124 pub(crate) fn cannot_uniquely_borrow_by_one_closure(
127 container_name: &str,
133 previous_end_span: Option<Span>,
134 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
135 let mut err = struct_span_err!(
139 "closure requires unique access to {} but {} is already borrowed{}
",
146 format!("{} construction occurs here{}
", container_name, opt_via),
148 err.span_label(old_loan_span, format!("borrow occurs here{}
", old_opt_via));
149 if let Some(previous_end_span) = previous_end_span {
150 err.span_label(previous_end_span, "borrow ends here
");
155 pub(crate) fn cannot_reborrow_already_uniquely_borrowed(
158 container_name: &str,
164 previous_end_span: Option<Span>,
165 second_borrow_desc: &str,
166 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
167 let mut err = struct_span_err!(
171 "cannot borrow {}{}
as {} because previous closure requires unique access
",
178 format!("{}borrow occurs here{}
", second_borrow_desc, opt_via),
182 format!("{} construction occurs here{}
", container_name, old_opt_via),
184 if let Some(previous_end_span) = previous_end_span {
185 err.span_label(previous_end_span, "borrow from closure ends here
");
190 pub(crate) fn cannot_reborrow_already_borrowed(
200 old_load_end_span: Option<Span>,
201 ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
203 |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg
) };
204 let mut err
= struct_span_err
!(
208 "cannot borrow {}{} as {} because {} is also borrowed as {}{}",
218 // If `msg_new` is empty, then this isn't a borrow of a union field.
219 err
.span_label(span
, format
!("{} borrow occurs here", kind_new
));
220 err
.span_label(old_span
, format
!("{} borrow occurs here", kind_old
));
222 // If `msg_new` isn't empty, then this a borrow of a union field.
226 "{} borrow of {} -- which overlaps with {} -- occurs here",
227 kind_new
, msg_new
, msg_old
,
230 err
.span_label(old_span
, format
!("{} borrow occurs here{}", kind_old
, via(msg_old
)));
233 if let Some(old_load_end_span
) = old_load_end_span
{
234 err
.span_label(old_load_end_span
, format
!("{} borrow ends here", kind_old
));
239 pub(crate) fn cannot_assign_to_borrowed(
244 ) -> DiagnosticBuilder
<'cx
, ErrorGuaranteed
> {
245 let mut err
= struct_span_err
!(
249 "cannot assign to {} because it is borrowed",
253 err
.span_label(borrow_span
, format
!("{} is borrowed here", desc
));
254 err
.span_label(span
, format
!("{} is assigned to here but it was already borrowed", desc
));
258 pub(crate) fn cannot_reassign_immutable(
263 ) -> DiagnosticBuilder
<'cx
, ErrorGuaranteed
> {
264 let msg
= if is_arg { "to immutable argument" }
else { "twice to immutable variable" }
;
265 struct_span_err
!(self, span
, E0384
, "cannot assign {} {}", msg
, desc
)
268 pub(crate) fn cannot_assign(
272 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
273 struct_span_err
!(self, span
, E0594
, "cannot assign to {}", desc
)
276 pub(crate) fn cannot_move_out_of(
278 move_from_span
: Span
,
279 move_from_desc
: &str,
280 ) -> DiagnosticBuilder
<'cx
, ErrorGuaranteed
> {
281 struct_span_err
!(self, move_from_span
, E0507
, "cannot move out of {}", move_from_desc
)
284 /// Signal an error due to an attempt to move out of the interior
285 /// of an array or slice. `is_index` is None when error origin
286 /// didn't capture whether there was an indexing operation or not.
287 pub(crate) fn cannot_move_out_of_interior_noncopy(
289 move_from_span
: Span
,
291 is_index
: Option
<bool
>,
292 ) -> DiagnosticBuilder
<'cx
, ErrorGuaranteed
> {
293 let type_name
= match (&ty
.kind(), is_index
) {
294 (&ty
::Array(_
, _
), Some(true)) | (&ty
::Array(_
, _
), None
) => "array",
295 (&ty
::Slice(_
), _
) => "slice",
296 _
=> span_bug
!(move_from_span
, "this path should not cause illegal move"),
298 let mut err
= struct_span_err
!(
302 "cannot move out of type `{}`, a non-copy {}",
306 err
.span_label(move_from_span
, "cannot move out of here");
310 pub(crate) fn cannot_move_out_of_interior_of_drop(
312 move_from_span
: Span
,
313 container_ty
: Ty
<'_
>,
314 ) -> DiagnosticBuilder
<'cx
, ErrorGuaranteed
> {
315 let mut err
= struct_span_err
!(
319 "cannot move out of type `{}`, which implements the `Drop` trait",
322 err
.span_label(move_from_span
, "cannot move out of here");
326 pub(crate) fn cannot_act_on_moved_value(
330 optional_adverb_for_moved
: &str,
331 moved_path
: Option
<String
>,
332 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
333 let moved_path
= moved_path
.map(|mp
| format
!(": `{}`", mp
)).unwrap_or_default();
339 "{} of {}moved value{}",
341 optional_adverb_for_moved
,
346 pub(crate) fn cannot_borrow_path_as_mutable_because(
351 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
352 struct_span_err
!(self, span
, E0596
, "cannot borrow {} as mutable{}", path
, reason
,)
355 pub(crate) fn cannot_mutate_in_immutable_section(
358 immutable_span
: Span
,
359 immutable_place
: &str,
360 immutable_section
: &str,
362 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
363 let mut err
= struct_span_err
!(
367 "cannot {} {} in {}",
372 err
.span_label(mutate_span
, format
!("cannot {}", action
));
373 err
.span_label(immutable_span
, format
!("value is immutable in {}", immutable_section
));
377 pub(crate) fn cannot_borrow_across_generator_yield(
381 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
382 let mut err
= struct_span_err
!(
386 "borrow may still be in use when generator yields",
388 err
.span_label(yield_span
, "possible yield occurs here");
392 pub(crate) fn cannot_borrow_across_destructor(
395 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
400 "borrow may still be in use when destructor runs",
404 pub(crate) fn path_does_not_live_long_enough(
408 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
409 struct_span_err
!(self, span
, E0597
, "{} does not live long enough", path
,)
412 pub(crate) fn cannot_return_reference_to_local(
416 reference_desc
: &str,
418 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
419 let mut err
= struct_span_err
!(
423 "cannot {RETURN} {REFERENCE} {LOCAL}",
424 RETURN
= return_kind
,
425 REFERENCE
= reference_desc
,
431 format
!("{}s a {} data owned by the current function", return_kind
, reference_desc
),
437 pub(crate) fn cannot_capture_in_long_lived_closure(
444 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
445 let mut err
= struct_span_err
!(
449 "{closure_kind} may outlive the current {scope}, but it borrows {borrowed_path}, \
450 which is owned by the current {scope}",
452 err
.span_label(capture_span
, format
!("{} is borrowed here", borrowed_path
))
453 .span_label(closure_span
, format
!("may outlive borrowed value {}", borrowed_path
));
457 pub(crate) fn thread_local_value_does_not_live_long_enough(
460 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
461 struct_span_err
!(self, span
, E0712
, "thread-local variable borrowed past end of function",)
464 pub(crate) fn temporary_value_borrowed_for_too_long(
467 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
468 struct_span_err
!(self, span
, E0716
, "temporary value dropped while borrowed",)
471 #[rustc_lint_diagnostics]
473 pub(crate) fn struct_span_err_with_code
<S
: Into
<MultiSpan
>>(
476 msg
: impl Into
<DiagnosticMessage
>,
478 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
479 self.infcx
.tcx
.sess
.struct_span_err_with_code(sp
, msg
, code
)
483 pub(crate) fn borrowed_data_escapes_closure
<'tcx
>(
487 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
492 "borrowed data escapes outside of {}",