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