]>
Commit | Line | Data |
---|---|---|
e74abb32 | 1 | use rustc_index::vec::IndexVec; |
5869c6ff | 2 | use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; |
ba9703b0 | 3 | use rustc_middle::mir::visit::{MutVisitor, TyContext}; |
a2a8927a | 4 | use rustc_middle::mir::{Body, Location, Promoted}; |
f2b60f7d | 5 | use rustc_middle::mir::{Constant, ConstantKind}; |
ba9703b0 XL |
6 | use rustc_middle::ty::subst::SubstsRef; |
7 | use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; | |
ff7c6d11 XL |
8 | |
9 | /// Replaces all free regions appearing in the MIR with fresh | |
10 | /// inference variables, returning the number of variables created. | |
c295e0f8 | 11 | #[instrument(skip(infcx, body, promoted), level = "debug")] |
e1599b0c XL |
12 | pub fn renumber_mir<'tcx>( |
13 | infcx: &InferCtxt<'_, 'tcx>, | |
f9f354fc XL |
14 | body: &mut Body<'tcx>, |
15 | promoted: &mut IndexVec<Promoted, Body<'tcx>>, | |
e1599b0c | 16 | ) { |
c295e0f8 | 17 | debug!(?body.arg_count); |
ff7c6d11 | 18 | |
5869c6ff | 19 | let mut visitor = NllVisitor { infcx }; |
e1599b0c XL |
20 | |
21 | for body in promoted.iter_mut() { | |
22 | visitor.visit_body(body); | |
23 | } | |
24 | ||
dc9dc135 | 25 | visitor.visit_body(body); |
ff7c6d11 XL |
26 | } |
27 | ||
28 | /// Replaces all regions appearing in `value` with fresh inference | |
29 | /// variables. | |
c295e0f8 | 30 | #[instrument(skip(infcx), level = "debug")] |
fc512014 | 31 | pub fn renumber_regions<'tcx, T>(infcx: &InferCtxt<'_, 'tcx>, value: T) -> T |
ff7c6d11 XL |
32 | where |
33 | T: TypeFoldable<'tcx>, | |
34 | { | |
064997fb | 35 | infcx.tcx.fold_regions(value, |_region, _depth| { |
5869c6ff | 36 | let origin = NllRegionVariableOrigin::Existential { from_forall: false }; |
dfeec247 XL |
37 | infcx.next_nll_region_var(origin) |
38 | }) | |
ff7c6d11 XL |
39 | } |
40 | ||
f2b60f7d FG |
41 | // FIXME(valtrees): This function is necessary because `fold_regions` |
42 | // panics for mir constants in the visitor. | |
43 | // | |
44 | // Once `visit_mir_constant` is removed we can also remove this function | |
45 | // and just use `renumber_regions`. | |
46 | fn renumber_regions_in_mir_constant<'tcx>( | |
47 | infcx: &InferCtxt<'_, 'tcx>, | |
48 | value: ConstantKind<'tcx>, | |
49 | ) -> ConstantKind<'tcx> { | |
50 | infcx.tcx.super_fold_regions(value, |_region, _depth| { | |
51 | let origin = NllRegionVariableOrigin::Existential { from_forall: false }; | |
52 | infcx.next_nll_region_var(origin) | |
53 | }) | |
54 | } | |
55 | ||
5869c6ff | 56 | struct NllVisitor<'a, 'tcx> { |
dc9dc135 | 57 | infcx: &'a InferCtxt<'a, 'tcx>, |
ff7c6d11 XL |
58 | } |
59 | ||
5869c6ff | 60 | impl<'a, 'tcx> NllVisitor<'a, 'tcx> { |
fc512014 | 61 | fn renumber_regions<T>(&mut self, value: T) -> T |
ff7c6d11 XL |
62 | where |
63 | T: TypeFoldable<'tcx>, | |
64 | { | |
8faf50e0 | 65 | renumber_regions(self.infcx, value) |
ff7c6d11 | 66 | } |
f2b60f7d FG |
67 | |
68 | fn renumber_regions_in_mir_constant( | |
69 | &mut self, | |
70 | value: ConstantKind<'tcx>, | |
71 | ) -> ConstantKind<'tcx> { | |
72 | renumber_regions_in_mir_constant(self.infcx, value) | |
73 | } | |
ff7c6d11 XL |
74 | } |
75 | ||
5869c6ff | 76 | impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { |
e74abb32 XL |
77 | fn tcx(&self) -> TyCtxt<'tcx> { |
78 | self.infcx.tcx | |
79 | } | |
80 | ||
c295e0f8 | 81 | #[instrument(skip(self), level = "debug")] |
ff7c6d11 | 82 | fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) { |
5099ac24 | 83 | *ty = self.renumber_regions(*ty); |
ff7c6d11 | 84 | |
c295e0f8 | 85 | debug!(?ty); |
ff7c6d11 XL |
86 | } |
87 | ||
c295e0f8 | 88 | #[instrument(skip(self), level = "debug")] |
532ac7d7 | 89 | fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) { |
fc512014 | 90 | *substs = self.renumber_regions(*substs); |
ff7c6d11 | 91 | |
c295e0f8 | 92 | debug!(?substs); |
ff7c6d11 XL |
93 | } |
94 | ||
c295e0f8 | 95 | #[instrument(skip(self), level = "debug")] |
ff7c6d11 | 96 | fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) { |
ff7c6d11 | 97 | let old_region = *region; |
5099ac24 | 98 | *region = self.renumber_regions(old_region); |
ff7c6d11 | 99 | |
c295e0f8 | 100 | debug!(?region); |
ff7c6d11 XL |
101 | } |
102 | ||
f2b60f7d FG |
103 | #[instrument(skip(self), level = "debug")] |
104 | fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) { | |
105 | let literal = constant.literal; | |
106 | constant.literal = self.renumber_regions_in_mir_constant(literal); | |
107 | debug!("constant: {:#?}", constant); | |
ff7c6d11 | 108 | } |
ff7c6d11 | 109 | } |