]> git.proxmox.com Git - rustc.git/blob - src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
7f3ec852e41de53ceb3b9f657e3553351d761116
[rustc.git] / src / librustc_infer / infer / error_reporting / nice_region_error / static_impl_trait.rs
1 //! Error Reporting for static impl Traits.
2
3 use crate::infer::error_reporting::msg_span_from_free_region;
4 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
5 use crate::infer::lexical_region_resolve::RegionResolutionError;
6 use rustc_errors::{Applicability, ErrorReported};
7 use rustc_middle::ty::{BoundRegion, FreeRegion, RegionKind};
8
9 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
10 /// Print the error message for lifetime errors when the return type is a static impl Trait.
11 pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
12 if let Some(ref error) = self.error {
13 if let RegionResolutionError::SubSupConflict(
14 _,
15 var_origin,
16 sub_origin,
17 sub_r,
18 sup_origin,
19 sup_r,
20 ) = error.clone()
21 {
22 let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
23 let return_ty = self.tcx().return_type_impl_trait(anon_reg_sup.def_id);
24 if sub_r == &RegionKind::ReStatic && return_ty.is_some() {
25 let sp = var_origin.span();
26 let return_sp = sub_origin.span();
27 let mut err =
28 self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
29 err.span_label(
30 return_sp,
31 "this return type evaluates to the `'static` lifetime...",
32 );
33 err.span_label(sup_origin.span(), "...but this borrow...");
34
35 let (lifetime, lt_sp_opt) = msg_span_from_free_region(self.tcx(), sup_r);
36 if let Some(lifetime_sp) = lt_sp_opt {
37 err.span_note(lifetime_sp, &format!("...can't outlive {}", lifetime));
38 }
39
40 let lifetime_name = match sup_r {
41 RegionKind::ReFree(FreeRegion {
42 bound_region: BoundRegion::BrNamed(_, ref name),
43 ..
44 }) => name.to_string(),
45 _ => "'_".to_owned(),
46 };
47 let fn_return_span = return_ty.unwrap().1;
48 if let Ok(snippet) =
49 self.tcx().sess.source_map().span_to_snippet(fn_return_span)
50 {
51 // only apply this suggestion onto functions with
52 // explicit non-desugar'able return.
53 if fn_return_span.desugaring_kind().is_none() {
54 err.span_suggestion(
55 fn_return_span,
56 &format!(
57 "you can add a bound to the return type to make it last \
58 less than `'static` and match {}",
59 lifetime,
60 ),
61 format!("{} + {}", snippet, lifetime_name),
62 Applicability::Unspecified,
63 );
64 }
65 }
66 err.emit();
67 return Some(ErrorReported);
68 }
69 }
70 }
71 None
72 }
73 }