]>
Commit | Line | Data |
---|---|---|
e74abb32 | 1 | use rustc_index::vec::IndexVec; |
74b04a01 | 2 | use rustc_infer::infer::{InferCtxt, NLLRegionVariableOrigin}; |
ba9703b0 | 3 | use rustc_middle::mir::visit::{MutVisitor, TyContext}; |
f9f354fc | 4 | use rustc_middle::mir::{Body, Location, PlaceElem, Promoted}; |
ba9703b0 XL |
5 | use rustc_middle::ty::subst::SubstsRef; |
6 | use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; | |
ff7c6d11 XL |
7 | |
8 | /// Replaces all free regions appearing in the MIR with fresh | |
9 | /// inference variables, returning the number of variables created. | |
e1599b0c XL |
10 | pub fn renumber_mir<'tcx>( |
11 | infcx: &InferCtxt<'_, 'tcx>, | |
f9f354fc XL |
12 | body: &mut Body<'tcx>, |
13 | promoted: &mut IndexVec<Promoted, Body<'tcx>>, | |
e1599b0c | 14 | ) { |
ff7c6d11 | 15 | debug!("renumber_mir()"); |
dc9dc135 | 16 | debug!("renumber_mir: body.arg_count={:?}", body.arg_count); |
ff7c6d11 XL |
17 | |
18 | let mut visitor = NLLVisitor { infcx }; | |
e1599b0c XL |
19 | |
20 | for body in promoted.iter_mut() { | |
21 | visitor.visit_body(body); | |
22 | } | |
23 | ||
dc9dc135 | 24 | visitor.visit_body(body); |
ff7c6d11 XL |
25 | } |
26 | ||
27 | /// Replaces all regions appearing in `value` with fresh inference | |
28 | /// variables. | |
fc512014 | 29 | pub fn renumber_regions<'tcx, T>(infcx: &InferCtxt<'_, 'tcx>, value: T) -> T |
ff7c6d11 XL |
30 | where |
31 | T: TypeFoldable<'tcx>, | |
32 | { | |
33 | debug!("renumber_regions(value={:?})", value); | |
34 | ||
dfeec247 XL |
35 | infcx.tcx.fold_regions(value, &mut false, |_region, _depth| { |
36 | let origin = NLLRegionVariableOrigin::Existential { from_forall: false }; | |
37 | infcx.next_nll_region_var(origin) | |
38 | }) | |
ff7c6d11 XL |
39 | } |
40 | ||
dc9dc135 XL |
41 | struct NLLVisitor<'a, 'tcx> { |
42 | infcx: &'a InferCtxt<'a, 'tcx>, | |
ff7c6d11 XL |
43 | } |
44 | ||
dc9dc135 | 45 | impl<'a, 'tcx> NLLVisitor<'a, 'tcx> { |
fc512014 | 46 | fn renumber_regions<T>(&mut self, value: T) -> T |
ff7c6d11 XL |
47 | where |
48 | T: TypeFoldable<'tcx>, | |
49 | { | |
8faf50e0 | 50 | renumber_regions(self.infcx, value) |
ff7c6d11 XL |
51 | } |
52 | } | |
53 | ||
dc9dc135 | 54 | impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> { |
e74abb32 XL |
55 | fn tcx(&self) -> TyCtxt<'tcx> { |
56 | self.infcx.tcx | |
57 | } | |
58 | ||
ff7c6d11 XL |
59 | fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) { |
60 | debug!("visit_ty(ty={:?}, ty_context={:?})", ty, ty_context); | |
61 | ||
8faf50e0 | 62 | *ty = self.renumber_regions(ty); |
ff7c6d11 XL |
63 | |
64 | debug!("visit_ty: ty={:?}", ty); | |
65 | } | |
66 | ||
ba9703b0 XL |
67 | fn process_projection_elem( |
68 | &mut self, | |
f9f354fc | 69 | elem: PlaceElem<'tcx>, |
ba9703b0 XL |
70 | _: Location, |
71 | ) -> Option<PlaceElem<'tcx>> { | |
e74abb32 | 72 | if let PlaceElem::Field(field, ty) = elem { |
fc512014 | 73 | let new_ty = self.renumber_regions(ty); |
e74abb32 | 74 | |
f9f354fc XL |
75 | if new_ty != ty { |
76 | return Some(PlaceElem::Field(field, new_ty)); | |
e74abb32 XL |
77 | } |
78 | } | |
79 | ||
80 | None | |
81 | } | |
82 | ||
532ac7d7 | 83 | fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) { |
ff7c6d11 XL |
84 | debug!("visit_substs(substs={:?}, location={:?})", substs, location); |
85 | ||
fc512014 | 86 | *substs = self.renumber_regions(*substs); |
ff7c6d11 XL |
87 | |
88 | debug!("visit_substs: substs={:?}", substs); | |
89 | } | |
90 | ||
91 | fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) { | |
92 | debug!("visit_region(region={:?}, location={:?})", region, location); | |
93 | ||
94 | let old_region = *region; | |
8faf50e0 | 95 | *region = self.renumber_regions(&old_region); |
ff7c6d11 XL |
96 | |
97 | debug!("visit_region: region={:?}", region); | |
98 | } | |
99 | ||
532ac7d7 | 100 | fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _location: Location) { |
8faf50e0 | 101 | *constant = self.renumber_regions(&*constant); |
ff7c6d11 | 102 | } |
ff7c6d11 | 103 | } |