Skip to content

Commit 8648732

Browse files
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.
1 parent 555d7a2 commit 8648732

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/librustc/mir/mod.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,23 @@ pub enum ProjectionElem<V, T> {
18011801
Downcast(Option<Symbol>, VariantIdx),
18021802
}
18031803

1804+
impl<V, T> ProjectionElem<V, T> {
1805+
/// Returns `true` if the target of this projection may refer to a different region of memory
1806+
/// than the base.
1807+
fn is_indirect(&self) -> bool {
1808+
match self {
1809+
Self::Deref => true,
1810+
1811+
| Self::Field(_, _)
1812+
| Self::Index(_)
1813+
| Self::ConstantIndex { .. }
1814+
| Self::Subslice { .. }
1815+
| Self::Downcast(_, _)
1816+
=> false
1817+
}
1818+
}
1819+
}
1820+
18041821
/// Alias for projections as they appear in places, where the base is a place
18051822
/// and the index is a local.
18061823
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
@@ -1862,6 +1879,14 @@ impl<'tcx> Place<'tcx> {
18621879
}
18631880
}
18641881

1882+
/// Returns `true` if this `Place` contains a `Deref` projection.
1883+
///
1884+
/// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
1885+
/// same region of memory as its base.
1886+
pub fn is_indirect(&self) -> bool {
1887+
self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
1888+
}
1889+
18651890
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
18661891
/// a single deref of a local.
18671892
//

0 commit comments

Comments
 (0)