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