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