]> git.lizzy.rs Git - rust.git/blob - src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
Rollup merge of #51765 - jonas-schievink:patch-1, r=KodrAus
[rust.git] / src / librustc / infer / error_reporting / nice_region_error / static_impl_trait.rs
1 // Copyright 2012-2013 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 //! Error Reporting for static impl Traits.
12
13 use infer::error_reporting::nice_region_error::NiceRegionError;
14 use infer::lexical_region_resolve::RegionResolutionError;
15 use ty::{BoundRegion, FreeRegion, RegionKind};
16 use util::common::ErrorReported;
17
18 impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
19     /// Print the error message for lifetime errors when the return type is a static impl Trait.
20     pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
21         if let Some(ref error) = self.error {
22             match error.clone() {
23                 RegionResolutionError::SubSupConflict(
24                     var_origin,
25                     sub_origin,
26                     sub_r,
27                     sup_origin,
28                     sup_r,
29                 ) => {
30                     let anon_reg_sup = self.is_suitable_region(sup_r)?;
31                     if sub_r == &RegionKind::ReStatic &&
32                         self.is_return_type_impl_trait(anon_reg_sup.def_id)
33                     {
34                         let sp = var_origin.span();
35                         let return_sp = sub_origin.span();
36                         let mut err = self.tcx.sess.struct_span_err(
37                             sp,
38                             "cannot infer an appropriate lifetime",
39                         );
40                         err.span_label(
41                             return_sp,
42                             "this return type evaluates to the `'static` lifetime...",
43                         );
44                         err.span_label(
45                             sup_origin.span(),
46                             "...but this borrow...",
47                         );
48
49                         let (lifetime, lt_sp_opt) = self.tcx.msg_span_from_free_region(sup_r);
50                         if let Some(lifetime_sp) = lt_sp_opt {
51                             err.span_note(
52                                 lifetime_sp,
53                                 &format!("...can't outlive {}", lifetime),
54                             );
55                         }
56
57                         let lifetime_name = match sup_r {
58                             RegionKind::ReFree(FreeRegion {
59                                 bound_region: BoundRegion::BrNamed(_, ref name), ..
60                             }) => format!("{}", name),
61                             _ => "'_".to_owned(),
62                         };
63                         if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(return_sp) {
64                             err.span_suggestion(
65                                 return_sp,
66                                 &format!(
67                                     "you can add a constraint to the return type to make it last \
68                                      less than `'static` and match {}",
69                                     lifetime,
70                                 ),
71                                 format!("{} + {}", snippet, lifetime_name),
72                             );
73                         }
74                         err.emit();
75                         return Some(ErrorReported);
76                     }
77                 }
78                 _ => {}
79             }
80         }
81         None
82     }
83 }