1 use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId};
2 use rustc_middle::ty::{self, Ty, TyCtxt};
3 use rustc_span::{MultiSpan, Span};
4
5 impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
cannot_move_when_borrowed(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx>6 crate fn cannot_move_when_borrowed(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
7 struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,)
8 }
9
cannot_use_when_mutably_borrowed( &self, span: Span, desc: &str, borrow_span: Span, borrow_desc: &str, ) -> DiagnosticBuilder<'cx>10 crate fn cannot_use_when_mutably_borrowed(
11 &self,
12 span: Span,
13 desc: &str,
14 borrow_span: Span,
15 borrow_desc: &str,
16 ) -> DiagnosticBuilder<'cx> {
17 let mut err = struct_span_err!(
18 self,
19 span,
20 E0503,
21 "cannot use {} because it was mutably borrowed",
22 desc,
23 );
24
25 err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_desc));
26 err.span_label(span, format!("use of borrowed {}", borrow_desc));
27 err
28 }
29
cannot_act_on_uninitialized_variable( &self, span: Span, verb: &str, desc: &str, ) -> DiagnosticBuilder<'cx>30 crate fn cannot_act_on_uninitialized_variable(
31 &self,
32 span: Span,
33 verb: &str,
34 desc: &str,
35 ) -> DiagnosticBuilder<'cx> {
36 struct_span_err!(
37 self,
38 span,
39 E0381,
40 "{} of possibly-uninitialized variable: `{}`",
41 verb,
42 desc,
43 )
44 }
45
cannot_mutably_borrow_multiply( &self, new_loan_span: Span, desc: &str, opt_via: &str, old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option<Span>, ) -> DiagnosticBuilder<'cx>46 crate fn cannot_mutably_borrow_multiply(
47 &self,
48 new_loan_span: Span,
49 desc: &str,
50 opt_via: &str,
51 old_loan_span: Span,
52 old_opt_via: &str,
53 old_load_end_span: Option<Span>,
54 ) -> DiagnosticBuilder<'cx> {
55 let via =
56 |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
57 let mut err = struct_span_err!(
58 self,
59 new_loan_span,
60 E0499,
61 "cannot borrow {}{} as mutable more than once at a time",
62 desc,
63 via(opt_via),
64 );
65 if old_loan_span == new_loan_span {
66 // Both borrows are happening in the same place
67 // Meaning the borrow is occurring in a loop
68 err.span_label(
69 new_loan_span,
70 format!(
71 "{}{} was mutably borrowed here in the previous iteration of the loop{}",
72 desc,
73 via(opt_via),
74 opt_via,
75 ),
76 );
77 if let Some(old_load_end_span) = old_load_end_span {
78 err.span_label(old_load_end_span, "mutable borrow ends here");
79 }
80 } else {
81 err.span_label(
82 old_loan_span,
83 format!("first mutable borrow occurs here{}", via(old_opt_via)),
84 );
85 err.span_label(
86 new_loan_span,
87 format!("second mutable borrow occurs here{}", via(opt_via)),
88 );
89 if let Some(old_load_end_span) = old_load_end_span {
90 err.span_label(old_load_end_span, "first borrow ends here");
91 }
92 }
93 err
94 }
95
cannot_uniquely_borrow_by_two_closures( &self, new_loan_span: Span, desc: &str, old_loan_span: Span, old_load_end_span: Option<Span>, ) -> DiagnosticBuilder<'cx>96 crate fn cannot_uniquely_borrow_by_two_closures(
97 &self,
98 new_loan_span: Span,
99 desc: &str,
100 old_loan_span: Span,
101 old_load_end_span: Option<Span>,
102 ) -> DiagnosticBuilder<'cx> {
103 let mut err = struct_span_err!(
104 self,
105 new_loan_span,
106 E0524,
107 "two closures require unique access to {} at the same time",
108 desc,
109 );
110 if old_loan_span == new_loan_span {
111 err.span_label(
112 old_loan_span,
113 "closures are constructed here in different iterations of loop",
114 );
115 } else {
116 err.span_label(old_loan_span, "first closure is constructed here");
117 err.span_label(new_loan_span, "second closure is constructed here");
118 }
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");
121 }
122 err
123 }
124
cannot_uniquely_borrow_by_one_closure( &self, new_loan_span: Span, container_name: &str, desc_new: &str, opt_via: &str, old_loan_span: Span, noun_old: &str, old_opt_via: &str, previous_end_span: Option<Span>, ) -> DiagnosticBuilder<'cx>125 crate fn cannot_uniquely_borrow_by_one_closure(
126 &self,
127 new_loan_span: Span,
128 container_name: &str,
129 desc_new: &str,
130 opt_via: &str,
131 old_loan_span: Span,
132 noun_old: &str,
133 old_opt_via: &str,
134 previous_end_span: Option<Span>,
135 ) -> DiagnosticBuilder<'cx> {
136 let mut err = struct_span_err!(
137 self,
138 new_loan_span,
139 E0500,
140 "closure requires unique access to {} but {} is already borrowed{}",
141 desc_new,
142 noun_old,
143 old_opt_via,
144 );
145 err.span_label(
146 new_loan_span,
147 format!("{} construction occurs here{}", container_name, opt_via),
148 );
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");
152 }
153 err
154 }
155
cannot_reborrow_already_uniquely_borrowed( &self, new_loan_span: Span, container_name: &str, desc_new: &str, opt_via: &str, kind_new: &str, old_loan_span: Span, old_opt_via: &str, previous_end_span: Option<Span>, second_borrow_desc: &str, ) -> DiagnosticBuilder<'cx>156 crate fn cannot_reborrow_already_uniquely_borrowed(
157 &self,
158 new_loan_span: Span,
159 container_name: &str,
160 desc_new: &str,
161 opt_via: &str,
162 kind_new: &str,
163 old_loan_span: Span,
164 old_opt_via: &str,
165 previous_end_span: Option<Span>,
166 second_borrow_desc: &str,
167 ) -> DiagnosticBuilder<'cx> {
168 let mut err = struct_span_err!(
169 self,
170 new_loan_span,
171 E0501,
172 "cannot borrow {}{} as {} because previous closure \
173 requires unique access",
174 desc_new,
175 opt_via,
176 kind_new,
177 );
178 err.span_label(
179 new_loan_span,
180 format!("{}borrow occurs here{}", second_borrow_desc, opt_via),
181 );
182 err.span_label(
183 old_loan_span,
184 format!("{} construction occurs here{}", container_name, old_opt_via),
185 );
186 if let Some(previous_end_span) = previous_end_span {
187 err.span_label(previous_end_span, "borrow from closure ends here");
188 }
189 err
190 }
191
cannot_reborrow_already_borrowed( &self, span: Span, desc_new: &str, msg_new: &str, kind_new: &str, old_span: Span, noun_old: &str, kind_old: &str, msg_old: &str, old_load_end_span: Option<Span>, ) -> DiagnosticBuilder<'cx>192 crate fn cannot_reborrow_already_borrowed(
193 &self,
194 span: Span,
195 desc_new: &str,
196 msg_new: &str,
197 kind_new: &str,
198 old_span: Span,
199 noun_old: &str,
200 kind_old: &str,
201 msg_old: &str,
202 old_load_end_span: Option<Span>,
203 ) -> DiagnosticBuilder<'cx> {
204 let via =
205 |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
206 let mut err = struct_span_err!(
207 self,
208 span,
209 E0502,
210 "cannot borrow {}{} as {} because {} is also borrowed as {}{}",
211 desc_new,
212 via(msg_new),
213 kind_new,
214 noun_old,
215 kind_old,
216 via(msg_old),
217 );
218
219 if msg_new == "" {
220 // If `msg_new` is empty, then this isn't a borrow of a union field.
221 err.span_label(span, format!("{} borrow occurs here", kind_new));
222 err.span_label(old_span, format!("{} borrow occurs here", kind_old));
223 } else {
224 // If `msg_new` isn't empty, then this a borrow of a union field.
225 err.span_label(
226 span,
227 format!(
228 "{} borrow of {} -- which overlaps with {} -- occurs here",
229 kind_new, msg_new, msg_old,
230 ),
231 );
232 err.span_label(old_span, format!("{} borrow occurs here{}", kind_old, via(msg_old)));
233 }
234
235 if let Some(old_load_end_span) = old_load_end_span {
236 err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old));
237 }
238 err
239 }
240
cannot_assign_to_borrowed( &self, span: Span, borrow_span: Span, desc: &str, ) -> DiagnosticBuilder<'cx>241 crate fn cannot_assign_to_borrowed(
242 &self,
243 span: Span,
244 borrow_span: Span,
245 desc: &str,
246 ) -> DiagnosticBuilder<'cx> {
247 let mut err = struct_span_err!(
248 self,
249 span,
250 E0506,
251 "cannot assign to {} because it is borrowed",
252 desc,
253 );
254
255 err.span_label(borrow_span, format!("borrow of {} occurs here", desc));
256 err.span_label(span, format!("assignment to borrowed {} occurs here", desc));
257 err
258 }
259
cannot_reassign_immutable( &self, span: Span, desc: &str, is_arg: bool, ) -> DiagnosticBuilder<'cx>260 crate fn cannot_reassign_immutable(
261 &self,
262 span: Span,
263 desc: &str,
264 is_arg: bool,
265 ) -> DiagnosticBuilder<'cx> {
266 let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
267 struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc)
268 }
269
cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx>270 crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
271 struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
272 }
273
cannot_move_out_of( &self, move_from_span: Span, move_from_desc: &str, ) -> DiagnosticBuilder<'cx>274 crate fn cannot_move_out_of(
275 &self,
276 move_from_span: Span,
277 move_from_desc: &str,
278 ) -> DiagnosticBuilder<'cx> {
279 struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,)
280 }
281
282 /// Signal an error due to an attempt to move out of the interior
283 /// of an array or slice. `is_index` is None when error origin
284 /// didn't capture whether there was an indexing operation or not.
cannot_move_out_of_interior_noncopy( &self, move_from_span: Span, ty: Ty<'_>, is_index: Option<bool>, ) -> DiagnosticBuilder<'cx>285 crate fn cannot_move_out_of_interior_noncopy(
286 &self,
287 move_from_span: Span,
288 ty: Ty<'_>,
289 is_index: Option<bool>,
290 ) -> DiagnosticBuilder<'cx> {
291 let type_name = match (&ty.kind(), is_index) {
292 (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
293 (&ty::Slice(_), _) => "slice",
294 _ => span_bug!(move_from_span, "this path should not cause illegal move"),
295 };
296 let mut err = struct_span_err!(
297 self,
298 move_from_span,
299 E0508,
300 "cannot move out of type `{}`, a non-copy {}",
301 ty,
302 type_name,
303 );
304 err.span_label(move_from_span, "cannot move out of here");
305 err
306 }
307
cannot_move_out_of_interior_of_drop( &self, move_from_span: Span, container_ty: Ty<'_>, ) -> DiagnosticBuilder<'cx>308 crate fn cannot_move_out_of_interior_of_drop(
309 &self,
310 move_from_span: Span,
311 container_ty: Ty<'_>,
312 ) -> DiagnosticBuilder<'cx> {
313 let mut err = struct_span_err!(
314 self,
315 move_from_span,
316 E0509,
317 "cannot move out of type `{}`, which implements the `Drop` trait",
318 container_ty,
319 );
320 err.span_label(move_from_span, "cannot move out of here");
321 err
322 }
323
cannot_act_on_moved_value( &self, use_span: Span, verb: &str, optional_adverb_for_moved: &str, moved_path: Option<String>, ) -> DiagnosticBuilder<'cx>324 crate fn cannot_act_on_moved_value(
325 &self,
326 use_span: Span,
327 verb: &str,
328 optional_adverb_for_moved: &str,
329 moved_path: Option<String>,
330 ) -> DiagnosticBuilder<'cx> {
331 let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default();
332
333 struct_span_err!(
334 self,
335 use_span,
336 E0382,
337 "{} of {}moved value{}",
338 verb,
339 optional_adverb_for_moved,
340 moved_path,
341 )
342 }
343
cannot_borrow_path_as_mutable_because( &self, span: Span, path: &str, reason: &str, ) -> DiagnosticBuilder<'cx>344 crate fn cannot_borrow_path_as_mutable_because(
345 &self,
346 span: Span,
347 path: &str,
348 reason: &str,
349 ) -> DiagnosticBuilder<'cx> {
350 struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
351 }
352
cannot_mutate_in_immutable_section( &self, mutate_span: Span, immutable_span: Span, immutable_place: &str, immutable_section: &str, action: &str, ) -> DiagnosticBuilder<'cx>353 crate fn cannot_mutate_in_immutable_section(
354 &self,
355 mutate_span: Span,
356 immutable_span: Span,
357 immutable_place: &str,
358 immutable_section: &str,
359 action: &str,
360 ) -> DiagnosticBuilder<'cx> {
361 let mut err = struct_span_err!(
362 self,
363 mutate_span,
364 E0510,
365 "cannot {} {} in {}",
366 action,
367 immutable_place,
368 immutable_section,
369 );
370 err.span_label(mutate_span, format!("cannot {}", action));
371 err.span_label(immutable_span, format!("value is immutable in {}", immutable_section));
372 err
373 }
374
cannot_borrow_across_generator_yield( &self, span: Span, yield_span: Span, ) -> DiagnosticBuilder<'cx>375 crate fn cannot_borrow_across_generator_yield(
376 &self,
377 span: Span,
378 yield_span: Span,
379 ) -> DiagnosticBuilder<'cx> {
380 let mut err = struct_span_err!(
381 self,
382 span,
383 E0626,
384 "borrow may still be in use when generator yields",
385 );
386 err.span_label(yield_span, "possible yield occurs here");
387 err
388 }
389
cannot_borrow_across_destructor(&self, borrow_span: Span) -> DiagnosticBuilder<'cx>390 crate fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> DiagnosticBuilder<'cx> {
391 struct_span_err!(
392 self,
393 borrow_span,
394 E0713,
395 "borrow may still be in use when destructor runs",
396 )
397 }
398
path_does_not_live_long_enough( &self, span: Span, path: &str, ) -> DiagnosticBuilder<'cx>399 crate fn path_does_not_live_long_enough(
400 &self,
401 span: Span,
402 path: &str,
403 ) -> DiagnosticBuilder<'cx> {
404 struct_span_err!(self, span, E0597, "{} does not live long enough", path,)
405 }
406
cannot_return_reference_to_local( &self, span: Span, return_kind: &str, reference_desc: &str, path_desc: &str, ) -> DiagnosticBuilder<'cx>407 crate fn cannot_return_reference_to_local(
408 &self,
409 span: Span,
410 return_kind: &str,
411 reference_desc: &str,
412 path_desc: &str,
413 ) -> DiagnosticBuilder<'cx> {
414 let mut err = struct_span_err!(
415 self,
416 span,
417 E0515,
418 "cannot {RETURN} {REFERENCE} {LOCAL}",
419 RETURN = return_kind,
420 REFERENCE = reference_desc,
421 LOCAL = path_desc,
422 );
423
424 err.span_label(
425 span,
426 format!("{}s a {} data owned by the current function", return_kind, reference_desc),
427 );
428
429 err
430 }
431
cannot_capture_in_long_lived_closure( &self, closure_span: Span, closure_kind: &str, borrowed_path: &str, capture_span: Span, ) -> DiagnosticBuilder<'cx>432 crate fn cannot_capture_in_long_lived_closure(
433 &self,
434 closure_span: Span,
435 closure_kind: &str,
436 borrowed_path: &str,
437 capture_span: Span,
438 ) -> DiagnosticBuilder<'cx> {
439 let mut err = struct_span_err!(
440 self,
441 closure_span,
442 E0373,
443 "{} may outlive the current function, \
444 but it borrows {}, \
445 which is owned by the current function",
446 closure_kind,
447 borrowed_path,
448 );
449 err.span_label(capture_span, format!("{} is borrowed here", borrowed_path))
450 .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path));
451 err
452 }
453
thread_local_value_does_not_live_long_enough( &self, span: Span, ) -> DiagnosticBuilder<'cx>454 crate fn thread_local_value_does_not_live_long_enough(
455 &self,
456 span: Span,
457 ) -> DiagnosticBuilder<'cx> {
458 struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",)
459 }
460
temporary_value_borrowed_for_too_long(&self, span: Span) -> DiagnosticBuilder<'cx>461 crate fn temporary_value_borrowed_for_too_long(&self, span: Span) -> DiagnosticBuilder<'cx> {
462 struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
463 }
464
struct_span_err_with_code<S: Into<MultiSpan>>( &self, sp: S, msg: &str, code: DiagnosticId, ) -> DiagnosticBuilder<'tcx>465 fn struct_span_err_with_code<S: Into<MultiSpan>>(
466 &self,
467 sp: S,
468 msg: &str,
469 code: DiagnosticId,
470 ) -> DiagnosticBuilder<'tcx> {
471 self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code)
472 }
473 }
474
borrowed_data_escapes_closure<'tcx>( tcx: TyCtxt<'tcx>, escape_span: Span, escapes_from: &str, ) -> DiagnosticBuilder<'tcx>475 crate fn borrowed_data_escapes_closure<'tcx>(
476 tcx: TyCtxt<'tcx>,
477 escape_span: Span,
478 escapes_from: &str,
479 ) -> DiagnosticBuilder<'tcx> {
480 struct_span_err!(
481 tcx.sess,
482 escape_span,
483 E0521,
484 "borrowed data escapes outside of {}",
485 escapes_from,
486 )
487 }
488