rustc_borrowck/diagnostics/
var_name.rs
1use rustc_index::IndexSlice;
2use rustc_middle::mir::{Body, Local};
3use rustc_middle::ty::{self, RegionVid, TyCtxt};
4use rustc_span::{Span, Symbol};
5use tracing::debug;
6
7use crate::region_infer::RegionInferenceContext;
8
9impl<'tcx> RegionInferenceContext<'tcx> {
10 pub(crate) fn get_var_name_and_span_for_region(
11 &self,
12 tcx: TyCtxt<'tcx>,
13 body: &Body<'tcx>,
14 local_names: &IndexSlice<Local, Option<Symbol>>,
15 upvars: &[&ty::CapturedPlace<'tcx>],
16 fr: RegionVid,
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));
20
21 debug!("get_var_name_and_span_for_region: attempting upvar");
22 self.get_upvar_index_for_region(tcx, fr)
23 .map(|index| {
24 let (name, span) = self.get_upvar_name_and_span_for_region(tcx, upvars, index);
26 (Some(name), span)
27 })
28 .or_else(|| {
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)
32 })
33 })
34 }
35
36 pub(crate) fn get_upvar_index_for_region(
38 &self,
39 tcx: TyCtxt<'tcx>,
40 fr: RegionVid,
41 ) -> Option<usize> {
42 let upvar_index =
43 self.universal_regions().defining_ty.upvar_tys().iter().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.as_var();
47 debug!("get_upvar_index_for_region: r={r:?} fr={fr:?}");
48 r == fr
49 })
50 })?;
51
52 let upvar_ty = self.universal_regions().defining_ty.upvar_tys().get(upvar_index);
53
54 debug!(
55 "get_upvar_index_for_region: found {fr:?} in upvar {upvar_index} which has type {upvar_ty:?}",
56 );
57
58 Some(upvar_index)
59 }
60
61 pub(crate) fn get_upvar_name_and_span_for_region(
64 &self,
65 tcx: TyCtxt<'tcx>,
66 upvars: &[&ty::CapturedPlace<'tcx>],
67 upvar_index: usize,
68 ) -> (Symbol, Span) {
69 let upvar_hir_id = upvars[upvar_index].get_root_variable();
70 debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}");
71
72 let upvar_name = tcx.hir().name(upvar_hir_id);
73 let upvar_span = tcx.hir().span(upvar_hir_id);
74 debug!(
75 "get_upvar_name_and_span_for_region: upvar_name={upvar_name:?} upvar_span={upvar_span:?}",
76 );
77
78 (upvar_name, upvar_span)
79 }
80
81 pub(crate) fn get_argument_index_for_region(
87 &self,
88 tcx: TyCtxt<'tcx>,
89 fr: RegionVid,
90 ) -> Option<usize> {
91 let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
92 let argument_index =
93 self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position(
94 |arg_ty| {
95 debug!("get_argument_index_for_region: arg_ty = {arg_ty:?}");
96 tcx.any_free_region_meets(arg_ty, |r| r.as_var() == fr)
97 },
98 )?;
99
100 debug!(
101 "get_argument_index_for_region: found {fr:?} in argument {argument_index} which has type {:?}",
102 self.universal_regions().unnormalized_input_tys[argument_index],
103 );
104
105 Some(argument_index)
106 }
107
108 pub(crate) fn get_argument_name_and_span_for_region(
111 &self,
112 body: &Body<'tcx>,
113 local_names: &IndexSlice<Local, Option<Symbol>>,
114 argument_index: usize,
115 ) -> (Option<Symbol>, Span) {
116 let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
117 let argument_local = Local::from_usize(implicit_inputs + argument_index + 1);
118 debug!("get_argument_name_and_span_for_region: argument_local={argument_local:?}");
119
120 let argument_name = local_names[argument_local];
121 let argument_span = body.local_decls[argument_local].source_info.span;
122 debug!(
123 "get_argument_name_and_span_for_region: argument_name={argument_name:?} argument_span={argument_span:?}",
124 );
125
126 (argument_name, argument_span)
127 }
128}