1 #![deny(rustc::untranslatable_diagnostic)]
2 #![deny(rustc::diagnostic_outside_of_impl)]
5 use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext};
6 use rustc_index::vec::{Idx, IndexVec};
7 use rustc_middle::mir::{Body, Local};
8 use rustc_middle::ty::{RegionVid, TyCtxt};
9 use rustc_span::source_map::Span;
10 use rustc_span::symbol::Symbol;
12 impl<'tcx> RegionInferenceContext<'tcx> {
13 pub(crate) fn get_var_name_and_span_for_region(
17 local_names: &IndexVec<Local, Option<Symbol>>,
18 upvars: &[Upvar<'tcx>],
20 ) -> Option<(Option<Symbol>, Span)> {
21 debug!("get_var_name_and_span_for_region(fr={:?})", fr);
22 assert!(self.universal_regions().is_universal_region(fr));
24 debug!("get_var_name_and_span_for_region: attempting upvar");
25 self.get_upvar_index_for_region(tcx, fr)
27 // FIXME(project-rfc-2229#8): Use place span for diagnostics
28 let (name, span) = self.get_upvar_name_and_span_for_region(tcx, upvars, index);
32 debug!("get_var_name_and_span_for_region: attempting argument");
33 self.get_argument_index_for_region(tcx, fr).map(|index| {
34 self.get_argument_name_and_span_for_region(body, local_names, index)
39 /// Search the upvars (if any) to find one that references fr. Return its index.
40 pub(crate) fn get_upvar_index_for_region(
46 self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| {
47 debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty);
48 tcx.any_free_region_meets(&upvar_ty, |r| {
49 let r = r.to_region_vid();
50 debug!("get_upvar_index_for_region: r={:?} fr={:?}", r, fr);
55 let upvar_ty = self.universal_regions().defining_ty.upvar_tys().nth(upvar_index);
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 pub(crate) fn get_upvar_name_and_span_for_region(
70 upvars: &[Upvar<'tcx>],
73 let upvar_hir_id = upvars[upvar_index].place.get_root_variable();
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);
79 "get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
80 upvar_name, upvar_span
83 (upvar_name, upvar_span)
86 /// Search the argument types for one that references fr (which should be a free region).
87 /// Returns Some(_) with the index of the input if one is found.
89 /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
90 /// user - in particular, index 0 is not the implicit self parameter.
91 pub(crate) fn get_argument_index_for_region(
96 let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
98 self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position(
100 debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty);
101 tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
106 "get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
109 self.universal_regions().unnormalized_input_tys[argument_index],
115 /// Given the index of an argument, finds its name (if any) and the span from where it was
117 pub(crate) fn get_argument_name_and_span_for_region(
120 local_names: &IndexVec<Local, Option<Symbol>>,
121 argument_index: usize,
122 ) -> (Option<Symbol>, Span) {
123 let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
124 let argument_local = Local::new(implicit_inputs + argument_index + 1);
125 debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
127 let argument_name = local_names[argument_local];
128 let argument_span = body.local_decls[argument_local].source_info.span;
130 "get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
131 argument_name, argument_span
134 (argument_name, argument_span)