]>
Commit | Line | Data |
---|---|---|
487cf647 FG |
1 | #![deny(rustc::untranslatable_diagnostic)] |
2 | #![deny(rustc::diagnostic_outside_of_impl)] | |
9ffffee4 | 3 | use crate::BorrowckInferCtxt; |
49aad941 | 4 | use rustc_index::IndexSlice; |
9ffffee4 | 5 | use rustc_infer::infer::NllRegionVariableOrigin; |
ba9703b0 | 6 | use rustc_middle::mir::visit::{MutVisitor, TyContext}; |
781aab86 | 7 | use rustc_middle::mir::{Body, ConstOperand, Location, Promoted}; |
add651ee | 8 | use rustc_middle::ty::GenericArgsRef; |
ba9703b0 | 9 | use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; |
781aab86 | 10 | use rustc_span::Symbol; |
ff7c6d11 XL |
11 | |
12 | /// Replaces all free regions appearing in the MIR with fresh | |
13 | /// inference variables, returning the number of variables created. | |
c295e0f8 | 14 | #[instrument(skip(infcx, body, promoted), level = "debug")] |
e1599b0c | 15 | pub fn renumber_mir<'tcx>( |
9ffffee4 | 16 | infcx: &BorrowckInferCtxt<'_, 'tcx>, |
f9f354fc | 17 | body: &mut Body<'tcx>, |
353b0b11 | 18 | promoted: &mut IndexSlice<Promoted, Body<'tcx>>, |
e1599b0c | 19 | ) { |
c295e0f8 | 20 | debug!(?body.arg_count); |
ff7c6d11 | 21 | |
353b0b11 | 22 | let mut renumberer = RegionRenumberer { infcx }; |
e1599b0c XL |
23 | |
24 | for body in promoted.iter_mut() { | |
353b0b11 | 25 | renumberer.visit_body(body); |
e1599b0c XL |
26 | } |
27 | ||
353b0b11 | 28 | renumberer.visit_body(body); |
ff7c6d11 XL |
29 | } |
30 | ||
9ffffee4 FG |
31 | #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] |
32 | pub(crate) enum RegionCtxt { | |
33 | Location(Location), | |
34 | TyContext(TyContext), | |
35 | Free(Symbol), | |
781aab86 FG |
36 | Bound(Symbol), |
37 | LateBound(Symbol), | |
9ffffee4 | 38 | Existential(Option<Symbol>), |
781aab86 | 39 | Placeholder(Symbol), |
9ffffee4 FG |
40 | Unknown, |
41 | } | |
42 | ||
43 | impl RegionCtxt { | |
44 | /// Used to determine the representative of a component in the strongly connected | |
45 | /// constraint graph | |
46 | pub(crate) fn preference_value(self) -> usize { | |
9ffffee4 FG |
47 | match self { |
48 | RegionCtxt::Unknown => 1, | |
49 | RegionCtxt::Existential(None) => 2, | |
353b0b11 | 50 | RegionCtxt::Existential(Some(_)) | RegionCtxt::Free(_) => 2, |
9ffffee4 FG |
51 | RegionCtxt::Location(_) => 3, |
52 | RegionCtxt::TyContext(_) => 4, | |
53 | _ => 5, | |
54 | } | |
55 | } | |
56 | } | |
57 | ||
353b0b11 | 58 | struct RegionRenumberer<'a, 'tcx> { |
9ffffee4 | 59 | infcx: &'a BorrowckInferCtxt<'a, 'tcx>, |
ff7c6d11 XL |
60 | } |
61 | ||
353b0b11 FG |
62 | impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> { |
63 | /// Replaces all regions appearing in `value` with fresh inference | |
64 | /// variables. | |
9ffffee4 | 65 | fn renumber_regions<T, F>(&mut self, value: T, region_ctxt_fn: F) -> T |
ff7c6d11 | 66 | where |
9ffffee4 FG |
67 | T: TypeFoldable<TyCtxt<'tcx>>, |
68 | F: Fn() -> RegionCtxt, | |
ff7c6d11 | 69 | { |
353b0b11 FG |
70 | let origin = NllRegionVariableOrigin::Existential { from_forall: false }; |
71 | self.infcx.tcx.fold_regions(value, |_region, _depth| { | |
72 | self.infcx.next_nll_region_var(origin, || region_ctxt_fn()) | |
73 | }) | |
ff7c6d11 XL |
74 | } |
75 | } | |
76 | ||
353b0b11 | 77 | impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> { |
e74abb32 XL |
78 | fn tcx(&self) -> TyCtxt<'tcx> { |
79 | self.infcx.tcx | |
80 | } | |
81 | ||
c295e0f8 | 82 | #[instrument(skip(self), level = "debug")] |
ff7c6d11 | 83 | fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) { |
9ffffee4 | 84 | *ty = self.renumber_regions(*ty, || RegionCtxt::TyContext(ty_context)); |
ff7c6d11 | 85 | |
c295e0f8 | 86 | debug!(?ty); |
ff7c6d11 XL |
87 | } |
88 | ||
c295e0f8 | 89 | #[instrument(skip(self), level = "debug")] |
add651ee FG |
90 | fn visit_args(&mut self, args: &mut GenericArgsRef<'tcx>, location: Location) { |
91 | *args = self.renumber_regions(*args, || RegionCtxt::Location(location)); | |
ff7c6d11 | 92 | |
add651ee | 93 | debug!(?args); |
ff7c6d11 XL |
94 | } |
95 | ||
c295e0f8 | 96 | #[instrument(skip(self), level = "debug")] |
ff7c6d11 | 97 | fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) { |
ff7c6d11 | 98 | let old_region = *region; |
9ffffee4 | 99 | *region = self.renumber_regions(old_region, || RegionCtxt::Location(location)); |
ff7c6d11 | 100 | |
c295e0f8 | 101 | debug!(?region); |
ff7c6d11 XL |
102 | } |
103 | ||
49aad941 FG |
104 | #[instrument(skip(self), level = "debug")] |
105 | fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, location: Location) { | |
106 | let old_ct = *ct; | |
107 | *ct = self.renumber_regions(old_ct, || RegionCtxt::Location(location)); | |
108 | ||
109 | debug!(?ct); | |
110 | } | |
111 | ||
f2b60f7d | 112 | #[instrument(skip(self), level = "debug")] |
781aab86 FG |
113 | fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) { |
114 | let const_ = constant.const_; | |
115 | constant.const_ = self.renumber_regions(const_, || RegionCtxt::Location(location)); | |
f2b60f7d | 116 | debug!("constant: {:#?}", constant); |
ff7c6d11 | 117 | } |
ff7c6d11 | 118 | } |