Add Place::is_indirect
This returns whether a `Place` references the same region of memory as its base, or equivalently whether it contains a `Deref` projection. This is helpful for analyses that must track state for locals, since an assignment to `x` or `x.field` is fundamentally different than one to `*x`, which may mutate any memory region.
This commit is contained in:
parent
555d7a2fd6
commit
86487329bb
@ -1801,6 +1801,23 @@ pub enum ProjectionElem<V, T> {
|
||||
Downcast(Option<Symbol>, VariantIdx),
|
||||
}
|
||||
|
||||
impl<V, T> ProjectionElem<V, T> {
|
||||
/// Returns `true` if the target of this projection may refer to a different region of memory
|
||||
/// than the base.
|
||||
fn is_indirect(&self) -> bool {
|
||||
match self {
|
||||
Self::Deref => true,
|
||||
|
||||
| Self::Field(_, _)
|
||||
| Self::Index(_)
|
||||
| Self::ConstantIndex { .. }
|
||||
| Self::Subslice { .. }
|
||||
| Self::Downcast(_, _)
|
||||
=> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Alias for projections as they appear in places, where the base is a place
|
||||
/// and the index is a local.
|
||||
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
|
||||
@ -1862,6 +1879,14 @@ impl<'tcx> Place<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `Place` contains a `Deref` projection.
|
||||
///
|
||||
/// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
|
||||
/// same region of memory as its base.
|
||||
pub fn is_indirect(&self) -> bool {
|
||||
self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
|
||||
}
|
||||
|
||||
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
|
||||
/// a single deref of a local.
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user