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.
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.
11 use infer
::{self, InferCtxt, SubregionOrigin}
;
13 use ty
::{self, Region}
;
14 use ty
::error
::TypeError
;
15 use errors
::DiagnosticBuilder
;
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
>) {
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 err
.note(&format
!("...so that the {}:\nexpected {}\n found {}",
27 trace
.cause
.as_requirement_str(),
31 // FIXME: this really should be handled at some earlier stage. Our
32 // handling of region checking when type errors are present is
35 err
.span_note(trace
.cause
.span
,
36 &format
!("...so that {}", trace
.cause
.as_requirement_str()));
39 infer
::Reborrow(span
) => {
41 "...so that reference does not outlive borrowed content");
43 infer
::ReborrowUpvar(span
, ref upvar_id
) => {
44 let var_node_id
= self.tcx
.hir
.hir_to_node_id(upvar_id
.var_id
);
45 let var_name
= self.tcx
.hir
.name(var_node_id
);
47 &format
!("...so that closure can access `{}`", var_name
));
49 infer
::InfStackClosure(span
) => {
50 err
.span_note(span
, "...so that closure does not outlive its stack frame");
52 infer
::InvokeClosure(span
) => {
54 "...so that closure is not invoked outside its lifetime");
56 infer
::DerefPointer(span
) => {
58 "...so that pointer is not dereferenced outside its lifetime");
60 infer
::FreeVariable(span
, id
) => {
62 &format
!("...so that captured variable `{}` does not outlive the \
64 self.tcx
.hir
.name(id
)));
66 infer
::IndexSlice(span
) => {
67 err
.span_note(span
, "...so that slice is not indexed outside the lifetime");
69 infer
::RelateObjectBound(span
) => {
70 err
.span_note(span
, "...so that it can be closed over into an object");
72 infer
::CallRcvr(span
) => {
74 "...so that method receiver is valid for the method call");
76 infer
::CallArg(span
) => {
77 err
.span_note(span
, "...so that argument is valid for the call");
79 infer
::CallReturn(span
) => {
80 err
.span_note(span
, "...so that return value is valid for the call");
82 infer
::Operand(span
) => {
83 err
.span_note(span
, "...so that operand is valid for operation");
85 infer
::AddrOf(span
) => {
86 err
.span_note(span
, "...so that reference is valid at the time of borrow");
88 infer
::AutoBorrow(span
) => {
90 "...so that auto-reference is valid at the time of borrow");
92 infer
::ExprTypeIsNotInScope(t
, span
) => {
94 &format
!("...so type `{}` of expression is valid during the \
96 self.ty_to_string(t
)));
98 infer
::BindingTypeIsNotValidAtDecl(span
) => {
100 "...so that variable is valid at time of its declaration");
102 infer
::ParameterInScope(_
, span
) => {
104 "...so that a type/lifetime parameter is in scope here");
106 infer
::DataBorrowed(ty
, span
) => {
108 &format
!("...so that the type `{}` is not borrowed for too long",
109 self.ty_to_string(ty
)));
111 infer
::ReferenceOutlivesReferent(ty
, span
) => {
113 &format
!("...so that the reference type `{}` does not outlive the \
115 self.ty_to_string(ty
)));
117 infer
::RelateParamBound(span
, t
) => {
119 &format
!("...so that the type `{}` will meet its required \
121 self.ty_to_string(t
)));
123 infer
::RelateDefaultParamBound(span
, t
) => {
125 &format
!("...so that type parameter instantiated with `{}`, will \
126 meet its declared lifetime bounds",
127 self.ty_to_string(t
)));
129 infer
::RelateRegionParamBound(span
) => {
131 "...so that the declared lifetime parameter bounds are satisfied");
133 infer
::SafeDestructor(span
) => {
135 "...so that references are valid when the destructor runs");
137 infer
::CompareImplMethodObligation { span, .. }
=> {
139 "...so that the definition in impl matches the definition from the \
145 pub(super) fn report_concrete_failure(&self,
146 region_scope_tree
: ®ion
::ScopeTree
,
147 origin
: SubregionOrigin
<'tcx
>,
150 -> DiagnosticBuilder
<'tcx
> {
152 infer
::Subtype(trace
) => {
153 let terr
= TypeError
::RegionsDoesNotOutlive(sup
, sub
);
154 let mut err
= self.report_and_explain_type_error(trace
, &terr
);
155 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
, "", sup
, "...");
156 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
157 "...does not necessarily outlive ", sub
, "");
160 infer
::Reborrow(span
) => {
161 let mut err
= struct_span_err
!(self.tcx
.sess
,
164 "lifetime of reference outlives lifetime of \
165 borrowed content...");
166 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
167 "...the reference is valid for ",
170 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
171 "...but the borrowed content is only valid for ",
176 infer
::ReborrowUpvar(span
, ref upvar_id
) => {
177 let var_node_id
= self.tcx
.hir
.hir_to_node_id(upvar_id
.var_id
);
178 let var_name
= self.tcx
.hir
.name(var_node_id
);
179 let mut err
= struct_span_err
!(self.tcx
.sess
,
182 "lifetime of borrowed pointer outlives lifetime \
183 of captured variable `{}`...",
185 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
186 "...the borrowed pointer is valid for ",
189 self.tcx
.note_and_explain_region(
192 &format
!("...but `{}` is only valid for ", var_name
),
197 infer
::InfStackClosure(span
) => {
199 struct_span_err
!(self.tcx
.sess
, span
, E0314
, "closure outlives stack frame");
200 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
201 "...the closure must be valid for ",
204 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
205 "...but the closure's stack frame is only valid \
211 infer
::InvokeClosure(span
) => {
212 let mut err
= struct_span_err
!(self.tcx
.sess
,
215 "cannot invoke closure outside of its lifetime");
216 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
217 "the closure is only valid for ", sup
, "");
220 infer
::DerefPointer(span
) => {
221 let mut err
= struct_span_err
!(self.tcx
.sess
,
224 "dereference of reference outside its lifetime");
225 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
226 "the reference is only valid for ", sup
, "");
229 infer
::FreeVariable(span
, id
) => {
230 let mut err
= struct_span_err
!(self.tcx
.sess
,
233 "captured variable `{}` does not outlive the \
235 self.tcx
.hir
.name(id
));
236 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
237 "captured variable is valid for ", sup
, "");
238 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
239 "closure is valid for ", sub
, "");
242 infer
::IndexSlice(span
) => {
243 let mut err
= struct_span_err
!(self.tcx
.sess
,
246 "index of slice outside its lifetime");
247 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
248 "the slice is only valid for ", sup
, "");
251 infer
::RelateObjectBound(span
) => {
252 let mut err
= struct_span_err
!(self.tcx
.sess
,
255 "lifetime of the source pointer does not outlive \
256 lifetime bound of the object type");
257 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
258 "object type is valid for ", sub
, "");
259 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
260 "source pointer is only valid for ",
265 infer
::RelateParamBound(span
, ty
) => {
266 let mut err
= struct_span_err
!(self.tcx
.sess
,
269 "the type `{}` does not fulfill the required \
271 self.ty_to_string(ty
));
274 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
275 "type must satisfy ", sub
, "")
278 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
279 "type must outlive ", sub
, "")
284 infer
::RelateRegionParamBound(span
) => {
286 struct_span_err
!(self.tcx
.sess
, span
, E0478
, "lifetime bound not satisfied");
287 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
288 "lifetime parameter instantiated with ",
291 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
292 "but lifetime parameter must outlive ",
297 infer
::RelateDefaultParamBound(span
, ty
) => {
298 let mut err
= struct_span_err
!(self.tcx
.sess
,
301 "the type `{}` (provided as the value of a type \
302 parameter) is not valid at this point",
303 self.ty_to_string(ty
));
304 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
305 "type must outlive ", sub
, "");
308 infer
::CallRcvr(span
) => {
309 let mut err
= struct_span_err
!(self.tcx
.sess
,
312 "lifetime of method receiver does not outlive the \
314 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
315 "the receiver is only valid for ", sup
, "");
318 infer
::CallArg(span
) => {
319 let mut err
= struct_span_err
!(self.tcx
.sess
,
322 "lifetime of function argument does not outlive \
324 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
325 "the function argument is only valid for ",
330 infer
::CallReturn(span
) => {
331 let mut err
= struct_span_err
!(self.tcx
.sess
,
334 "lifetime of return value does not outlive the \
336 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
337 "the return value is only valid for ",
342 infer
::Operand(span
) => {
343 let mut err
= struct_span_err
!(self.tcx
.sess
,
346 "lifetime of operand does not outlive the \
348 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
349 "the operand is only valid for ", sup
, "");
352 infer
::AddrOf(span
) => {
353 let mut err
= struct_span_err
!(self.tcx
.sess
,
356 "reference is not valid at the time of borrow");
357 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
358 "the borrow is only valid for ", sup
, "");
361 infer
::AutoBorrow(span
) => {
362 let mut err
= struct_span_err
!(self.tcx
.sess
,
365 "automatically reference is not valid at the time \
367 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
368 "the automatic borrow is only valid for ",
373 infer
::ExprTypeIsNotInScope(t
, span
) => {
374 let mut err
= struct_span_err
!(self.tcx
.sess
,
377 "type of expression contains references that are \
378 not valid during the expression: `{}`",
379 self.ty_to_string(t
));
380 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
381 "type is only valid for ", sup
, "");
384 infer
::SafeDestructor(span
) => {
385 let mut err
= struct_span_err
!(self.tcx
.sess
,
388 "unsafe use of destructor: destructor might be \
389 called while references are dead");
390 // FIXME (22171): terms "super/subregion" are suboptimal
391 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
392 "superregion: ", sup
, "");
393 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
394 "subregion: ", sub
, "");
397 infer
::BindingTypeIsNotValidAtDecl(span
) => {
398 let mut err
= struct_span_err
!(self.tcx
.sess
,
401 "lifetime of variable does not enclose its \
403 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
404 "the variable is only valid for ", sup
, "");
407 infer
::ParameterInScope(_
, span
) => {
408 let mut err
= struct_span_err
!(self.tcx
.sess
,
411 "type/lifetime parameter not in scope here");
412 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
413 "the parameter is only valid for ", sub
, "");
416 infer
::DataBorrowed(ty
, span
) => {
417 let mut err
= struct_span_err
!(self.tcx
.sess
,
420 "a value of type `{}` is borrowed for too long",
421 self.ty_to_string(ty
));
422 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
423 "the type is valid for ", sub
, "");
424 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
425 "but the borrow lasts for ", sup
, "");
428 infer
::ReferenceOutlivesReferent(ty
, span
) => {
429 let mut err
= struct_span_err
!(self.tcx
.sess
,
432 "in type `{}`, reference has a longer lifetime \
433 than the data it references",
434 self.ty_to_string(ty
));
435 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
436 "the pointer is valid for ", sub
, "");
437 self.tcx
.note_and_explain_region(region_scope_tree
, &mut err
,
438 "but the referenced data is only valid for ",
443 infer
::CompareImplMethodObligation
{ span
,
446 trait_item_def_id
} => {
447 self.report_extra_impl_obligation(span
,
451 &format
!("`{}: {}`", sup
, sub
))