]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_borrowck/src/borrowck_errors.rs
Rollup merge of #95909 - vacuus:theme-build-rule, r=GuillaumeGomez
[rust.git] / compiler / rustc_borrowck / src / borrowck_errors.rs
1 use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed, MultiSpan};
2 use rustc_middle::ty::{self, Ty, TyCtxt};
3 use rustc_span::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 }