subtyping_projections
This commit is contained in:
parent
177091258c
commit
3148e6a993
28 changed files with 431 additions and 5 deletions
|
@ -0,0 +1,57 @@
|
|||
use crate::MirPass;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::patch::MirPatch;
|
||||
use rustc_middle::mir::visit::MutVisitor;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub struct Subtyper;
|
||||
|
||||
pub struct SubTypeCheker<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
patcher: MirPatch<'tcx>,
|
||||
local_decls: &'a IndexVec<Local, LocalDecl<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeCheker<'a, 'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_assign(
|
||||
&mut self,
|
||||
place: &mut Place<'tcx>,
|
||||
rvalue: &mut Rvalue<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
let place_ty = place.ty(self.local_decls, self.tcx);
|
||||
let rval_ty = rvalue.ty(self.local_decls, self.tcx);
|
||||
if place_ty.ty != rval_ty {
|
||||
let temp = self
|
||||
.patcher
|
||||
.new_temp(rval_ty, self.local_decls[place.as_ref().local].source_info.span);
|
||||
let new_place =
|
||||
Place::from(temp).project_deeper(&[ProjectionElem::Subtype(place_ty.ty)], self.tcx);
|
||||
self.patcher.add_assign(location, new_place, rvalue.clone());
|
||||
let new_rval = Rvalue::Use(Operand::Move(new_place));
|
||||
*rvalue = new_rval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let patch = MirPatch::new(body);
|
||||
let mut checker = SubTypeCheker { tcx, patcher: patch, local_decls: &body.local_decls };
|
||||
|
||||
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
|
||||
checker.visit_basic_block_data(bb, data);
|
||||
}
|
||||
|
||||
checker.patcher.apply(body);
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Subtyper {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
subtype_finder(tcx, body);
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ mod check_packed_ref;
|
|||
pub mod check_unsafety;
|
||||
mod remove_place_mention;
|
||||
// This pass is public to allow external drivers to perform MIR cleanup
|
||||
mod add_subtyping_projections;
|
||||
pub mod cleanup_post_borrowck;
|
||||
mod const_debuginfo;
|
||||
mod const_goto;
|
||||
|
@ -466,6 +467,7 @@ pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
|
|||
/// After this series of passes, no lifetime analysis based on borrowing can be done.
|
||||
fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let passes: &[&dyn MirPass<'tcx>] = &[
|
||||
&add_subtyping_projections::Subtyper,
|
||||
&cleanup_post_borrowck::CleanupPostBorrowck,
|
||||
&remove_noop_landing_pads::RemoveNoopLandingPads,
|
||||
&simplify::SimplifyCfg::EarlyOpt,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue