2021-05-13 12:04:41 +02:00
|
|
|
//! Normalizes MIR in RevealAll mode.
|
|
|
|
|
|
|
|
use rustc_middle::mir::visit::*;
|
|
|
|
use rustc_middle::mir::*;
|
|
|
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
|
|
|
|
|
|
|
pub struct RevealAll;
|
|
|
|
|
|
|
|
impl<'tcx> MirPass<'tcx> for RevealAll {
|
|
|
|
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
2021-12-02 09:17:32 -08:00
|
|
|
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
|
2022-08-02 20:06:16 -07:00
|
|
|
RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
|
2021-05-13 12:04:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct RevealAllVisitor<'tcx> {
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
|
|
|
|
#[inline]
|
|
|
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
|
|
|
self.tcx
|
|
|
|
}
|
|
|
|
|
2023-09-27 11:20:17 +00:00
|
|
|
#[inline]
|
|
|
|
fn visit_place(
|
|
|
|
&mut self,
|
|
|
|
place: &mut Place<'tcx>,
|
|
|
|
_context: PlaceContext,
|
|
|
|
_location: Location,
|
|
|
|
) {
|
2023-09-27 11:23:39 +00:00
|
|
|
// Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
|
|
|
|
if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
|
|
|
|
return;
|
|
|
|
}
|
2023-09-27 11:20:17 +00:00
|
|
|
// `OpaqueCast` projections are only needed if there are opaque types on which projections are performed.
|
|
|
|
// After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these
|
|
|
|
// projections anymore.
|
|
|
|
place.projection = self.tcx.mk_place_elems(
|
|
|
|
&place
|
|
|
|
.projection
|
|
|
|
.into_iter()
|
|
|
|
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
);
|
2023-10-03 13:19:00 +03:00
|
|
|
self.super_place(place, _context, _location);
|
2023-09-27 11:20:17 +00:00
|
|
|
}
|
|
|
|
|
2023-04-14 18:59:17 +00:00
|
|
|
#[inline]
|
2024-06-13 15:35:38 +02:00
|
|
|
fn visit_const_operand(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
|
2023-04-14 18:59:17 +00:00
|
|
|
// We have to use `try_normalize_erasing_regions` here, since it's
|
|
|
|
// possible that we visit impossible-to-satisfy where clauses here,
|
|
|
|
// see #91745
|
2023-09-20 20:51:14 +02:00
|
|
|
if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) {
|
|
|
|
constant.const_ = c;
|
2023-04-14 18:59:17 +00:00
|
|
|
}
|
2024-06-13 15:35:38 +02:00
|
|
|
self.super_const_operand(constant, location);
|
2023-04-14 18:59:17 +00:00
|
|
|
}
|
|
|
|
|
2021-05-13 12:04:41 +02:00
|
|
|
#[inline]
|
|
|
|
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
|
2021-12-13 22:24:08 +01:00
|
|
|
// We have to use `try_normalize_erasing_regions` here, since it's
|
|
|
|
// possible that we visit impossible-to-satisfy where clauses here,
|
|
|
|
// see #91745
|
2023-04-14 18:59:17 +00:00
|
|
|
if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) {
|
|
|
|
*ty = t;
|
|
|
|
}
|
2021-05-13 12:04:41 +02:00
|
|
|
}
|
|
|
|
}
|