1 //! Error Reporting for Anonymous Region Lifetime Errors
2 //! where both the regions are anonymous.
4 use crate::errors
::AddLifetimeParamsSuggestion
;
5 use crate::errors
::LifetimeMismatch
;
6 use crate::errors
::LifetimeMismatchLabels
;
7 use crate::infer
::error_reporting
::nice_region_error
::find_anon_type
::find_anon_type
;
8 use crate::infer
::error_reporting
::nice_region_error
::util
::AnonymousParamInfo
;
9 use crate::infer
::error_reporting
::nice_region_error
::NiceRegionError
;
10 use crate::infer
::lexical_region_resolve
::RegionResolutionError
;
11 use crate::infer
::SubregionOrigin
;
12 use crate::infer
::TyCtxt
;
14 use rustc_errors
::AddSubdiagnostic
;
15 use rustc_errors
::{Diagnostic, ErrorGuaranteed}
;
17 use rustc_middle
::ty
::Region
;
19 impl<'a
, 'tcx
> NiceRegionError
<'a
, 'tcx
> {
20 /// Print the error message for lifetime errors when both the concerned regions are anonymous.
22 /// Consider a case where we have
24 /// ```compile_fail,E0623
25 /// fn foo(x: &mut Vec<&u8>, y: &u8) {
33 /// fn foo(x: &mut Vec<&u8>, y: &u8) {
34 /// --- --- these references are declared with different lifetimes...
36 /// ^ ...but data from `y` flows into `x` here
39 /// It has been extended for the case of structs too.
41 /// Consider the example
44 /// struct Ref<'a> { x: &'a u32 }
48 /// fn foo(mut x: Vec<Ref>, y: Ref) {
49 /// --- --- these structs are declared with different lifetimes...
51 /// ^ ...but data from `y` flows into `x` here
55 /// It will later be extended to trait objects.
56 pub(super) fn try_report_anon_anon_conflict(&self) -> Option
<ErrorGuaranteed
> {
57 let (span
, sub
, sup
) = self.regions()?
;
59 if let Some(RegionResolutionError
::ConcreteFailure(
60 SubregionOrigin
::ReferenceOutlivesReferent(..),
64 // This error doesn't make much sense in this case.
68 // Determine whether the sub and sup consist of both anonymous (elided) regions.
69 let anon_reg_sup
= self.tcx().is_suitable_region(sup
)?
;
71 let anon_reg_sub
= self.tcx().is_suitable_region(sub
)?
;
72 let scope_def_id_sup
= anon_reg_sup
.def_id
;
73 let bregion_sup
= anon_reg_sup
.boundregion
;
74 let scope_def_id_sub
= anon_reg_sub
.def_id
;
75 let bregion_sub
= anon_reg_sub
.boundregion
;
77 let ty_sup
= find_anon_type(self.tcx(), sup
, &bregion_sup
)?
;
79 let ty_sub
= find_anon_type(self.tcx(), sub
, &bregion_sub
)?
;
82 "try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",
83 ty_sub
, sup
, bregion_sup
86 "try_report_anon_anon_conflict: found_param2={:?} sub={:?} br2={:?}",
87 ty_sup
, sub
, bregion_sub
90 let (ty_sup
, ty_fndecl_sup
) = ty_sup
;
91 let (ty_sub
, ty_fndecl_sub
) = ty_sub
;
93 let AnonymousParamInfo { param: anon_param_sup, .. }
=
94 self.find_param_with_region(sup
, sup
)?
;
95 let AnonymousParamInfo { param: anon_param_sub, .. }
=
96 self.find_param_with_region(sub
, sub
)?
;
99 self.is_return_type_anon(scope_def_id_sup
, bregion_sup
, ty_fndecl_sup
);
100 let sub_is_ret_type
=
101 self.is_return_type_anon(scope_def_id_sub
, bregion_sub
, ty_fndecl_sub
);
104 "try_report_anon_anon_conflict: sub_is_ret_type={:?} sup_is_ret_type={:?}",
105 sub_is_ret_type
, sup_is_ret_type
108 let labels
= match (sup_is_ret_type
, sub_is_ret_type
) {
109 (ret_capture @
Some(ret_span
), _
) | (_
, ret_capture @
Some(ret_span
)) => {
111 if sup_is_ret_type
== ret_capture { ty_sub.span }
else { ty_sup.span }
;
112 LifetimeMismatchLabels
::InRet
{
116 label_var1
: anon_param_sup
.pat
.simple_ident(),
120 (None
, None
) => LifetimeMismatchLabels
::Normal
{
121 hir_equal
: ty_sup
.hir_id
== ty_sub
.hir_id
,
125 sup
: anon_param_sup
.pat
.simple_ident(),
126 sub
: anon_param_sub
.pat
.simple_ident(),
131 AddLifetimeParamsSuggestion { tcx: self.tcx(), sub, ty_sup, ty_sub, add_note: true }
;
132 let err
= LifetimeMismatch { span, labels, suggestion }
;
133 let reported
= self.tcx().sess
.emit_err(err
);
138 /// Currently only used in rustc_borrowck, probably should be
139 /// removed in favour of public_errors::AddLifetimeParamsSuggestion
140 pub fn suggest_adding_lifetime_params
<'tcx
>(
143 ty_sup
: &'tcx Ty
<'_
>,
144 ty_sub
: &'tcx Ty
<'_
>,
145 err
: &mut Diagnostic
,
147 let suggestion
= AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false }
;
148 suggestion
.add_to_diagnostic(err
);