rustc_mir_transform/
post_analysis_normalize.rs1use rustc_middle::mir::visit::*;
6use rustc_middle::mir::*;
7use rustc_middle::ty::{self, Ty, TyCtxt};
8
9use crate::PassPolicy;
10
11pub(super) struct PostAnalysisNormalize;
12
13impl<'tcx> crate::MirPass<'tcx> for PostAnalysisNormalize {
14 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
15 let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
18 PostAnalysisNormalizeVisitor { tcx, typing_env }.visit_body_preserves_cfg(body);
19 }
20
21 fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
22 PassPolicy::Required
24 }
25}
26
27struct PostAnalysisNormalizeVisitor<'tcx> {
28 tcx: TyCtxt<'tcx>,
29 typing_env: ty::TypingEnv<'tcx>,
30}
31
32impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> {
33 #[inline]
34 fn tcx(&self) -> TyCtxt<'tcx> {
35 self.tcx
36 }
37
38 #[inline]
39 fn visit_place(
40 &mut self,
41 place: &mut Place<'tcx>,
42 _context: PlaceContext,
43 _location: Location,
44 ) {
45 if !self.tcx.next_trait_solver_globally() {
46 if place.projection.iter().any(|elem| matches!(elem, ProjectionElem::OpaqueCast(_))) {
52 place.projection = self.tcx.mk_place_elems(
53 &place
54 .projection
55 .into_iter()
56 .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
57 .collect::<Vec<_>>(),
58 );
59 };
60 }
61 self.super_place(place, _context, _location);
62 }
63
64 #[inline]
65 fn visit_const_operand(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
66 if let Ok(c) = self.tcx.try_normalize_erasing_regions(
70 self.typing_env,
71 ty::set_aliases_to_non_rigid(self.tcx, constant.const_),
72 ) {
73 constant.const_ = c;
74 }
75 self.super_const_operand(constant, location);
76 }
77
78 #[inline]
79 fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
80 if let Ok(t) = self.tcx.try_normalize_erasing_regions(
84 self.typing_env,
85 ty::set_aliases_to_non_rigid(self.tcx, *ty),
86 ) {
87 *ty = t;
88 }
89 }
90
91 #[inline]
92 fn visit_args(&mut self, args: &mut ty::GenericArgsRef<'tcx>, _: Location) {
93 if let Ok(a) = self.tcx.try_normalize_erasing_regions(
94 self.typing_env,
95 ty::set_aliases_to_non_rigid(self.tcx, *args),
96 ) {
97 *args = a;
98 }
99 }
100}