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