1 use crate::borrow_check
::{nll::ToRegionVid, region_infer::RegionInferenceContext}
;
2 use crate::borrow_check
::Upvar
;
3 use rustc
::mir
::{Local, Body}
;
4 use rustc
::ty
::{RegionVid, TyCtxt}
;
5 use rustc_index
::vec
::{Idx, IndexVec}
;
6 use syntax
::source_map
::Span
;
7 use syntax_pos
::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
)
25 self.get_upvar_name_and_span_for_region(tcx
, upvars
, index
);
29 debug
!("get_var_name_and_span_for_region: attempting argument");
30 self.get_argument_index_for_region(tcx
, fr
).map(|index
| {
31 self.get_argument_name_and_span_for_region(body
, local_names
, index
)
36 /// Search the upvars (if any) to find one that references fr. Return its index.
37 crate fn get_upvar_index_for_region(&self, tcx
: TyCtxt
<'tcx
>, fr
: RegionVid
) -> Option
<usize> {
38 let upvar_index
= self
42 .position(|upvar_ty
| {
43 debug
!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty
);
44 tcx
.any_free_region_meets(&upvar_ty
, |r
| {
45 let r
= r
.to_region_vid();
46 debug
!("get_upvar_index_for_region: r={:?} fr={:?}", r
, fr
);
58 "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
59 fr
, upvar_index
, upvar_ty
,
65 /// Given the index of an upvar, finds its name and the span from where it was
67 crate fn get_upvar_name_and_span_for_region(
73 let upvar_hir_id
= upvars
[upvar_index
].var_hir_id
;
74 debug
!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id
);
76 let upvar_name
= tcx
.hir().name(upvar_hir_id
);
77 let upvar_span
= tcx
.hir().span(upvar_hir_id
);
78 debug
!("get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
79 upvar_name
, upvar_span
);
81 (upvar_name
, upvar_span
)
84 /// Search the argument types for one that references fr (which should be a free region).
85 /// Returns Some(_) with the index of the input if one is found.
87 /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
88 /// user - in particular, index 0 is not the implicit self parameter.
89 crate fn get_argument_index_for_region(
94 let implicit_inputs
= self.universal_regions
.defining_ty
.implicit_inputs();
95 let argument_index
= self
97 .unnormalized_input_tys
99 .skip(implicit_inputs
)
102 "get_argument_index_for_region: arg_ty = {:?}",
105 tcx
.any_free_region_meets(arg_ty
, |r
| r
.to_region_vid() == fr
)
109 "get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
110 fr
, argument_index
, self.universal_regions
.unnormalized_input_tys
[argument_index
],
116 /// Given the index of an argument, finds its name (if any) and the span from where it was
118 crate fn get_argument_name_and_span_for_region(
121 local_names
: &IndexVec
<Local
, Option
<Symbol
>>,
122 argument_index
: usize,
123 ) -> (Option
<Symbol
>, Span
) {
124 let implicit_inputs
= self.universal_regions
.defining_ty
.implicit_inputs();
125 let argument_local
= Local
::new(implicit_inputs
+ argument_index
+ 1);
126 debug
!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local
);
128 let argument_name
= local_names
[argument_local
];
129 let argument_span
= body
.local_decls
[argument_local
].source_info
.span
;
130 debug
!("get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
131 argument_name
, argument_span
);
133 (argument_name
, argument_span
)