]>
Commit | Line | Data |
---|---|---|
c295e0f8 XL |
1 | use crate::Upvar; |
2 | use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; | |
60c5eb7d | 3 | use rustc_index::vec::{Idx, IndexVec}; |
ba9703b0 XL |
4 | use rustc_middle::mir::{Body, Local}; |
5 | use rustc_middle::ty::{RegionVid, TyCtxt}; | |
dfeec247 XL |
6 | use rustc_span::source_map::Span; |
7 | use rustc_span::symbol::Symbol; | |
8faf50e0 XL |
8 | |
9 | impl<'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 | } |