]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_const_eval/src/util/find_self_call.rs
Rollup merge of #103703 - Nilstrieb:flag-recovery-1, r=compiler-errors
[rust.git] / compiler / rustc_const_eval / src / util / find_self_call.rs
1 use rustc_middle::mir::*;
2 use rustc_middle::ty::subst::SubstsRef;
3 use rustc_middle::ty::{self, TyCtxt};
4 use rustc_span::def_id::DefId;
5
6 /// Checks if the specified `local` is used as the `self` parameter of a method call
7 /// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is
8 /// returned.
9 pub fn find_self_call<'tcx>(
10     tcx: TyCtxt<'tcx>,
11     body: &Body<'tcx>,
12     local: Local,
13     block: BasicBlock,
14 ) -> Option<(DefId, SubstsRef<'tcx>)> {
15     debug!("find_self_call(local={:?}): terminator={:?}", local, &body[block].terminator);
16     if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
17         &body[block].terminator
18     {
19         debug!("find_self_call: func={:?}", func);
20         if let Operand::Constant(box Constant { literal, .. }) = func {
21             if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
22                 if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
23                     tcx.opt_associated_item(def_id)
24                 {
25                     debug!("find_self_call: args={:?}", args);
26                     if let [Operand::Move(self_place) | Operand::Copy(self_place), ..] = **args {
27                         if self_place.as_local() == Some(local) {
28                             return Some((def_id, substs));
29                         }
30                     }
31                 }
32             }
33         }
34     }
35     None
36 }