]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_mir_transform/src/reveal_all.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / compiler / rustc_mir_transform / src / reveal_all.rs
1 //! Normalizes MIR in RevealAll mode.
2
3 use crate::MirPass;
4 use rustc_middle::mir::visit::*;
5 use rustc_middle::mir::*;
6 use rustc_middle::ty::{self, Ty, TyCtxt};
7
8 pub struct RevealAll;
9
10 impl<'tcx> MirPass<'tcx> for RevealAll {
11 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
12 let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
13 RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
14 }
15 }
16
17 struct RevealAllVisitor<'tcx> {
18 tcx: TyCtxt<'tcx>,
19 param_env: ty::ParamEnv<'tcx>,
20 }
21
22 impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
23 #[inline]
24 fn tcx(&self) -> TyCtxt<'tcx> {
25 self.tcx
26 }
27
28 #[inline]
29 fn visit_place(
30 &mut self,
31 place: &mut Place<'tcx>,
32 _context: PlaceContext,
33 _location: Location,
34 ) {
35 // Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
36 if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
37 return;
38 }
39 // `OpaqueCast` projections are only needed if there are opaque types on which projections are performed.
40 // After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these
41 // projections anymore.
42 place.projection = self.tcx.mk_place_elems(
43 &place
44 .projection
45 .into_iter()
46 .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
47 .collect::<Vec<_>>(),
48 );
49 self.super_place(place, _context, _location);
50 }
51
52 #[inline]
53 fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
54 // We have to use `try_normalize_erasing_regions` here, since it's
55 // possible that we visit impossible-to-satisfy where clauses here,
56 // see #91745
57 if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) {
58 constant.const_ = c;
59 }
60 self.super_constant(constant, location);
61 }
62
63 #[inline]
64 fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
65 // We have to use `try_normalize_erasing_regions` here, since it's
66 // possible that we visit impossible-to-satisfy where clauses here,
67 // see #91745
68 if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) {
69 *ty = t;
70 }
71 }
72 }