]> git.proxmox.com Git - rustc.git/blob - src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
New upstream version 1.31.0~beta.4+dfsg1
[rustc.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 use errors::Applicability;
18
19 impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
20 /// Print the error message for lifetime errors when the return type is a static impl Trait.
21 pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
22 if let Some(ref error) = self.error {
23 if let RegionResolutionError::SubSupConflict(
24 var_origin,
25 sub_origin,
26 sub_r,
27 sup_origin,
28 sup_r,
29 ) = error.clone()
30 {
31 let anon_reg_sup = self.tcx.is_suitable_region(sup_r)?;
32 if sub_r == &RegionKind::ReStatic &&
33 self.tcx.return_type_impl_trait(anon_reg_sup.def_id).is_some()
34 {
35 let sp = var_origin.span();
36 let return_sp = sub_origin.span();
37 let mut err = self.tcx.sess.struct_span_err(
38 sp,
39 "cannot infer an appropriate lifetime",
40 );
41 err.span_label(
42 return_sp,
43 "this return type evaluates to the `'static` lifetime...",
44 );
45 err.span_label(
46 sup_origin.span(),
47 "...but this borrow...",
48 );
49
50 let (lifetime, lt_sp_opt) = self.tcx.msg_span_from_free_region(sup_r);
51 if let Some(lifetime_sp) = lt_sp_opt {
52 err.span_note(
53 lifetime_sp,
54 &format!("...can't outlive {}", lifetime),
55 );
56 }
57
58 let lifetime_name = match sup_r {
59 RegionKind::ReFree(FreeRegion {
60 bound_region: BoundRegion::BrNamed(_, ref name), ..
61 }) => name.to_string(),
62 _ => "'_".to_owned(),
63 };
64 if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) {
65 err.span_suggestion_with_applicability(
66 return_sp,
67 &format!(
68 "you can add a constraint to the return type to make it last \
69 less than `'static` and match {}",
70 lifetime,
71 ),
72 format!("{} + {}", snippet, lifetime_name),
73 Applicability::Unspecified,
74 );
75 }
76 err.emit();
77 return Some(ErrorReported);
78 }
79 }
80 }
81 None
82 }
83 }