Move find_self_call
.
It's a function that does stuff with MIR and yet it weirdly has its own module in `rustc_middle::util`. This commit moves it into `rustc_middle::mir`, a more sensible home.
This commit is contained in:
parent
3f5e218581
commit
140817380c
6 changed files with 48 additions and 60 deletions
|
@ -3777,7 +3777,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) =
|
if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) =
|
||||||
&self.body[loan.reserve_location.block].terminator
|
&self.body[loan.reserve_location.block].terminator
|
||||||
&& let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
|
&& let Some((method_did, method_args)) = mir::find_self_call(
|
||||||
tcx,
|
tcx,
|
||||||
self.body,
|
self.body,
|
||||||
loan.assigned_place.local,
|
loan.assigned_place.local,
|
||||||
|
|
|
@ -17,7 +17,7 @@ use rustc_middle::mir::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo,
|
AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo,
|
||||||
LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement,
|
LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement,
|
||||||
StatementKind, Terminator, TerminatorKind,
|
StatementKind, Terminator, TerminatorKind, find_self_call,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::print::Print;
|
use rustc_middle::ty::print::Print;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
@ -1016,12 +1016,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
|
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
|
||||||
}) = &self.body[location.block].terminator
|
}) = &self.body[location.block].terminator
|
||||||
{
|
{
|
||||||
let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
|
let Some((method_did, method_args)) =
|
||||||
self.infcx.tcx,
|
find_self_call(self.infcx.tcx, self.body, target_temp, location.block)
|
||||||
self.body,
|
else {
|
||||||
target_temp,
|
|
||||||
location.block,
|
|
||||||
) else {
|
|
||||||
return normal_ret;
|
return normal_ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisit
|
||||||
use rustc_serialize::{Decodable, Encodable};
|
use rustc_serialize::{Decodable, Encodable};
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::{DUMMY_SP, Span, Symbol};
|
use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||||
use tracing::trace;
|
use tracing::{debug, trace};
|
||||||
|
|
||||||
pub use self::query::*;
|
pub use self::query::*;
|
||||||
use self::visit::TyContext;
|
use self::visit::TyContext;
|
||||||
|
@ -1796,6 +1796,47 @@ impl DefLocation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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, GenericArgsRef<'tcx>)> {
|
||||||
|
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
||||||
|
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
||||||
|
&body[block].terminator
|
||||||
|
&& let Operand::Constant(box ConstOperand { const_, .. }) = func
|
||||||
|
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
|
||||||
|
&& let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
||||||
|
tcx.opt_associated_item(def_id)
|
||||||
|
&& let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
|
||||||
|
**args
|
||||||
|
{
|
||||||
|
if self_place.as_local() == Some(local) {
|
||||||
|
return Some((def_id, fn_args));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the case where `self_place` gets reborrowed.
|
||||||
|
// This happens when the receiver is `&T`.
|
||||||
|
for stmt in &body[block].statements {
|
||||||
|
if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind
|
||||||
|
&& let Some(reborrow_local) = place.as_local()
|
||||||
|
&& self_place.as_local() == Some(reborrow_local)
|
||||||
|
&& let Rvalue::Ref(_, _, deref_place) = rvalue
|
||||||
|
&& let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } =
|
||||||
|
deref_place.as_ref()
|
||||||
|
&& deref_local == local
|
||||||
|
{
|
||||||
|
return Some((def_id, fn_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
mod size_asserts {
|
mod size_asserts {
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
use rustc_span::def_id::DefId;
|
|
||||||
use rustc_span::source_map::Spanned;
|
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use crate::mir::*;
|
|
||||||
use crate::ty::{self, GenericArgsRef, TyCtxt};
|
|
||||||
|
|
||||||
/// 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, GenericArgsRef<'tcx>)> {
|
|
||||||
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
|
||||||
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
|
||||||
&body[block].terminator
|
|
||||||
&& let Operand::Constant(box ConstOperand { const_, .. }) = func
|
|
||||||
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
|
|
||||||
&& let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
|
||||||
tcx.opt_associated_item(def_id)
|
|
||||||
&& let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
|
|
||||||
**args
|
|
||||||
{
|
|
||||||
if self_place.as_local() == Some(local) {
|
|
||||||
return Some((def_id, fn_args));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the case where `self_place` gets reborrowed.
|
|
||||||
// This happens when the receiver is `&T`.
|
|
||||||
for stmt in &body[block].statements {
|
|
||||||
if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind
|
|
||||||
&& let Some(reborrow_local) = place.as_local()
|
|
||||||
&& self_place.as_local() == Some(reborrow_local)
|
|
||||||
&& let Rvalue::Ref(_, _, deref_place) = rvalue
|
|
||||||
&& let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } =
|
|
||||||
deref_place.as_ref()
|
|
||||||
&& deref_local == local
|
|
||||||
{
|
|
||||||
return Some((def_id, fn_args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
|
@ -1,8 +1,5 @@
|
||||||
pub mod bug;
|
pub mod bug;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod find_self_call;
|
|
||||||
|
|
||||||
pub use find_self_call::find_self_call;
|
|
||||||
|
|
||||||
#[derive(Default, Copy, Clone)]
|
#[derive(Default, Copy, Clone)]
|
||||||
pub struct Providers {
|
pub struct Providers {
|
||||||
|
|
|
@ -133,7 +133,7 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
|
||||||
// the `self` parameter of a method call (as the terminator of our current
|
// the `self` parameter of a method call (as the terminator of our current
|
||||||
// BasicBlock). If so, we emit a more specific lint.
|
// BasicBlock). If so, we emit a more specific lint.
|
||||||
let method_did = self.target_local.and_then(|target_local| {
|
let method_did = self.target_local.and_then(|target_local| {
|
||||||
rustc_middle::util::find_self_call(self.tcx, self.body, target_local, loc.block)
|
find_self_call(self.tcx, self.body, target_local, loc.block)
|
||||||
});
|
});
|
||||||
let lint_loc =
|
let lint_loc =
|
||||||
if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc };
|
if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue