]> git.lizzy.rs Git - rust.git/blob - src/librustc/infer/error_reporting/note.rs
Use NodeId/HirId instead of DefId for local variables.
[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 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: &region::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 }