mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Rollup merge of #114505 - ouz-a:cleanup_mir, r=RalfJung
Add documentation to has_deref Documentation of `has_deref` needed some polish to be more clear about where it should be used and what's it's purpose. cc https://github.com/rust-lang/rust/issues/114401 r? `@RalfJung`
This commit is contained in:
commit
13de583583
@ -441,7 +441,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
LocalRef::Place(place) => place,
|
LocalRef::Place(place) => place,
|
||||||
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
|
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
|
||||||
LocalRef::Operand(..) => {
|
LocalRef::Operand(..) => {
|
||||||
if place_ref.has_deref() {
|
if place_ref.is_indirect_first_projection() {
|
||||||
base = 1;
|
base = 1;
|
||||||
let cg_base = self.codegen_consume(
|
let cg_base = self.codegen_consume(
|
||||||
bx,
|
bx,
|
||||||
|
@ -247,7 +247,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
|
|
||||||
AddressOf(_, place) => {
|
AddressOf(_, place) => {
|
||||||
// Figure out whether this is an addr_of of an already raw place.
|
// Figure out whether this is an addr_of of an already raw place.
|
||||||
let place_base_raw = if place.has_deref() {
|
let place_base_raw = if place.is_indirect_first_projection() {
|
||||||
let ty = self.frame().body.local_decls[place.local].ty;
|
let ty = self.frame().body.local_decls[place.local].ty;
|
||||||
ty.is_unsafe_ptr()
|
ty.is_unsafe_ptr()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1592,14 +1592,13 @@ impl<'tcx> Place<'tcx> {
|
|||||||
self.projection.iter().any(|elem| elem.is_indirect())
|
self.projection.iter().any(|elem| elem.is_indirect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If MirPhase >= Derefered and if projection contains Deref,
|
/// Returns `true` if this `Place`'s first projection is `Deref`.
|
||||||
/// It's guaranteed to be in the first place
|
///
|
||||||
pub fn has_deref(&self) -> bool {
|
/// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
|
||||||
// To make sure this is not accidentally used in wrong mir phase
|
/// `Deref` projections can only occur as the first projection. In that case this method
|
||||||
debug_assert!(
|
/// is equivalent to `is_indirect`, but faster.
|
||||||
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
|
pub fn is_indirect_first_projection(&self) -> bool {
|
||||||
);
|
self.as_ref().is_indirect_first_projection()
|
||||||
self.projection.first() == Some(&PlaceElem::Deref)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
|
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
|
||||||
@ -1672,9 +1671,16 @@ impl<'tcx> PlaceRef<'tcx> {
|
|||||||
self.projection.iter().any(|elem| elem.is_indirect())
|
self.projection.iter().any(|elem| elem.is_indirect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If MirPhase >= Derefered and if projection contains Deref,
|
/// Returns `true` if this `Place`'s first projection is `Deref`.
|
||||||
/// It's guaranteed to be in the first place
|
///
|
||||||
pub fn has_deref(&self) -> bool {
|
/// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
|
||||||
|
/// `Deref` projections can only occur as the first projection. In that case this method
|
||||||
|
/// is equivalent to `is_indirect`, but faster.
|
||||||
|
pub fn is_indirect_first_projection(&self) -> bool {
|
||||||
|
// To make sure this is not accidentally used in wrong mir phase
|
||||||
|
debug_assert!(
|
||||||
|
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
|
||||||
|
);
|
||||||
self.projection.first() == Some(&PlaceElem::Deref)
|
self.projection.first() == Some(&PlaceElem::Deref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +839,7 @@ impl Map {
|
|||||||
tail_elem: Option<TrackElem>,
|
tail_elem: Option<TrackElem>,
|
||||||
f: &mut impl FnMut(ValueIndex),
|
f: &mut impl FnMut(ValueIndex),
|
||||||
) {
|
) {
|
||||||
if place.has_deref() {
|
if place.is_indirect_first_projection() {
|
||||||
// We do not track indirect places.
|
// We do not track indirect places.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
|
|||||||
let basic_blocks = body.basic_blocks.as_mut();
|
let basic_blocks = body.basic_blocks.as_mut();
|
||||||
let local_decls = &body.local_decls;
|
let local_decls = &body.local_decls;
|
||||||
let needs_retag = |place: &Place<'tcx>| {
|
let needs_retag = |place: &Place<'tcx>| {
|
||||||
!place.has_deref() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
|
!place.is_indirect_first_projection() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
|
||||||
&& may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
|
&& may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
|
||||||
&& !local_decls[place.local].is_deref_temp()
|
&& !local_decls[place.local].is_deref_temp()
|
||||||
};
|
};
|
||||||
|
@ -154,7 +154,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
|
|||||||
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
|
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
|
||||||
if let Operand::Move(place) = *operand
|
if let Operand::Move(place) = *operand
|
||||||
// A move out of a projection of a copy is equivalent to a copy of the original projection.
|
// A move out of a projection of a copy is equivalent to a copy of the original projection.
|
||||||
&& !place.has_deref()
|
&& !place.is_indirect_first_projection()
|
||||||
&& !self.fully_moved.contains(place.local)
|
&& !self.fully_moved.contains(place.local)
|
||||||
{
|
{
|
||||||
*operand = Operand::Copy(place);
|
*operand = Operand::Copy(place);
|
||||||
|
@ -1170,7 +1170,7 @@ fn referent_used_exactly_once<'tcx>(
|
|||||||
&& let [location] = *local_assignments(mir, local).as_slice()
|
&& let [location] = *local_assignments(mir, local).as_slice()
|
||||||
&& let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
|
&& let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
|
||||||
&& let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
|
&& let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
|
||||||
&& !place.has_deref()
|
&& !place.is_indirect_first_projection()
|
||||||
// Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
|
// Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
|
||||||
&& TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
|
&& TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user