Skip to content

Instantly share code, notes, and snippets.

@sanxiyn
Created October 7, 2016 11:46
Show Gist options
  • Save sanxiyn/b1d666f132d3314cd999bb9b629acc2b to your computer and use it in GitHub Desktop.
Save sanxiyn/b1d666f132d3314cd999bb9b629acc2b to your computer and use it in GitHub Desktop.
#![crate_type = "lib"]
#![feature(rustc_private)]
extern crate rustc;
use rustc::mir::repr::{Location, Lvalue, Mir};
use rustc::mir::visit::{LvalueContext, MutVisitor};
use std::marker::PhantomData;
pub struct DefUseAnalysis<'tcx> {
info: Use<'tcx>,
}
#[derive(Clone)]
pub struct Use<'tcx> {
pub context: LvalueContext<'tcx>,
pub location: Location,
}
impl<'tcx> DefUseAnalysis<'tcx> {
fn mutate_defs_and_uses<F>(&self, mir: &mut Mir<'tcx>, mut callback: F)
where F: for<'a> FnMut(&'a mut Lvalue<'tcx>,
LvalueContext<'tcx>,
Location) {
let mut v = MutateUseVisitor::new(&mut callback);
v.visit_location(mir, self.info.location);
}
pub fn replace_all_defs_and_uses_with(&self,
mir: &mut Mir<'tcx>,
new_lvalue: Lvalue<'tcx>) {
self.mutate_defs_and_uses(mir, |lvalue, _, _| *lvalue = new_lvalue.clone())
}
}
struct MutateUseVisitor<'tcx, F> {
callback: F,
phantom: PhantomData<&'tcx ()>,
}
impl<'tcx, F> MutateUseVisitor<'tcx, F> {
fn new(callback: F)
-> MutateUseVisitor<'tcx, F>
where F: for<'a> FnMut(&'a mut Lvalue<'tcx>, LvalueContext<'tcx>, Location) {
MutateUseVisitor {
callback: callback,
phantom: PhantomData,
}
}
}
impl<'tcx, F> MutVisitor<'tcx> for MutateUseVisitor<'tcx, F>
where F: for<'a> FnMut(&'a mut Lvalue<'tcx>, LvalueContext<'tcx>, Location) {
fn visit_lvalue(&mut self,
lvalue: &mut Lvalue<'tcx>,
context: LvalueContext<'tcx>,
location: Location) {
(self.callback)(lvalue, context, location)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment