]>
Commit | Line | Data |
---|---|---|
1 | // Copyright 2017 The Rust Project Developers. See the COPYRIGHT | |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | use infer::{self, InferCtxt, SubregionOrigin}; | |
12 | use middle::region; | |
13 | use ty::{self, Region}; | |
14 | use ty::error::TypeError; | |
15 | use errors::DiagnosticBuilder; | |
16 | ||
17 | impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { | |
18 | pub(super) fn note_region_origin(&self, | |
19 | err: &mut DiagnosticBuilder, | |
20 | origin: &SubregionOrigin<'tcx>) { | |
21 | match *origin { | |
22 | infer::Subtype(ref trace) => { | |
23 | if let Some((expected, found)) = self.values_str(&trace.values) { | |
24 | let expected = expected.content(); | |
25 | let found = found.content(); | |
26 | // FIXME: do we want a "the" here? | |
27 | err.span_note(trace.cause.span, | |
28 | &format!("...so that {} (expected {}, found {})", | |
29 | trace.cause.as_requirement_str(), | |
30 | expected, | |
31 | found)); | |
32 | } else { | |
33 | // FIXME: this really should be handled at some earlier stage. Our | |
34 | // handling of region checking when type errors are present is | |
35 | // *terrible*. | |
36 | ||
37 | err.span_note(trace.cause.span, | |
38 | &format!("...so that {}", trace.cause.as_requirement_str())); | |
39 | } | |
40 | } | |
41 | infer::Reborrow(span) => { | |
42 | err.span_note(span, | |
43 | "...so that reference does not outlive borrowed content"); | |
44 | } | |
45 | infer::ReborrowUpvar(span, ref upvar_id) => { | |
46 | let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); | |
47 | let var_name = self.tcx.hir.name(var_node_id); | |
48 | err.span_note(span, | |
49 | &format!("...so that closure can access `{}`", var_name)); | |
50 | } | |
51 | infer::InfStackClosure(span) => { | |
52 | err.span_note(span, "...so that closure does not outlive its stack frame"); | |
53 | } | |
54 | infer::InvokeClosure(span) => { | |
55 | err.span_note(span, | |
56 | "...so that closure is not invoked outside its lifetime"); | |
57 | } | |
58 | infer::DerefPointer(span) => { | |
59 | err.span_note(span, | |
60 | "...so that pointer is not dereferenced outside its lifetime"); | |
61 | } | |
62 | infer::FreeVariable(span, id) => { | |
63 | err.span_note(span, | |
64 | &format!("...so that captured variable `{}` does not outlive the \ | |
65 | enclosing closure", | |
66 | self.tcx.hir.name(id))); | |
67 | } | |
68 | infer::IndexSlice(span) => { | |
69 | err.span_note(span, "...so that slice is not indexed outside the lifetime"); | |
70 | } | |
71 | infer::RelateObjectBound(span) => { | |
72 | err.span_note(span, "...so that it can be closed over into an object"); | |
73 | } | |
74 | infer::CallRcvr(span) => { | |
75 | err.span_note(span, | |
76 | "...so that method receiver is valid for the method call"); | |
77 | } | |
78 | infer::CallArg(span) => { | |
79 | err.span_note(span, "...so that argument is valid for the call"); | |
80 | } | |
81 | infer::CallReturn(span) => { | |
82 | err.span_note(span, "...so that return value is valid for the call"); | |
83 | } | |
84 | infer::Operand(span) => { | |
85 | err.span_note(span, "...so that operand is valid for operation"); | |
86 | } | |
87 | infer::AddrOf(span) => { | |
88 | err.span_note(span, "...so that reference is valid at the time of borrow"); | |
89 | } | |
90 | infer::AutoBorrow(span) => { | |
91 | err.span_note(span, | |
92 | "...so that auto-reference is valid at the time of borrow"); | |
93 | } | |
94 | infer::ExprTypeIsNotInScope(t, span) => { | |
95 | err.span_note(span, | |
96 | &format!("...so type `{}` of expression is valid during the \ | |
97 | expression", | |
98 | self.ty_to_string(t))); | |
99 | } | |
100 | infer::BindingTypeIsNotValidAtDecl(span) => { | |
101 | err.span_note(span, | |
102 | "...so that variable is valid at time of its declaration"); | |
103 | } | |
104 | infer::ParameterInScope(_, span) => { | |
105 | err.span_note(span, | |
106 | "...so that a type/lifetime parameter is in scope here"); | |
107 | } | |
108 | infer::DataBorrowed(ty, span) => { | |
109 | err.span_note(span, | |
110 | &format!("...so that the type `{}` is not borrowed for too long", | |
111 | self.ty_to_string(ty))); | |
112 | } | |
113 | infer::ReferenceOutlivesReferent(ty, span) => { | |
114 | err.span_note(span, | |
115 | &format!("...so that the reference type `{}` does not outlive the \ | |
116 | data it points at", | |
117 | self.ty_to_string(ty))); | |
118 | } | |
119 | infer::RelateParamBound(span, t) => { | |
120 | err.span_note(span, | |
121 | &format!("...so that the type `{}` will meet its required \ | |
122 | lifetime bounds", | |
123 | self.ty_to_string(t))); | |
124 | } | |
125 | infer::RelateDefaultParamBound(span, t) => { | |
126 | err.span_note(span, | |
127 | &format!("...so that type parameter instantiated with `{}`, will \ | |
128 | meet its declared lifetime bounds", | |
129 | self.ty_to_string(t))); | |
130 | } | |
131 | infer::RelateRegionParamBound(span) => { | |
132 | err.span_note(span, | |
133 | "...so that the declared lifetime parameter bounds are satisfied"); | |
134 | } | |
135 | infer::SafeDestructor(span) => { | |
136 | err.span_note(span, | |
137 | "...so that references are valid when the destructor runs"); | |
138 | } | |
139 | infer::CompareImplMethodObligation { span, .. } => { | |
140 | err.span_note(span, | |
141 | "...so that the definition in impl matches the definition from the \ | |
142 | trait"); | |
143 | } | |
144 | } | |
145 | } | |
146 | ||
147 | pub(super) fn report_concrete_failure(&self, | |
148 | region_scope_tree: ®ion::ScopeTree, | |
149 | origin: SubregionOrigin<'tcx>, | |
150 | sub: Region<'tcx>, | |
151 | sup: Region<'tcx>) | |
152 | -> DiagnosticBuilder<'tcx> { | |
153 | match origin { | |
154 | infer::Subtype(trace) => { | |
155 | let terr = TypeError::RegionsDoesNotOutlive(sup, sub); | |
156 | let mut err = self.report_and_explain_type_error(trace, &terr); | |
157 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, "", sup, "..."); | |
158 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
159 | "...does not necessarily outlive ", sub, ""); | |
160 | err | |
161 | } | |
162 | infer::Reborrow(span) => { | |
163 | let mut err = struct_span_err!(self.tcx.sess, | |
164 | span, | |
165 | E0312, | |
166 | "lifetime of reference outlives lifetime of \ | |
167 | borrowed content..."); | |
168 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
169 | "...the reference is valid for ", | |
170 | sub, | |
171 | "..."); | |
172 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
173 | "...but the borrowed content is only valid for ", | |
174 | sup, | |
175 | ""); | |
176 | err | |
177 | } | |
178 | infer::ReborrowUpvar(span, ref upvar_id) => { | |
179 | let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); | |
180 | let var_name = self.tcx.hir.name(var_node_id); | |
181 | let mut err = struct_span_err!(self.tcx.sess, | |
182 | span, | |
183 | E0313, | |
184 | "lifetime of borrowed pointer outlives lifetime \ | |
185 | of captured variable `{}`...", | |
186 | var_name); | |
187 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
188 | "...the borrowed pointer is valid for ", | |
189 | sub, | |
190 | "..."); | |
191 | self.tcx.note_and_explain_region( | |
192 | region_scope_tree, | |
193 | &mut err, | |
194 | &format!("...but `{}` is only valid for ", var_name), | |
195 | sup, | |
196 | ""); | |
197 | err | |
198 | } | |
199 | infer::InfStackClosure(span) => { | |
200 | let mut err = | |
201 | struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame"); | |
202 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
203 | "...the closure must be valid for ", | |
204 | sub, | |
205 | "..."); | |
206 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
207 | "...but the closure's stack frame is only valid \ | |
208 | for ", | |
209 | sup, | |
210 | ""); | |
211 | err | |
212 | } | |
213 | infer::InvokeClosure(span) => { | |
214 | let mut err = struct_span_err!(self.tcx.sess, | |
215 | span, | |
216 | E0315, | |
217 | "cannot invoke closure outside of its lifetime"); | |
218 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
219 | "the closure is only valid for ", sup, ""); | |
220 | err | |
221 | } | |
222 | infer::DerefPointer(span) => { | |
223 | let mut err = struct_span_err!(self.tcx.sess, | |
224 | span, | |
225 | E0473, | |
226 | "dereference of reference outside its lifetime"); | |
227 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
228 | "the reference is only valid for ", sup, ""); | |
229 | err | |
230 | } | |
231 | infer::FreeVariable(span, id) => { | |
232 | let mut err = struct_span_err!(self.tcx.sess, | |
233 | span, | |
234 | E0474, | |
235 | "captured variable `{}` does not outlive the \ | |
236 | enclosing closure", | |
237 | self.tcx.hir.name(id)); | |
238 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
239 | "captured variable is valid for ", sup, ""); | |
240 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
241 | "closure is valid for ", sub, ""); | |
242 | err | |
243 | } | |
244 | infer::IndexSlice(span) => { | |
245 | let mut err = struct_span_err!(self.tcx.sess, | |
246 | span, | |
247 | E0475, | |
248 | "index of slice outside its lifetime"); | |
249 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
250 | "the slice is only valid for ", sup, ""); | |
251 | err | |
252 | } | |
253 | infer::RelateObjectBound(span) => { | |
254 | let mut err = struct_span_err!(self.tcx.sess, | |
255 | span, | |
256 | E0476, | |
257 | "lifetime of the source pointer does not outlive \ | |
258 | lifetime bound of the object type"); | |
259 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
260 | "object type is valid for ", sub, ""); | |
261 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
262 | "source pointer is only valid for ", | |
263 | sup, | |
264 | ""); | |
265 | err | |
266 | } | |
267 | infer::RelateParamBound(span, ty) => { | |
268 | let mut err = struct_span_err!(self.tcx.sess, | |
269 | span, | |
270 | E0477, | |
271 | "the type `{}` does not fulfill the required \ | |
272 | lifetime", | |
273 | self.ty_to_string(ty)); | |
274 | match *sub { | |
275 | ty::ReStatic => { | |
276 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
277 | "type must satisfy ", sub, "") | |
278 | } | |
279 | _ => { | |
280 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
281 | "type must outlive ", sub, "") | |
282 | } | |
283 | } | |
284 | err | |
285 | } | |
286 | infer::RelateRegionParamBound(span) => { | |
287 | let mut err = | |
288 | struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); | |
289 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
290 | "lifetime parameter instantiated with ", | |
291 | sup, | |
292 | ""); | |
293 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
294 | "but lifetime parameter must outlive ", | |
295 | sub, | |
296 | ""); | |
297 | err | |
298 | } | |
299 | infer::RelateDefaultParamBound(span, ty) => { | |
300 | let mut err = struct_span_err!(self.tcx.sess, | |
301 | span, | |
302 | E0479, | |
303 | "the type `{}` (provided as the value of a type \ | |
304 | parameter) is not valid at this point", | |
305 | self.ty_to_string(ty)); | |
306 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
307 | "type must outlive ", sub, ""); | |
308 | err | |
309 | } | |
310 | infer::CallRcvr(span) => { | |
311 | let mut err = struct_span_err!(self.tcx.sess, | |
312 | span, | |
313 | E0480, | |
314 | "lifetime of method receiver does not outlive the \ | |
315 | method call"); | |
316 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
317 | "the receiver is only valid for ", sup, ""); | |
318 | err | |
319 | } | |
320 | infer::CallArg(span) => { | |
321 | let mut err = struct_span_err!(self.tcx.sess, | |
322 | span, | |
323 | E0481, | |
324 | "lifetime of function argument does not outlive \ | |
325 | the function call"); | |
326 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
327 | "the function argument is only valid for ", | |
328 | sup, | |
329 | ""); | |
330 | err | |
331 | } | |
332 | infer::CallReturn(span) => { | |
333 | let mut err = struct_span_err!(self.tcx.sess, | |
334 | span, | |
335 | E0482, | |
336 | "lifetime of return value does not outlive the \ | |
337 | function call"); | |
338 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
339 | "the return value is only valid for ", | |
340 | sup, | |
341 | ""); | |
342 | err | |
343 | } | |
344 | infer::Operand(span) => { | |
345 | let mut err = struct_span_err!(self.tcx.sess, | |
346 | span, | |
347 | E0483, | |
348 | "lifetime of operand does not outlive the \ | |
349 | operation"); | |
350 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
351 | "the operand is only valid for ", sup, ""); | |
352 | err | |
353 | } | |
354 | infer::AddrOf(span) => { | |
355 | let mut err = struct_span_err!(self.tcx.sess, | |
356 | span, | |
357 | E0484, | |
358 | "reference is not valid at the time of borrow"); | |
359 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
360 | "the borrow is only valid for ", sup, ""); | |
361 | err | |
362 | } | |
363 | infer::AutoBorrow(span) => { | |
364 | let mut err = struct_span_err!(self.tcx.sess, | |
365 | span, | |
366 | E0485, | |
367 | "automatically reference is not valid at the time \ | |
368 | of borrow"); | |
369 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
370 | "the automatic borrow is only valid for ", | |
371 | sup, | |
372 | ""); | |
373 | err | |
374 | } | |
375 | infer::ExprTypeIsNotInScope(t, span) => { | |
376 | let mut err = struct_span_err!(self.tcx.sess, | |
377 | span, | |
378 | E0486, | |
379 | "type of expression contains references that are \ | |
380 | not valid during the expression: `{}`", | |
381 | self.ty_to_string(t)); | |
382 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
383 | "type is only valid for ", sup, ""); | |
384 | err | |
385 | } | |
386 | infer::SafeDestructor(span) => { | |
387 | let mut err = struct_span_err!(self.tcx.sess, | |
388 | span, | |
389 | E0487, | |
390 | "unsafe use of destructor: destructor might be \ | |
391 | called while references are dead"); | |
392 | // FIXME (22171): terms "super/subregion" are suboptimal | |
393 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
394 | "superregion: ", sup, ""); | |
395 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
396 | "subregion: ", sub, ""); | |
397 | err | |
398 | } | |
399 | infer::BindingTypeIsNotValidAtDecl(span) => { | |
400 | let mut err = struct_span_err!(self.tcx.sess, | |
401 | span, | |
402 | E0488, | |
403 | "lifetime of variable does not enclose its \ | |
404 | declaration"); | |
405 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
406 | "the variable is only valid for ", sup, ""); | |
407 | err | |
408 | } | |
409 | infer::ParameterInScope(_, span) => { | |
410 | let mut err = struct_span_err!(self.tcx.sess, | |
411 | span, | |
412 | E0489, | |
413 | "type/lifetime parameter not in scope here"); | |
414 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
415 | "the parameter is only valid for ", sub, ""); | |
416 | err | |
417 | } | |
418 | infer::DataBorrowed(ty, span) => { | |
419 | let mut err = struct_span_err!(self.tcx.sess, | |
420 | span, | |
421 | E0490, | |
422 | "a value of type `{}` is borrowed for too long", | |
423 | self.ty_to_string(ty)); | |
424 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
425 | "the type is valid for ", sub, ""); | |
426 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
427 | "but the borrow lasts for ", sup, ""); | |
428 | err | |
429 | } | |
430 | infer::ReferenceOutlivesReferent(ty, span) => { | |
431 | let mut err = struct_span_err!(self.tcx.sess, | |
432 | span, | |
433 | E0491, | |
434 | "in type `{}`, reference has a longer lifetime \ | |
435 | than the data it references", | |
436 | self.ty_to_string(ty)); | |
437 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
438 | "the pointer is valid for ", sub, ""); | |
439 | self.tcx.note_and_explain_region(region_scope_tree, &mut err, | |
440 | "but the referenced data is only valid for ", | |
441 | sup, | |
442 | ""); | |
443 | err | |
444 | } | |
445 | infer::CompareImplMethodObligation { span, | |
446 | item_name, | |
447 | impl_item_def_id, | |
448 | trait_item_def_id, | |
449 | lint_id } => { | |
450 | self.report_extra_impl_obligation(span, | |
451 | item_name, | |
452 | impl_item_def_id, | |
453 | trait_item_def_id, | |
454 | &format!("`{}: {}`", sup, sub), | |
455 | lint_id) | |
456 | } | |
457 | } | |
458 | } | |
459 | } |