about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/util/find_self_call.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-16 13:12:53 +0000
committerbors <bors@rust-lang.org>2023-04-16 13:12:53 +0000
commit8a778ca1e35e4a8df95c00d800100d95e63e7722 (patch)
treef74a5282fe636aa9e51d238b2cb46a9092a5c38b /compiler/rustc_middle/src/util/find_self_call.rs
parent1b50ea9abb65b33aac7285dbe36b37f9e33381a2 (diff)
parent38215fb77aca2dcd25277ff7b3093ea56e4e8ffb (diff)
downloadrust-8a778ca1e35e4a8df95c00d800100d95e63e7722.tar.gz
rust-8a778ca1e35e4a8df95c00d800100d95e63e7722.zip
Auto merge of #110405 - fee1-dead-contrib:rollup-9rkree6, r=fee1-dead
Rollup of 4 pull requests

Successful merges:

 - #110397 (Move some utils out of `rustc_const_eval`)
 - #110398 (use matches! macro in more places)
 - #110400 (more clippy fixes: clippy::{iter_cloned_collect, unwarp_or_else_defau…)
 - #110402 (Remove the loop in `Align::from_bytes`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_middle/src/util/find_self_call.rs')
-rw-r--r--compiler/rustc_middle/src/util/find_self_call.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/util/find_self_call.rs b/compiler/rustc_middle/src/util/find_self_call.rs
new file mode 100644
index 00000000000..0eab0adf07e
--- /dev/null
+++ b/compiler/rustc_middle/src/util/find_self_call.rs
@@ -0,0 +1,36 @@
+use crate::mir::*;
+use crate::ty::subst::SubstsRef;
+use crate::ty::{self, TyCtxt};
+use rustc_span::def_id::DefId;
+
+/// Checks if the specified `local` is used as the `self` parameter 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>(
+    tcx: TyCtxt<'tcx>,
+    body: &Body<'tcx>,
+    local: Local,
+    block: BasicBlock,
+) -> Option<(DefId, SubstsRef<'tcx>)> {
+    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, .. }) = func {
+            if let ty::FnDef(def_id, substs) = *literal.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, substs));
+                        }
+                    }
+                }
+            }
+        }
+    }
+    None
+}