36 lines
1.3 KiB
Rust
36 lines
1.3 KiB
Rust
|
|
use rustc_middle::mir::*;
|
||
|
|
use rustc_middle::ty::{self, TyCtxt};
|
||
|
|
use rustc_span::def_id::DefId;
|
||
|
|
|
||
|
|
/// Checks if the specified `local` is used as the `self` prameter of a method call
|
||
|
|
/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is
|
||
|
|
/// returned.
|
||
|
|
pub fn find_self_call(
|
||
|
|
tcx: TyCtxt<'_>,
|
||
|
|
body: &Body<'_>,
|
||
|
|
local: Local,
|
||
|
|
block: BasicBlock,
|
||
|
|
) -> Option<DefId> {
|
||
|
|
debug!("find_self_call(local={:?}): terminator={:?}", local, &body[block].terminator);
|
||
|
|
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
||
|
|
&body[block].terminator
|
||
|
|
{
|
||
|
|
debug!("find_self_call: func={:?}", func);
|
||
|
|
if let Operand::Constant(box Constant { literal: ty::Const { ty, .. }, .. }) = func {
|
||
|
|
if let ty::FnDef(def_id, _) = *ty.kind() {
|
||
|
|
if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
||
|
|
tcx.opt_associated_item(def_id)
|
||
|
|
{
|
||
|
|
debug!("find_self_call: args={:?}", args);
|
||
|
|
if let [Operand::Move(self_place) | Operand::Copy(self_place), ..] = **args {
|
||
|
|
if self_place.as_local() == Some(local) {
|
||
|
|
return Some(def_id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
None
|
||
|
|
}
|