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