1 use crate::borrow_check::nll::region_infer::RegionInferenceContext;
2 use crate::borrow_check::nll::ToRegionVid;
3 use crate::borrow_check::Upvar;
4 use rustc::mir::{Local, Body};
5 use rustc::ty::{RegionVid, TyCtxt};
6 use rustc_index::vec::{Idx, IndexVec};
7 use syntax::source_map::Span;
8 use syntax_pos::symbol::Symbol;
10 impl<'tcx> RegionInferenceContext<'tcx> {
11 crate fn get_var_name_and_span_for_region(
15 local_names: &IndexVec<Local, Option<Symbol>>,
18 ) -> Option<(Option<Symbol>, Span)> {
19 debug!("get_var_name_and_span_for_region(fr={:?})", fr);
20 assert!(self.universal_regions.is_universal_region(fr));
22 debug!("get_var_name_and_span_for_region: attempting upvar");
23 self.get_upvar_index_for_region(tcx, fr)
26 self.get_upvar_name_and_span_for_region(tcx, upvars, index);
30 debug!("get_var_name_and_span_for_region: attempting argument");
31 self.get_argument_index_for_region(tcx, fr).map(|index| {
32 self.get_argument_name_and_span_for_region(body, local_names, index)
37 /// Search the upvars (if any) to find one that references fr. Return its index.
38 crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option<usize> {
39 let upvar_index = self
43 .position(|upvar_ty| {
44 debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty);
45 tcx.any_free_region_meets(&upvar_ty, |r| {
46 let r = r.to_region_vid();
47 debug!("get_upvar_index_for_region: r={:?} fr={:?}", r, fr);
59 "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
60 fr, upvar_index, upvar_ty,
66 /// Given the index of an upvar, finds its name and the span from where it was
68 crate fn get_upvar_name_and_span_for_region(
74 let upvar_hir_id = upvars[upvar_index].var_hir_id;
75 debug!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id);
77 let upvar_name = tcx.hir().name(upvar_hir_id);
78 let upvar_span = tcx.hir().span(upvar_hir_id);
79 debug!("get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
80 upvar_name, upvar_span);
82 (upvar_name, upvar_span)
85 /// Search the argument types for one that references fr (which should be a free region).
86 /// Returns Some(_) with the index of the input if one is found.
88 /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
89 /// user - in particular, index 0 is not the implicit self parameter.
90 crate fn get_argument_index_for_region(
95 let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
96 let argument_index = self
98 .unnormalized_input_tys
100 .skip(implicit_inputs)
103 "get_argument_index_for_region: arg_ty = {:?}",
106 tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
110 "get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
111 fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
117 /// Given the index of an argument, finds its name (if any) and the span from where it was
119 crate fn get_argument_name_and_span_for_region(
122 local_names: &IndexVec<Local, Option<Symbol>>,
123 argument_index: usize,
124 ) -> (Option<Symbol>, Span) {
125 let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
126 let argument_local = Local::new(implicit_inputs + argument_index + 1);
127 debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
129 let argument_name = local_names[argument_local];
130 let argument_span = body.local_decls[argument_local].source_info.span;
131 debug!("get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
132 argument_name, argument_span);
134 (argument_name, argument_span)