]>
Commit | Line | Data |
---|---|---|
3c0e092e XL |
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>) { | |
a2a8927a | 12 | let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); |
f2b60f7d | 13 | RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body); |
3c0e092e XL |
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 | ||
49aad941 | 28 | #[inline] |
781aab86 FG |
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) { | |
49aad941 FG |
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 | |
781aab86 FG |
57 | if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) { |
58 | constant.const_ = c; | |
49aad941 | 59 | } |
781aab86 | 60 | self.super_constant(constant, location); |
49aad941 FG |
61 | } |
62 | ||
3c0e092e XL |
63 | #[inline] |
64 | fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) { | |
a2a8927a XL |
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 | |
49aad941 FG |
68 | if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) { |
69 | *ty = t; | |
70 | } | |
3c0e092e XL |
71 | } |
72 | } |