flowistry_pdg_construction/
callback.rsuse flowistry_pdg::{rustc_portable::Location, CallString};
use rustc_middle::{
mir,
ty::{Instance, TypingEnv},
};
use rustc_span::Span;
use crate::{calling_convention::CallingConvention, utils::ArgSlice};
pub trait CallChangeCallback<'tcx> {
fn on_inline(&self, info: CallInfo<'tcx, '_>) -> CallChanges<'tcx>;
fn on_inline_miss(
&self,
_resolution: Instance<'tcx>,
_param_env: TypingEnv<'tcx>,
_loc: Location,
_under_analysis: Instance<'tcx>,
_reason: InlineMissReason,
_call_span: Span,
) {
}
}
pub struct CallChangeCallbackFn<'tcx> {
f: Box<dyn Fn(CallInfo<'tcx, '_>) -> CallChanges<'tcx> + 'tcx>,
}
impl<'tcx> CallChangeCallbackFn<'tcx> {
pub fn new(f: impl Fn(CallInfo<'tcx, '_>) -> CallChanges<'tcx> + 'tcx) -> Self {
Self { f: Box::new(f) }
}
}
impl<'tcx> CallChangeCallback<'tcx> for CallChangeCallbackFn<'tcx> {
fn on_inline(&self, info: CallInfo<'tcx, '_>) -> CallChanges<'tcx> {
(self.f)(info)
}
}
#[derive(Debug)]
pub enum InlineMissReason {
Async(String),
TraitMethod,
}
impl Default for CallChanges<'_> {
fn default() -> Self {
CallChanges {
skip: SkipCall::NoSkip,
}
}
}
pub struct CallInfo<'tcx, 'mir> {
pub callee: Instance<'tcx>,
pub async_parent: Option<Instance<'tcx>>,
pub call_string: CallString,
pub is_cached: bool,
pub span: Span,
pub arguments: ArgSlice<'mir, 'tcx>,
pub caller_body: &'mir mir::Body<'tcx>,
pub param_env: TypingEnv<'tcx>,
}
#[derive(Debug)]
pub struct CallChanges<'tcx> {
pub(crate) skip: SkipCall<'tcx>,
}
#[derive(Debug)]
pub enum SkipCall<'tcx> {
Skip,
NoSkip,
Replace {
instance: Instance<'tcx>,
calling_convention: CallingConvention<'tcx>,
},
}
impl<'tcx> CallChanges<'tcx> {
pub fn with_skip(self, skip: SkipCall<'tcx>) -> Self {
CallChanges { skip }
}
}