| //! Error Reporting for static impl Traits. |
| |
| use crate::infer::error_reporting::nice_region_error::NiceRegionError; |
| use crate::infer::lexical_region_resolve::RegionResolutionError; |
| use crate::ty::{BoundRegion, FreeRegion, RegionKind}; |
| use crate::util::common::ErrorReported; |
| use errors::Applicability; |
| |
| impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { |
| /// Print the error message for lifetime errors when the return type is a static impl Trait. |
| pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> { |
| if let Some(ref error) = self.error { |
| if let RegionResolutionError::SubSupConflict( |
| _, |
| var_origin, |
| sub_origin, |
| sub_r, |
| sup_origin, |
| sup_r, |
| ) = error.clone() |
| { |
| let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?; |
| let return_ty = self.tcx().return_type_impl_trait(anon_reg_sup.def_id); |
| if sub_r == &RegionKind::ReStatic && |
| return_ty.is_some() |
| { |
| let sp = var_origin.span(); |
| let return_sp = sub_origin.span(); |
| let mut err = self.tcx().sess.struct_span_err( |
| sp, |
| "cannot infer an appropriate lifetime", |
| ); |
| err.span_label( |
| return_sp, |
| "this return type evaluates to the `'static` lifetime...", |
| ); |
| err.span_label( |
| sup_origin.span(), |
| "...but this borrow...", |
| ); |
| |
| let (lifetime, lt_sp_opt) = self.tcx().msg_span_from_free_region(sup_r); |
| if let Some(lifetime_sp) = lt_sp_opt { |
| err.span_note( |
| lifetime_sp, |
| &format!("...can't outlive {}", lifetime), |
| ); |
| } |
| |
| let lifetime_name = match sup_r { |
| RegionKind::ReFree(FreeRegion { |
| bound_region: BoundRegion::BrNamed(_, ref name), .. |
| }) => name.to_string(), |
| _ => "'_".to_owned(), |
| }; |
| let fn_return_span = return_ty.unwrap().1; |
| if let Ok(snippet) = |
| self.tcx().sess.source_map().span_to_snippet(fn_return_span) { |
| // only apply this suggestion onto functions with |
| // explicit non-desugar'able return. |
| if fn_return_span.desugaring_kind().is_none() { |
| err.span_suggestion( |
| fn_return_span, |
| &format!( |
| "you can add a constraint to the return type to make it last \ |
| less than `'static` and match {}", |
| lifetime, |
| ), |
| format!("{} + {}", snippet, lifetime_name), |
| Applicability::Unspecified, |
| ); |
| } |
| } |
| err.emit(); |
| return Some(ErrorReported); |
| } |
| } |
| } |
| None |
| } |
| } |