]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_borrowck/src/diagnostics/var_name.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / compiler / rustc_borrowck / src / diagnostics / var_name.rs
CommitLineData
c295e0f8
XL
1use crate::Upvar;
2use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext};
60c5eb7d 3use rustc_index::vec::{Idx, IndexVec};
ba9703b0
XL
4use rustc_middle::mir::{Body, Local};
5use rustc_middle::ty::{RegionVid, TyCtxt};
dfeec247
XL
6use rustc_span::source_map::Span;
7use rustc_span::symbol::Symbol;
8faf50e0
XL
8
9impl<'tcx> RegionInferenceContext<'tcx> {
923072b8 10 pub(crate) fn get_var_name_and_span_for_region(
8faf50e0 11 &self,
dc9dc135
XL
12 tcx: TyCtxt<'tcx>,
13 body: &Body<'tcx>,
60c5eb7d 14 local_names: &IndexVec<Local, Option<Symbol>>,
5869c6ff 15 upvars: &[Upvar<'tcx>],
8faf50e0
XL
16 fr: RegionVid,
17 ) -> Option<(Option<Symbol>, Span)> {
18 debug!("get_var_name_and_span_for_region(fr={:?})", fr);
dfeec247 19 assert!(self.universal_regions().is_universal_region(fr));
8faf50e0
XL
20
21 debug!("get_var_name_and_span_for_region: attempting upvar");
22 self.get_upvar_index_for_region(tcx, fr)
23 .map(|index| {
5869c6ff 24 // FIXME(project-rfc-2229#8): Use place span for diagnostics
dfeec247 25 let (name, span) = self.get_upvar_name_and_span_for_region(tcx, upvars, index);
8faf50e0
XL
26 (Some(name), span)
27 })
28 .or_else(|| {
29 debug!("get_var_name_and_span_for_region: attempting argument");
60c5eb7d
XL
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 })
8faf50e0
XL
33 })
34 }
35
36 /// Search the upvars (if any) to find one that references fr. Return its index.
923072b8
FG
37 pub(crate) fn get_upvar_index_for_region(
38 &self,
39 tcx: TyCtxt<'tcx>,
40 fr: RegionVid,
41 ) -> Option<usize> {
dfeec247 42 let upvar_index =
ba9703b0 43 self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| {
0bf4aa26
XL
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);
48 r == fr
49 })
8faf50e0
XL
50 })?;
51
ba9703b0 52 let upvar_ty = self.universal_regions().defining_ty.upvar_tys().nth(upvar_index);
8faf50e0
XL
53
54 debug!(
55 "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
56 fr, upvar_index, upvar_ty,
57 );
58
59 Some(upvar_index)
60 }
61
62 /// Given the index of an upvar, finds its name and the span from where it was
63 /// declared.
923072b8 64 pub(crate) fn get_upvar_name_and_span_for_region(
8faf50e0 65 &self,
dc9dc135 66 tcx: TyCtxt<'tcx>,
5869c6ff 67 upvars: &[Upvar<'tcx>],
8faf50e0
XL
68 upvar_index: usize,
69 ) -> (Symbol, Span) {
5869c6ff 70 let upvar_hir_id = upvars[upvar_index].place.get_root_variable();
9fa01778 71 debug!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id);
8faf50e0 72
dc9dc135
XL
73 let upvar_name = tcx.hir().name(upvar_hir_id);
74 let upvar_span = tcx.hir().span(upvar_hir_id);
dfeec247
XL
75 debug!(
76 "get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
77 upvar_name, upvar_span
78 );
8faf50e0
XL
79
80 (upvar_name, upvar_span)
81 }
82
83 /// Search the argument types for one that references fr (which should be a free region).
84 /// Returns Some(_) with the index of the input if one is found.
85 ///
0731742a 86 /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
8faf50e0 87 /// user - in particular, index 0 is not the implicit self parameter.
923072b8 88 pub(crate) fn get_argument_index_for_region(
8faf50e0 89 &self,
dc9dc135 90 tcx: TyCtxt<'tcx>,
8faf50e0
XL
91 fr: RegionVid,
92 ) -> Option<usize> {
dfeec247
XL
93 let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
94 let argument_index =
95 self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position(
96 |arg_ty| {
97 debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty);
98 tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
99 },
100 )?;
8faf50e0
XL
101
102 debug!(
103 "get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
dfeec247
XL
104 fr,
105 argument_index,
106 self.universal_regions().unnormalized_input_tys[argument_index],
8faf50e0
XL
107 );
108
109 Some(argument_index)
110 }
111
112 /// Given the index of an argument, finds its name (if any) and the span from where it was
113 /// declared.
923072b8 114 pub(crate) fn get_argument_name_and_span_for_region(
8faf50e0 115 &self,
dc9dc135 116 body: &Body<'tcx>,
60c5eb7d 117 local_names: &IndexVec<Local, Option<Symbol>>,
8faf50e0
XL
118 argument_index: usize,
119 ) -> (Option<Symbol>, Span) {
dfeec247 120 let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
8faf50e0
XL
121 let argument_local = Local::new(implicit_inputs + argument_index + 1);
122 debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
123
60c5eb7d 124 let argument_name = local_names[argument_local];
dc9dc135 125 let argument_span = body.local_decls[argument_local].source_info.span;
dfeec247
XL
126 debug!(
127 "get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
128 argument_name, argument_span
129 );
8faf50e0
XL
130
131 (argument_name, argument_span)
132 }
8faf50e0 133}