]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_borrowck/src/renumber.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / compiler / rustc_borrowck / src / renumber.rs
CommitLineData
487cf647
FG
1#![deny(rustc::untranslatable_diagnostic)]
2#![deny(rustc::diagnostic_outside_of_impl)]
9ffffee4 3use crate::BorrowckInferCtxt;
49aad941 4use rustc_index::IndexSlice;
9ffffee4 5use rustc_infer::infer::NllRegionVariableOrigin;
ba9703b0 6use rustc_middle::mir::visit::{MutVisitor, TyContext};
781aab86 7use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
add651ee 8use rustc_middle::ty::GenericArgsRef;
ba9703b0 9use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
781aab86 10use 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 15pub 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)]
32pub(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
43impl 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 58struct RegionRenumberer<'a, 'tcx> {
9ffffee4 59 infcx: &'a BorrowckInferCtxt<'a, 'tcx>,
ff7c6d11
XL
60}
61
353b0b11
FG
62impl<'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 77impl<'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}