]> git.lizzy.rs Git - rust.git/blob - src/librustc/infer/error_reporting/note.rs
Auto merge of #44060 - taleks:issue-43205, r=arielb1
[rust.git] / src / librustc / infer / error_reporting / note.rs
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 ty::{self, Region};
13 use ty::error::TypeError;
14 use errors::DiagnosticBuilder;
15
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>) {
20         match *origin {
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(),
29                                            expected,
30                                            found));
31                 } else {
32                     // FIXME: this really should be handled at some earlier stage. Our
33                     // handling of region checking when type errors are present is
34                     // *terrible*.
35
36                     err.span_note(trace.cause.span,
37                                   &format!("...so that {}", trace.cause.as_requirement_str()));
38                 }
39             }
40             infer::Reborrow(span) => {
41                 err.span_note(span,
42                               "...so that reference does not outlive borrowed content");
43             }
44             infer::ReborrowUpvar(span, ref upvar_id) => {
45                 err.span_note(span,
46                               &format!("...so that closure can access `{}`",
47                                        self.tcx
48                                            .local_var_name_str_def_index(upvar_id.var_id)));
49             }
50             infer::InfStackClosure(span) => {
51                 err.span_note(span, "...so that closure does not outlive its stack frame");
52             }
53             infer::InvokeClosure(span) => {
54                 err.span_note(span,
55                               "...so that closure is not invoked outside its lifetime");
56             }
57             infer::DerefPointer(span) => {
58                 err.span_note(span,
59                               "...so that pointer is not dereferenced outside its lifetime");
60             }
61             infer::FreeVariable(span, id) => {
62                 err.span_note(span,
63                               &format!("...so that captured variable `{}` does not outlive the \
64                                         enclosing closure",
65                                        self.tcx.local_var_name_str(id)));
66             }
67             infer::IndexSlice(span) => {
68                 err.span_note(span, "...so that slice is not indexed outside the lifetime");
69             }
70             infer::RelateObjectBound(span) => {
71                 err.span_note(span, "...so that it can be closed over into an object");
72             }
73             infer::CallRcvr(span) => {
74                 err.span_note(span,
75                               "...so that method receiver is valid for the method call");
76             }
77             infer::CallArg(span) => {
78                 err.span_note(span, "...so that argument is valid for the call");
79             }
80             infer::CallReturn(span) => {
81                 err.span_note(span, "...so that return value is valid for the call");
82             }
83             infer::Operand(span) => {
84                 err.span_note(span, "...so that operand is valid for operation");
85             }
86             infer::AddrOf(span) => {
87                 err.span_note(span, "...so that reference is valid at the time of borrow");
88             }
89             infer::AutoBorrow(span) => {
90                 err.span_note(span,
91                               "...so that auto-reference is valid at the time of borrow");
92             }
93             infer::ExprTypeIsNotInScope(t, span) => {
94                 err.span_note(span,
95                               &format!("...so type `{}` of expression is valid during the \
96                                         expression",
97                                        self.ty_to_string(t)));
98             }
99             infer::BindingTypeIsNotValidAtDecl(span) => {
100                 err.span_note(span,
101                               "...so that variable is valid at time of its declaration");
102             }
103             infer::ParameterInScope(_, span) => {
104                 err.span_note(span,
105                               "...so that a type/lifetime parameter is in scope here");
106             }
107             infer::DataBorrowed(ty, span) => {
108                 err.span_note(span,
109                               &format!("...so that the type `{}` is not borrowed for too long",
110                                        self.ty_to_string(ty)));
111             }
112             infer::ReferenceOutlivesReferent(ty, span) => {
113                 err.span_note(span,
114                               &format!("...so that the reference type `{}` does not outlive the \
115                                         data it points at",
116                                        self.ty_to_string(ty)));
117             }
118             infer::RelateParamBound(span, t) => {
119                 err.span_note(span,
120                               &format!("...so that the type `{}` will meet its required \
121                                         lifetime bounds",
122                                        self.ty_to_string(t)));
123             }
124             infer::RelateDefaultParamBound(span, t) => {
125                 err.span_note(span,
126                               &format!("...so that type parameter instantiated with `{}`, will \
127                                         meet its declared lifetime bounds",
128                                        self.ty_to_string(t)));
129             }
130             infer::RelateRegionParamBound(span) => {
131                 err.span_note(span,
132                               "...so that the declared lifetime parameter bounds are satisfied");
133             }
134             infer::SafeDestructor(span) => {
135                 err.span_note(span,
136                               "...so that references are valid when the destructor runs");
137             }
138             infer::CompareImplMethodObligation { span, .. } => {
139                 err.span_note(span,
140                               "...so that the definition in impl matches the definition from the \
141                                trait");
142             }
143         }
144     }
145
146     pub(super) fn report_concrete_failure(&self,
147                                           origin: SubregionOrigin<'tcx>,
148                                           sub: Region<'tcx>,
149                                           sup: Region<'tcx>)
150                                           -> DiagnosticBuilder<'tcx> {
151         match origin {
152             infer::Subtype(trace) => {
153                 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
154                 self.report_and_explain_type_error(trace, &terr)
155             }
156             infer::Reborrow(span) => {
157                 let mut err = struct_span_err!(self.tcx.sess,
158                                                span,
159                                                E0312,
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 ",
164                                                  sub,
165                                                  "...");
166                 self.tcx.note_and_explain_region(&mut err,
167                                                  "...but the borrowed content is only valid for ",
168                                                  sup,
169                                                  "");
170                 err
171             }
172             infer::ReborrowUpvar(span, ref upvar_id) => {
173                 let mut err = struct_span_err!(self.tcx.sess,
174                                                span,
175                                                E0313,
176                                                "lifetime of borrowed pointer outlives lifetime \
177                                                 of captured variable `{}`...",
178                                                self.tcx
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 ",
182                                                  sub,
183                                                  "...");
184                 self.tcx
185                     .note_and_explain_region(
186                       &mut err,
187                       &format!("...but `{}` is only valid for ",
188                                self.tcx.local_var_name_str_def_index(upvar_id.var_id)),
189                       sup,
190                       "");
191                 err
192             }
193             infer::InfStackClosure(span) => {
194                 let mut err =
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 ",
198                                                  sub,
199                                                  "...");
200                 self.tcx.note_and_explain_region(&mut err,
201                                                  "...but the closure's stack frame is only valid \
202                                                   for ",
203                                                  sup,
204                                                  "");
205                 err
206             }
207             infer::InvokeClosure(span) => {
208                 let mut err = struct_span_err!(self.tcx.sess,
209                                                span,
210                                                E0315,
211                                                "cannot invoke closure outside of its lifetime");
212                 self.tcx
213                     .note_and_explain_region(&mut err, "the closure is only valid for ", sup, "");
214                 err
215             }
216             infer::DerefPointer(span) => {
217                 let mut err = struct_span_err!(self.tcx.sess,
218                                                span,
219                                                E0473,
220                                                "dereference of reference outside its lifetime");
221                 self.tcx
222                     .note_and_explain_region(&mut err, "the reference is only valid for ", sup, "");
223                 err
224             }
225             infer::FreeVariable(span, id) => {
226                 let mut err = struct_span_err!(self.tcx.sess,
227                                                span,
228                                                E0474,
229                                                "captured variable `{}` does not outlive the \
230                                                 enclosing closure",
231                                                self.tcx.local_var_name_str(id));
232                 self.tcx
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, "");
235                 err
236             }
237             infer::IndexSlice(span) => {
238                 let mut err = struct_span_err!(self.tcx.sess,
239                                                span,
240                                                E0475,
241                                                "index of slice outside its lifetime");
242                 self.tcx.note_and_explain_region(&mut err, "the slice is only valid for ", sup, "");
243                 err
244             }
245             infer::RelateObjectBound(span) => {
246                 let mut err = struct_span_err!(self.tcx.sess,
247                                                span,
248                                                E0476,
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 ",
254                                                  sup,
255                                                  "");
256                 err
257             }
258             infer::RelateParamBound(span, ty) => {
259                 let mut err = struct_span_err!(self.tcx.sess,
260                                                span,
261                                                E0477,
262                                                "the type `{}` does not fulfill the required \
263                                                 lifetime",
264                                                self.ty_to_string(ty));
265                 match *sub {
266                     ty::ReStatic => {
267                         self.tcx.note_and_explain_region(&mut err, "type must satisfy ", sub, "")
268                     }
269                     _ => {
270                         self.tcx.note_and_explain_region(&mut err, "type must outlive ", sub, "")
271                     }
272                 }
273                 err
274             }
275             infer::RelateRegionParamBound(span) => {
276                 let mut err =
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 ",
280                                                  sup,
281                                                  "");
282                 self.tcx.note_and_explain_region(&mut err,
283                                                  "but lifetime parameter must outlive ",
284                                                  sub,
285                                                  "");
286                 err
287             }
288             infer::RelateDefaultParamBound(span, ty) => {
289                 let mut err = struct_span_err!(self.tcx.sess,
290                                                span,
291                                                E0479,
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, "");
296                 err
297             }
298             infer::CallRcvr(span) => {
299                 let mut err = struct_span_err!(self.tcx.sess,
300                                                span,
301                                                E0480,
302                                                "lifetime of method receiver does not outlive the \
303                                                 method call");
304                 self.tcx
305                     .note_and_explain_region(&mut err, "the receiver is only valid for ", sup, "");
306                 err
307             }
308             infer::CallArg(span) => {
309                 let mut err = struct_span_err!(self.tcx.sess,
310                                                span,
311                                                E0481,
312                                                "lifetime of function argument does not outlive \
313                                                 the function call");
314                 self.tcx.note_and_explain_region(&mut err,
315                                                  "the function argument is only valid for ",
316                                                  sup,
317                                                  "");
318                 err
319             }
320             infer::CallReturn(span) => {
321                 let mut err = struct_span_err!(self.tcx.sess,
322                                                span,
323                                                E0482,
324                                                "lifetime of return value does not outlive the \
325                                                 function call");
326                 self.tcx.note_and_explain_region(&mut err,
327                                                  "the return value is only valid for ",
328                                                  sup,
329                                                  "");
330                 err
331             }
332             infer::Operand(span) => {
333                 let mut err = struct_span_err!(self.tcx.sess,
334                                                span,
335                                                E0483,
336                                                "lifetime of operand does not outlive the \
337                                                 operation");
338                 self.tcx
339                     .note_and_explain_region(&mut err, "the operand is only valid for ", sup, "");
340                 err
341             }
342             infer::AddrOf(span) => {
343                 let mut err = struct_span_err!(self.tcx.sess,
344                                                span,
345                                                E0484,
346                                                "reference is not valid at the time of borrow");
347                 self.tcx
348                     .note_and_explain_region(&mut err, "the borrow is only valid for ", sup, "");
349                 err
350             }
351             infer::AutoBorrow(span) => {
352                 let mut err = struct_span_err!(self.tcx.sess,
353                                                span,
354                                                E0485,
355                                                "automatically reference is not valid at the time \
356                                                 of borrow");
357                 self.tcx.note_and_explain_region(&mut err,
358                                                  "the automatic borrow is only valid for ",
359                                                  sup,
360                                                  "");
361                 err
362             }
363             infer::ExprTypeIsNotInScope(t, span) => {
364                 let mut err = struct_span_err!(self.tcx.sess,
365                                                span,
366                                                E0486,
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, "");
371                 err
372             }
373             infer::SafeDestructor(span) => {
374                 let mut err = struct_span_err!(self.tcx.sess,
375                                                span,
376                                                E0487,
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, "");
382                 err
383             }
384             infer::BindingTypeIsNotValidAtDecl(span) => {
385                 let mut err = struct_span_err!(self.tcx.sess,
386                                                span,
387                                                E0488,
388                                                "lifetime of variable does not enclose its \
389                                                 declaration");
390                 self.tcx
391                     .note_and_explain_region(&mut err, "the variable is only valid for ", sup, "");
392                 err
393             }
394             infer::ParameterInScope(_, span) => {
395                 let mut err = struct_span_err!(self.tcx.sess,
396                                                span,
397                                                E0489,
398                                                "type/lifetime parameter not in scope here");
399                 self.tcx
400                     .note_and_explain_region(&mut err, "the parameter is only valid for ", sub, "");
401                 err
402             }
403             infer::DataBorrowed(ty, span) => {
404                 let mut err = struct_span_err!(self.tcx.sess,
405                                                span,
406                                                E0490,
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, "");
411                 err
412             }
413             infer::ReferenceOutlivesReferent(ty, span) => {
414                 let mut err = struct_span_err!(self.tcx.sess,
415                                                span,
416                                                E0491,
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 ",
423                                                  sup,
424                                                  "");
425                 err
426             }
427             infer::CompareImplMethodObligation { span,
428                                                  item_name,
429                                                  impl_item_def_id,
430                                                  trait_item_def_id,
431                                                  lint_id } => {
432                 self.report_extra_impl_obligation(span,
433                                                   item_name,
434                                                   impl_item_def_id,
435                                                   trait_item_def_id,
436                                                   &format!("`{}: {}`", sup, sub),
437                                                   lint_id)
438             }
439         }
440     }
441 }