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};
12 use ty::{self, Region};
13 use ty::error::TypeError;
14 use errors::DiagnosticBuilder;
16 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
17 pub(super) fn note_region_origin(&self,
18 err: &mut DiagnosticBuilder,
19 origin: &SubregionOrigin<'tcx>) {
21 infer::Subtype(ref trace) => {
22 if let Some((expected, found)) = self.values_str(&trace.values) {
23 let expected = expected.content();
24 let found = found.content();
25 // FIXME: do we want a "the" here?
26 err.span_note(trace.cause.span,
27 &format!("...so that {} (expected {}, found {})",
28 trace.cause.as_requirement_str(),
32 // FIXME: this really should be handled at some earlier stage. Our
33 // handling of region checking when type errors are present is
36 err.span_note(trace.cause.span,
37 &format!("...so that {}", trace.cause.as_requirement_str()));
40 infer::Reborrow(span) => {
42 "...so that reference does not outlive borrowed content");
44 infer::ReborrowUpvar(span, ref upvar_id) => {
46 &format!("...so that closure can access `{}`",
48 .local_var_name_str_def_index(upvar_id.var_id)));
50 infer::InfStackClosure(span) => {
51 err.span_note(span, "...so that closure does not outlive its stack frame");
53 infer::InvokeClosure(span) => {
55 "...so that closure is not invoked outside its lifetime");
57 infer::DerefPointer(span) => {
59 "...so that pointer is not dereferenced outside its lifetime");
61 infer::FreeVariable(span, id) => {
63 &format!("...so that captured variable `{}` does not outlive the \
65 self.tcx.local_var_name_str(id)));
67 infer::IndexSlice(span) => {
68 err.span_note(span, "...so that slice is not indexed outside the lifetime");
70 infer::RelateObjectBound(span) => {
71 err.span_note(span, "...so that it can be closed over into an object");
73 infer::CallRcvr(span) => {
75 "...so that method receiver is valid for the method call");
77 infer::CallArg(span) => {
78 err.span_note(span, "...so that argument is valid for the call");
80 infer::CallReturn(span) => {
81 err.span_note(span, "...so that return value is valid for the call");
83 infer::Operand(span) => {
84 err.span_note(span, "...so that operand is valid for operation");
86 infer::AddrOf(span) => {
87 err.span_note(span, "...so that reference is valid at the time of borrow");
89 infer::AutoBorrow(span) => {
91 "...so that auto-reference is valid at the time of borrow");
93 infer::ExprTypeIsNotInScope(t, span) => {
95 &format!("...so type `{}` of expression is valid during the \
97 self.ty_to_string(t)));
99 infer::BindingTypeIsNotValidAtDecl(span) => {
101 "...so that variable is valid at time of its declaration");
103 infer::ParameterInScope(_, span) => {
105 "...so that a type/lifetime parameter is in scope here");
107 infer::DataBorrowed(ty, span) => {
109 &format!("...so that the type `{}` is not borrowed for too long",
110 self.ty_to_string(ty)));
112 infer::ReferenceOutlivesReferent(ty, span) => {
114 &format!("...so that the reference type `{}` does not outlive the \
116 self.ty_to_string(ty)));
118 infer::RelateParamBound(span, t) => {
120 &format!("...so that the type `{}` will meet its required \
122 self.ty_to_string(t)));
124 infer::RelateDefaultParamBound(span, t) => {
126 &format!("...so that type parameter instantiated with `{}`, will \
127 meet its declared lifetime bounds",
128 self.ty_to_string(t)));
130 infer::RelateRegionParamBound(span) => {
132 "...so that the declared lifetime parameter bounds are satisfied");
134 infer::SafeDestructor(span) => {
136 "...so that references are valid when the destructor runs");
138 infer::CompareImplMethodObligation { span, .. } => {
140 "...so that the definition in impl matches the definition from the \
146 pub(super) fn report_concrete_failure(&self,
147 origin: SubregionOrigin<'tcx>,
150 -> DiagnosticBuilder<'tcx> {
152 infer::Subtype(trace) => {
153 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
154 self.report_and_explain_type_error(trace, &terr)
156 infer::Reborrow(span) => {
157 let mut err = struct_span_err!(self.tcx.sess,
160 "lifetime of reference outlives lifetime of \
161 borrowed content...");
162 self.tcx.note_and_explain_region(&mut err,
163 "...the reference is valid for ",
166 self.tcx.note_and_explain_region(&mut err,
167 "...but the borrowed content is only valid for ",
172 infer::ReborrowUpvar(span, ref upvar_id) => {
173 let mut err = struct_span_err!(self.tcx.sess,
176 "lifetime of borrowed pointer outlives lifetime \
177 of captured variable `{}`...",
179 .local_var_name_str_def_index(upvar_id.var_id));
180 self.tcx.note_and_explain_region(&mut err,
181 "...the borrowed pointer is valid for ",
185 .note_and_explain_region(
187 &format!("...but `{}` is only valid for ",
188 self.tcx.local_var_name_str_def_index(upvar_id.var_id)),
193 infer::InfStackClosure(span) => {
195 struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame");
196 self.tcx.note_and_explain_region(&mut err,
197 "...the closure must be valid for ",
200 self.tcx.note_and_explain_region(&mut err,
201 "...but the closure's stack frame is only valid \
207 infer::InvokeClosure(span) => {
208 let mut err = struct_span_err!(self.tcx.sess,
211 "cannot invoke closure outside of its lifetime");
213 .note_and_explain_region(&mut err, "the closure is only valid for ", sup, "");
216 infer::DerefPointer(span) => {
217 let mut err = struct_span_err!(self.tcx.sess,
220 "dereference of reference outside its lifetime");
222 .note_and_explain_region(&mut err, "the reference is only valid for ", sup, "");
225 infer::FreeVariable(span, id) => {
226 let mut err = struct_span_err!(self.tcx.sess,
229 "captured variable `{}` does not outlive the \
231 self.tcx.local_var_name_str(id));
233 .note_and_explain_region(&mut err, "captured variable is valid for ", sup, "");
234 self.tcx.note_and_explain_region(&mut err, "closure is valid for ", sub, "");
237 infer::IndexSlice(span) => {
238 let mut err = struct_span_err!(self.tcx.sess,
241 "index of slice outside its lifetime");
242 self.tcx.note_and_explain_region(&mut err, "the slice is only valid for ", sup, "");
245 infer::RelateObjectBound(span) => {
246 let mut err = struct_span_err!(self.tcx.sess,
249 "lifetime of the source pointer does not outlive \
250 lifetime bound of the object type");
251 self.tcx.note_and_explain_region(&mut err, "object type is valid for ", sub, "");
252 self.tcx.note_and_explain_region(&mut err,
253 "source pointer is only valid for ",
258 infer::RelateParamBound(span, ty) => {
259 let mut err = struct_span_err!(self.tcx.sess,
262 "the type `{}` does not fulfill the required \
264 self.ty_to_string(ty));
267 self.tcx.note_and_explain_region(&mut err, "type must satisfy ", sub, "")
270 self.tcx.note_and_explain_region(&mut err, "type must outlive ", sub, "")
275 infer::RelateRegionParamBound(span) => {
277 struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied");
278 self.tcx.note_and_explain_region(&mut err,
279 "lifetime parameter instantiated with ",
282 self.tcx.note_and_explain_region(&mut err,
283 "but lifetime parameter must outlive ",
288 infer::RelateDefaultParamBound(span, ty) => {
289 let mut err = struct_span_err!(self.tcx.sess,
292 "the type `{}` (provided as the value of a type \
293 parameter) is not valid at this point",
294 self.ty_to_string(ty));
295 self.tcx.note_and_explain_region(&mut err, "type must outlive ", sub, "");
298 infer::CallRcvr(span) => {
299 let mut err = struct_span_err!(self.tcx.sess,
302 "lifetime of method receiver does not outlive the \
305 .note_and_explain_region(&mut err, "the receiver is only valid for ", sup, "");
308 infer::CallArg(span) => {
309 let mut err = struct_span_err!(self.tcx.sess,
312 "lifetime of function argument does not outlive \
314 self.tcx.note_and_explain_region(&mut err,
315 "the function argument is only valid for ",
320 infer::CallReturn(span) => {
321 let mut err = struct_span_err!(self.tcx.sess,
324 "lifetime of return value does not outlive the \
326 self.tcx.note_and_explain_region(&mut err,
327 "the return value is only valid for ",
332 infer::Operand(span) => {
333 let mut err = struct_span_err!(self.tcx.sess,
336 "lifetime of operand does not outlive the \
339 .note_and_explain_region(&mut err, "the operand is only valid for ", sup, "");
342 infer::AddrOf(span) => {
343 let mut err = struct_span_err!(self.tcx.sess,
346 "reference is not valid at the time of borrow");
348 .note_and_explain_region(&mut err, "the borrow is only valid for ", sup, "");
351 infer::AutoBorrow(span) => {
352 let mut err = struct_span_err!(self.tcx.sess,
355 "automatically reference is not valid at the time \
357 self.tcx.note_and_explain_region(&mut err,
358 "the automatic borrow is only valid for ",
363 infer::ExprTypeIsNotInScope(t, span) => {
364 let mut err = struct_span_err!(self.tcx.sess,
367 "type of expression contains references that are \
368 not valid during the expression: `{}`",
369 self.ty_to_string(t));
370 self.tcx.note_and_explain_region(&mut err, "type is only valid for ", sup, "");
373 infer::SafeDestructor(span) => {
374 let mut err = struct_span_err!(self.tcx.sess,
377 "unsafe use of destructor: destructor might be \
378 called while references are dead");
379 // FIXME (22171): terms "super/subregion" are suboptimal
380 self.tcx.note_and_explain_region(&mut err, "superregion: ", sup, "");
381 self.tcx.note_and_explain_region(&mut err, "subregion: ", sub, "");
384 infer::BindingTypeIsNotValidAtDecl(span) => {
385 let mut err = struct_span_err!(self.tcx.sess,
388 "lifetime of variable does not enclose its \
391 .note_and_explain_region(&mut err, "the variable is only valid for ", sup, "");
394 infer::ParameterInScope(_, span) => {
395 let mut err = struct_span_err!(self.tcx.sess,
398 "type/lifetime parameter not in scope here");
400 .note_and_explain_region(&mut err, "the parameter is only valid for ", sub, "");
403 infer::DataBorrowed(ty, span) => {
404 let mut err = struct_span_err!(self.tcx.sess,
407 "a value of type `{}` is borrowed for too long",
408 self.ty_to_string(ty));
409 self.tcx.note_and_explain_region(&mut err, "the type is valid for ", sub, "");
410 self.tcx.note_and_explain_region(&mut err, "but the borrow lasts for ", sup, "");
413 infer::ReferenceOutlivesReferent(ty, span) => {
414 let mut err = struct_span_err!(self.tcx.sess,
417 "in type `{}`, reference has a longer lifetime \
418 than the data it references",
419 self.ty_to_string(ty));
420 self.tcx.note_and_explain_region(&mut err, "the pointer is valid for ", sub, "");
421 self.tcx.note_and_explain_region(&mut err,
422 "but the referenced data is only valid for ",
427 infer::CompareImplMethodObligation { span,
432 self.report_extra_impl_obligation(span,
436 &format!("`{}: {}`", sup, sub),