]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
New upstream version 1.60.0+dfsg1
[rustc.git] / compiler / rustc_infer / src / infer / error_reporting / nice_region_error / named_anon_conflict.rs
CommitLineData
ff7c6d11
XL
1//! Error Reporting for Anonymous Region Lifetime Errors
2//! where one region is named and the other is anonymous.
6a06907d 3use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
9fa01778 4use crate::infer::error_reporting::nice_region_error::NiceRegionError;
dfeec247 5use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
ba9703b0 6use rustc_middle::ty;
60c5eb7d 7
dc9dc135 8impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
e1599b0c 9 /// When given a `ConcreteFailure` for a function with parameters containing a named region and
ff7c6d11 10 /// an anonymous region, emit an descriptive diagnostic error.
6a06907d 11 pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
74b04a01 12 let (span, sub, sup) = self.regions()?;
ff7c6d11
XL
13
14 debug!(
532ac7d7 15 "try_report_named_anon_conflict(sub={:?}, sup={:?}, error={:?})",
dfeec247 16 sub, sup, self.error,
ff7c6d11
XL
17 );
18
19 // Determine whether the sub and sup consist of one named region ('a)
20 // and one anonymous (elided) region. If so, find the parameter arg
21 // where the anonymous region appears (there must always be one; we
22 // only introduced anonymous regions in parameters) as well as a
23 // version new_ty of its type where the anonymous region is replaced
f9f354fc
XL
24 // with the named one.
25 let (named, anon, anon_param_info, region_info) = if sub.has_name()
9fa01778 26 && self.tcx().is_suitable_region(sup).is_some()
e1599b0c 27 && self.find_param_with_region(sup, sub).is_some()
ff7c6d11
XL
28 {
29 (
30 sub,
31 sup,
e1599b0c 32 self.find_param_with_region(sup, sub).unwrap(),
9fa01778 33 self.tcx().is_suitable_region(sup).unwrap(),
ff7c6d11 34 )
f9f354fc 35 } else if sup.has_name()
dfeec247 36 && self.tcx().is_suitable_region(sub).is_some()
e1599b0c 37 && self.find_param_with_region(sub, sup).is_some()
ff7c6d11
XL
38 {
39 (
40 sup,
41 sub,
e1599b0c 42 self.find_param_with_region(sub, sup).unwrap(),
9fa01778 43 self.tcx().is_suitable_region(sub).unwrap(),
ff7c6d11
XL
44 )
45 } else {
46 return None; // inapplicable
47 };
48
3c0e092e
XL
49 // Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
50 // and can steer users down the wrong path.
5099ac24 51 if named.is_static() {
3c0e092e
XL
52 return None;
53 }
54
ff7c6d11 55 debug!("try_report_named_anon_conflict: named = {:?}", named);
dfeec247
XL
56 debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info);
57 debug!("try_report_named_anon_conflict: region_info = {:?}", region_info);
ff7c6d11 58
3c0e092e
XL
59 let param = anon_param_info.param;
60 let new_ty = anon_param_info.param_ty;
61 let new_ty_span = anon_param_info.param_ty_span;
62 let br = anon_param_info.bound_region;
63 let is_first = anon_param_info.is_first;
64 let scope_def_id = region_info.def_id;
65 let is_impl_item = region_info.is_impl_item;
66
ff7c6d11
XL
67 match br {
68 ty::BrAnon(_) => {}
69 _ => {
70 /* not an anonymous region */
71 debug!("try_report_named_anon_conflict: not an anonymous region");
72 return None;
73 }
74 }
75
76 if is_impl_item {
77 debug!("try_report_named_anon_conflict: impl item, bail out");
78 return None;
79 }
80
3c0e092e
XL
81 if find_anon_type(self.tcx(), anon, &br).is_some()
82 && self.is_self_anon(is_first, scope_def_id)
83 {
84 return None;
ff7c6d11
XL
85 }
86
e1599b0c 87 let (error_var, span_label_var) = match param.pat.simple_ident() {
48663c56 88 Some(simple_ident) => (
8faf50e0
XL
89 format!("the type of `{}`", simple_ident),
90 format!("the type of `{}`", simple_ident),
48663c56
XL
91 ),
92 None => ("parameter type".to_owned(), "type".to_owned()),
ff7c6d11
XL
93 };
94
9fa01778
XL
95 let mut diag = struct_span_err!(
96 self.tcx().sess,
ff7c6d11
XL
97 span,
98 E0621,
99 "explicit lifetime required in {}",
100 error_var
9fa01778
XL
101 );
102
532ac7d7 103 diag.span_label(span, format!("lifetime `{}` required", named));
3c0e092e
XL
104 diag.span_suggestion(
105 new_ty_span,
106 &format!("add explicit lifetime `{}` to {}", named, span_label_var),
107 new_ty.to_string(),
108 Applicability::Unspecified,
109 );
9fa01778
XL
110
111 Some(diag)
ff7c6d11
XL
112 }
113}