rustc_mir_transform/
post_analysis_normalize.rs
1use rustc_middle::mir::visit::*;
6use rustc_middle::mir::*;
7use rustc_middle::ty::{self, Ty, TyCtxt};
8
9pub(super) struct PostAnalysisNormalize;
10
11impl<'tcx> crate::MirPass<'tcx> for PostAnalysisNormalize {
12 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
13 let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
16 PostAnalysisNormalizeVisitor { tcx, typing_env }.visit_body_preserves_cfg(body);
17 }
18
19 fn is_required(&self) -> bool {
20 true
21 }
22}
23
24struct PostAnalysisNormalizeVisitor<'tcx> {
25 tcx: TyCtxt<'tcx>,
26 typing_env: ty::TypingEnv<'tcx>,
27}
28
29impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> {
30 #[inline]
31 fn tcx(&self) -> TyCtxt<'tcx> {
32 self.tcx
33 }
34
35 #[inline]
36 fn visit_place(
37 &mut self,
38 place: &mut Place<'tcx>,
39 _context: PlaceContext,
40 _location: Location,
41 ) {
42 if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
44 return;
45 }
46 place.projection = self.tcx.mk_place_elems(
50 &place
51 .projection
52 .into_iter()
53 .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
54 .collect::<Vec<_>>(),
55 );
56 self.super_place(place, _context, _location);
57 }
58
59 #[inline]
60 fn visit_const_operand(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
61 if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.typing_env, constant.const_) {
65 constant.const_ = c;
66 }
67 self.super_const_operand(constant, location);
68 }
69
70 #[inline]
71 fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
72 if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.typing_env, *ty) {
76 *ty = t;
77 }
78 }
79}