5 use rustc_target
::abi
::VariantIdx
;
7 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
9 /// A temporary variable
11 /// A named `static` item
13 /// A named local variable
15 /// An upvar referenced by closure env
19 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
20 pub enum ProjectionKind
{
21 /// A dereference of a pointer, reference or `Box<T>` of the given type
24 /// `B.F` where `B` is the base expression and `F` is
25 /// the field. The field is identified by which variant
26 /// it appears in along with a field index. The variant
27 /// is used for enums.
28 Field(u32, VariantIdx
),
30 /// Some index like `B[x]`, where `B` is the base
31 /// expression. We don't preserve the index `x` because
35 /// A subslice covering a range of values like `B[x..y]`.
39 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
40 pub struct Projection
<'tcx
> {
41 /// Type after the projection is being applied.
44 /// Defines the type of access
45 pub kind
: ProjectionKind
,
48 /// A `Place` represents how a value is located in memory.
50 /// This is an HIR version of `mir::Place`
51 #[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
52 pub struct Place
<'tcx
> {
53 /// The type of the `PlaceBase`
54 pub base_ty
: Ty
<'tcx
>,
55 /// The "outermost" place that holds this value.
57 /// How this place is derived from the base place.
58 pub projections
: Vec
<Projection
<'tcx
>>,
61 /// A `PlaceWithHirId` represents how a value is located in memory.
63 /// This is an HIR version of `mir::Place`
64 #[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
65 pub struct PlaceWithHirId
<'tcx
> {
66 /// `HirId` of the expression or pattern producing this value.
69 /// Information about the `Place`
70 pub place
: Place
<'tcx
>,
73 impl<'tcx
> PlaceWithHirId
<'tcx
> {
78 projections
: Vec
<Projection
<'tcx
>>,
79 ) -> PlaceWithHirId
<'tcx
> {
82 place
: Place { base_ty: base_ty, base: base, projections: projections }
,
87 impl<'tcx
> Place
<'tcx
> {
88 /// Returns an iterator of the types that have to be dereferenced to access
91 /// The types are in the reverse order that they are applied. So if
92 /// `x: &*const u32` and the `Place` is `**x`, then the types returned are
93 ///`*const u32` then `&*const u32`.
94 pub fn deref_tys(&self) -> impl Iterator
<Item
= Ty
<'tcx
>> + '_
{
95 self.projections
.iter().enumerate().rev().filter_map(move |(index
, proj
)| {
96 if ProjectionKind
::Deref
== proj
.kind
{
97 Some(self.ty_before_projection(index
))
104 /// Returns the type of this `Place` after all projections have been applied.
105 pub fn ty(&self) -> Ty
<'tcx
> {
106 self.projections
.last().map_or_else(|| self.base_ty
, |proj
| proj
.ty
)
109 /// Returns the type of this `Place` immediately before `projection_index`th projection
111 pub fn ty_before_projection(&self, projection_index
: usize) -> Ty
<'tcx
> {
112 assert
!(projection_index
< self.projections
.len());
113 if projection_index
== 0 { self.base_ty }
else { self.projections[projection_index - 1].ty }