1 //! Error Reporting for Anonymous Region Lifetime Errors
2 //! where one region is named and the other is anonymous.
3 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
5 use crate::util::common::ErrorReported;
6 use errors::Applicability;
8 impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
9 /// When given a `ConcreteFailure` for a function with arguments containing a named region and
10 /// an anonymous region, emit an descriptive diagnostic error.
11 pub(super) fn try_report_named_anon_conflict(&self) -> Option<ErrorReported> {
12 let (span, sub, sup) = self.get_regions();
15 "try_report_named_anon_conflict(sub={:?}, sup={:?})",
20 // Determine whether the sub and sup consist of one named region ('a)
21 // and one anonymous (elided) region. If so, find the parameter arg
22 // where the anonymous region appears (there must always be one; we
23 // only introduced anonymous regions in parameters) as well as a
24 // version new_ty of its type where the anonymous region is replaced
25 // with the named one.//scope_def_id
26 let (named, anon, anon_arg_info, region_info) = if self.is_named_region(sub)
27 && self.tcx().is_suitable_region(sup).is_some()
28 && self.find_arg_with_region(sup, sub).is_some()
33 self.find_arg_with_region(sup, sub).unwrap(),
34 self.tcx().is_suitable_region(sup).unwrap(),
36 } else if self.is_named_region(sup) && self.tcx().is_suitable_region(sub).is_some()
37 && self.find_arg_with_region(sub, sup).is_some()
42 self.find_arg_with_region(sub, sup).unwrap(),
43 self.tcx().is_suitable_region(sub).unwrap(),
46 return None; // inapplicable
49 debug!("try_report_named_anon_conflict: named = {:?}", named);
51 "try_report_named_anon_conflict: anon_arg_info = {:?}",
55 "try_report_named_anon_conflict: region_info = {:?}",
59 let (arg, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = (
62 anon_arg_info.arg_ty_span,
63 anon_arg_info.bound_region,
64 anon_arg_info.is_first,
66 region_info.is_impl_item,
71 /* not an anonymous region */
72 debug!("try_report_named_anon_conflict: not an anonymous region");
78 debug!("try_report_named_anon_conflict: impl item, bail out");
82 if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
83 if self.is_return_type_anon(scope_def_id, br, fndecl).is_some()
84 || self.is_self_anon(is_first, scope_def_id)
90 let (error_var, span_label_var) = if let Some(simple_ident) = arg.pat.simple_ident() {
92 format!("the type of `{}`", simple_ident),
93 format!("the type of `{}`", simple_ident),
96 ("parameter type".to_owned(), "type".to_owned())
103 "explicit lifetime required in {}",
107 &format!("add explicit lifetime `{}` to {}", named, span_label_var),
109 Applicability::Unspecified,
111 .span_label(span, format!("lifetime `{}` required", named))
113 return Some(ErrorReported);
116 // This method returns whether the given Region is Named
117 pub(super) fn is_named_region(&self, region: ty::Region<'tcx>) -> bool {
119 ty::ReStatic => true,
120 ty::ReFree(ref free_region) => match free_region.bound_region {
121 ty::BrNamed(..) => true,
124 ty::ReEarlyBound(ebr) => ebr.has_name(),