1 use crate::borrow_check
::Upvar
;
2 use crate::borrow_check
::{nll::ToRegionVid, region_infer::RegionInferenceContext}
;
3 use rustc_index
::vec
::{Idx, IndexVec}
;
4 use rustc_middle
::mir
::{Body, Local}
;
5 use rustc_middle
::ty
::{RegionVid, TyCtxt}
;
6 use rustc_span
::source_map
::Span
;
7 use rustc_span
::symbol
::Symbol
;
9 impl<'tcx
> RegionInferenceContext
<'tcx
> {
10 crate fn get_var_name_and_span_for_region(
14 local_names
: &IndexVec
<Local
, Option
<Symbol
>>,
17 ) -> Option
<(Option
<Symbol
>, Span
)> {
18 debug
!("get_var_name_and_span_for_region(fr={:?})", fr
);
19 assert
!(self.universal_regions().is_universal_region(fr
));
21 debug
!("get_var_name_and_span_for_region: attempting upvar");
22 self.get_upvar_index_for_region(tcx
, fr
)
24 let (name
, span
) = self.get_upvar_name_and_span_for_region(tcx
, upvars
, index
);
28 debug
!("get_var_name_and_span_for_region: attempting argument");
29 self.get_argument_index_for_region(tcx
, fr
).map(|index
| {
30 self.get_argument_name_and_span_for_region(body
, local_names
, index
)
35 /// Search the upvars (if any) to find one that references fr. Return its index.
36 crate fn get_upvar_index_for_region(&self, tcx
: TyCtxt
<'tcx
>, fr
: RegionVid
) -> Option
<usize> {
38 self.universal_regions().defining_ty
.upvar_tys().position(|upvar_ty
| {
39 debug
!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty
);
40 tcx
.any_free_region_meets(&upvar_ty
, |r
| {
41 let r
= r
.to_region_vid();
42 debug
!("get_upvar_index_for_region: r={:?} fr={:?}", r
, fr
);
47 let upvar_ty
= self.universal_regions().defining_ty
.upvar_tys().nth(upvar_index
);
50 "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
51 fr
, upvar_index
, upvar_ty
,
57 /// Given the index of an upvar, finds its name and the span from where it was
59 crate fn get_upvar_name_and_span_for_region(
65 let upvar_hir_id
= upvars
[upvar_index
].var_hir_id
;
66 debug
!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id
);
68 let upvar_name
= tcx
.hir().name(upvar_hir_id
);
69 let upvar_span
= tcx
.hir().span(upvar_hir_id
);
71 "get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
72 upvar_name
, upvar_span
75 (upvar_name
, upvar_span
)
78 /// Search the argument types for one that references fr (which should be a free region).
79 /// Returns Some(_) with the index of the input if one is found.
81 /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
82 /// user - in particular, index 0 is not the implicit self parameter.
83 crate fn get_argument_index_for_region(
88 let implicit_inputs
= self.universal_regions().defining_ty
.implicit_inputs();
90 self.universal_regions().unnormalized_input_tys
.iter().skip(implicit_inputs
).position(
92 debug
!("get_argument_index_for_region: arg_ty = {:?}", arg_ty
);
93 tcx
.any_free_region_meets(arg_ty
, |r
| r
.to_region_vid() == fr
)
98 "get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
101 self.universal_regions().unnormalized_input_tys
[argument_index
],
107 /// Given the index of an argument, finds its name (if any) and the span from where it was
109 crate fn get_argument_name_and_span_for_region(
112 local_names
: &IndexVec
<Local
, Option
<Symbol
>>,
113 argument_index
: usize,
114 ) -> (Option
<Symbol
>, Span
) {
115 let implicit_inputs
= self.universal_regions().defining_ty
.implicit_inputs();
116 let argument_local
= Local
::new(implicit_inputs
+ argument_index
+ 1);
117 debug
!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local
);
119 let argument_name
= local_names
[argument_local
];
120 let argument_span
= body
.local_decls
[argument_local
].source_info
.span
;
122 "get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
123 argument_name
, argument_span
126 (argument_name
, argument_span
)