rustc_middle/hir/
place.rs

1use rustc_abi::{FieldIdx, VariantIdx};
2use rustc_hir::HirId;
3use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
4
5use crate::ty;
6use crate::ty::Ty;
7
8#[derive(#[automatically_derived]
impl ::core::clone::Clone for PlaceBase {
    #[inline]
    fn clone(&self) -> PlaceBase {
        let _: ::core::clone::AssertParamIsClone<HirId>;
        let _: ::core::clone::AssertParamIsClone<ty::UpvarId>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PlaceBase { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for PlaceBase {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            PlaceBase::Rvalue =>
                ::core::fmt::Formatter::write_str(f, "Rvalue"),
            PlaceBase::StaticItem =>
                ::core::fmt::Formatter::write_str(f, "StaticItem"),
            PlaceBase::Local(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Local",
                    &__self_0),
            PlaceBase::Upvar(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Upvar",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PlaceBase {
    #[inline]
    fn eq(&self, other: &PlaceBase) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (PlaceBase::Local(__self_0), PlaceBase::Local(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (PlaceBase::Upvar(__self_0), PlaceBase::Upvar(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PlaceBase {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<HirId>;
        let _: ::core::cmp::AssertParamIsEq<ty::UpvarId>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for PlaceBase {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            PlaceBase::Local(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            PlaceBase::Upvar(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for PlaceBase {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        PlaceBase::Rvalue => { 0usize }
                        PlaceBase::StaticItem => { 1usize }
                        PlaceBase::Local(ref __binding_0) => { 2usize }
                        PlaceBase::Upvar(ref __binding_0) => { 3usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    PlaceBase::Rvalue => {}
                    PlaceBase::StaticItem => {}
                    PlaceBase::Local(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    PlaceBase::Upvar(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for PlaceBase {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { PlaceBase::Rvalue }
                    1usize => { PlaceBase::StaticItem }
                    2usize => {
                        PlaceBase::Local(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => {
                        PlaceBase::Upvar(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `PlaceBase`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PlaceBase {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    PlaceBase::Rvalue => {}
                    PlaceBase::StaticItem => {}
                    PlaceBase::Local(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PlaceBase::Upvar(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
9#[derive(const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PlaceBase {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        PlaceBase::Rvalue => { PlaceBase::Rvalue }
                        PlaceBase::StaticItem => { PlaceBase::StaticItem }
                        PlaceBase::Local(__binding_0) => {
                            PlaceBase::Local(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        PlaceBase::Upvar(__binding_0) => {
                            PlaceBase::Upvar(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    PlaceBase::Rvalue => { PlaceBase::Rvalue }
                    PlaceBase::StaticItem => { PlaceBase::StaticItem }
                    PlaceBase::Local(__binding_0) => {
                        PlaceBase::Local(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    PlaceBase::Upvar(__binding_0) => {
                        PlaceBase::Upvar(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PlaceBase {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    PlaceBase::Rvalue => {}
                    PlaceBase::StaticItem => {}
                    PlaceBase::Local(ref __binding_0) => {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                    PlaceBase::Upvar(ref __binding_0) => {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable)]
10pub enum PlaceBase {
11    /// A temporary variable.
12    Rvalue,
13    /// A named `static` item.
14    StaticItem,
15    /// A named local variable.
16    Local(HirId),
17    /// An upvar referenced by closure env.
18    Upvar(ty::UpvarId),
19}
20
21#[derive(#[automatically_derived]
impl ::core::clone::Clone for ProjectionKind {
    #[inline]
    fn clone(&self) -> ProjectionKind {
        let _: ::core::clone::AssertParamIsClone<FieldIdx>;
        let _: ::core::clone::AssertParamIsClone<VariantIdx>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ProjectionKind { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for ProjectionKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ProjectionKind::Deref =>
                ::core::fmt::Formatter::write_str(f, "Deref"),
            ProjectionKind::Field(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Field",
                    __self_0, &__self_1),
            ProjectionKind::Index =>
                ::core::fmt::Formatter::write_str(f, "Index"),
            ProjectionKind::Subslice =>
                ::core::fmt::Formatter::write_str(f, "Subslice"),
            ProjectionKind::OpaqueCast =>
                ::core::fmt::Formatter::write_str(f, "OpaqueCast"),
            ProjectionKind::UnwrapUnsafeBinder =>
                ::core::fmt::Formatter::write_str(f, "UnwrapUnsafeBinder"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ProjectionKind {
    #[inline]
    fn eq(&self, other: &ProjectionKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (ProjectionKind::Field(__self_0, __self_1),
                    ProjectionKind::Field(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ProjectionKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<FieldIdx>;
        let _: ::core::cmp::AssertParamIsEq<VariantIdx>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for ProjectionKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            ProjectionKind::Field(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            _ => {}
        }
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for ProjectionKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        ProjectionKind::Deref => { 0usize }
                        ProjectionKind::Field(ref __binding_0, ref __binding_1) => {
                            1usize
                        }
                        ProjectionKind::Index => { 2usize }
                        ProjectionKind::Subslice => { 3usize }
                        ProjectionKind::OpaqueCast => { 4usize }
                        ProjectionKind::UnwrapUnsafeBinder => { 5usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    ProjectionKind::Deref => {}
                    ProjectionKind::Field(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    ProjectionKind::Index => {}
                    ProjectionKind::Subslice => {}
                    ProjectionKind::OpaqueCast => {}
                    ProjectionKind::UnwrapUnsafeBinder => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for ProjectionKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { ProjectionKind::Deref }
                    1usize => {
                        ProjectionKind::Field(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => { ProjectionKind::Index }
                    3usize => { ProjectionKind::Subslice }
                    4usize => { ProjectionKind::OpaqueCast }
                    5usize => { ProjectionKind::UnwrapUnsafeBinder }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ProjectionKind`, expected 0..6, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for ProjectionKind {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    ProjectionKind::Deref => {}
                    ProjectionKind::Field(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ProjectionKind::Index => {}
                    ProjectionKind::Subslice => {}
                    ProjectionKind::OpaqueCast => {}
                    ProjectionKind::UnwrapUnsafeBinder => {}
                }
            }
        }
    };HashStable)]
22#[derive(const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for ProjectionKind {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        ProjectionKind::Deref => { ProjectionKind::Deref }
                        ProjectionKind::Field(__binding_0, __binding_1) => {
                            ProjectionKind::Field(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?)
                        }
                        ProjectionKind::Index => { ProjectionKind::Index }
                        ProjectionKind::Subslice => { ProjectionKind::Subslice }
                        ProjectionKind::OpaqueCast => { ProjectionKind::OpaqueCast }
                        ProjectionKind::UnwrapUnsafeBinder => {
                            ProjectionKind::UnwrapUnsafeBinder
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    ProjectionKind::Deref => { ProjectionKind::Deref }
                    ProjectionKind::Field(__binding_0, __binding_1) => {
                        ProjectionKind::Field(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder))
                    }
                    ProjectionKind::Index => { ProjectionKind::Index }
                    ProjectionKind::Subslice => { ProjectionKind::Subslice }
                    ProjectionKind::OpaqueCast => { ProjectionKind::OpaqueCast }
                    ProjectionKind::UnwrapUnsafeBinder => {
                        ProjectionKind::UnwrapUnsafeBinder
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for ProjectionKind {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    ProjectionKind::Deref => {}
                    ProjectionKind::Field(ref __binding_0, ref __binding_1) => {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                    ProjectionKind::Index => {}
                    ProjectionKind::Subslice => {}
                    ProjectionKind::OpaqueCast => {}
                    ProjectionKind::UnwrapUnsafeBinder => {}
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable)]
23pub enum ProjectionKind {
24    /// A dereference of a pointer, reference or `Box<T>` of the given type.
25    Deref,
26
27    /// `B.F` where `B` is the base expression and `F` is
28    /// the field. The field is identified by which variant
29    /// it appears in along with a field index. The variant
30    /// is used for enums.
31    Field(FieldIdx, VariantIdx),
32
33    /// Some index like `B[x]`, where `B` is the base
34    /// expression. We don't preserve the index `x` because
35    /// we won't need it.
36    Index,
37
38    /// A subslice covering a range of values like `B[x..y]`.
39    Subslice,
40
41    /// A conversion from an opaque type to its hidden type so we can
42    /// do further projections on it.
43    ///
44    /// This is unused if `-Znext-solver` is enabled.
45    OpaqueCast,
46
47    /// `unwrap_binder!(expr)`
48    UnwrapUnsafeBinder,
49}
50
51#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Projection<'tcx> {
    #[inline]
    fn clone(&self) -> Projection<'tcx> {
        let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<ProjectionKind>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for Projection<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Projection<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Projection",
            "ty", &self.ty, "kind", &&self.kind)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Projection<'tcx> {
    #[inline]
    fn eq(&self, other: &Projection<'tcx>) -> bool {
        self.ty == other.ty && self.kind == other.kind
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for Projection<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<Ty<'tcx>>;
        let _: ::core::cmp::AssertParamIsEq<ProjectionKind>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for Projection<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        ::core::hash::Hash::hash(&self.ty, state);
        ::core::hash::Hash::hash(&self.kind, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for Projection<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Projection { ty: ref __binding_0, kind: ref __binding_1 } =>
                        {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for Projection<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                Projection {
                    ty: ::rustc_serialize::Decodable::decode(__decoder),
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Projection<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Projection { ty: ref __binding_0, kind: ref __binding_1 } =>
                        {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
52#[derive(const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Projection<'tcx> {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        Projection { ty: __binding_0, kind: __binding_1 } => {
                            Projection {
                                ty: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                kind: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    Projection { ty: __binding_0, kind: __binding_1 } => {
                        Projection {
                            ty: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            kind: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Projection<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Projection { ty: ref __binding_0, kind: ref __binding_1 } =>
                        {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable)]
53pub struct Projection<'tcx> {
54    /// Type after the projection is applied.
55    pub ty: Ty<'tcx>,
56
57    /// Defines the kind of access made by the projection.
58    pub kind: ProjectionKind,
59}
60
61/// A `Place` represents how a value is located in memory. This does not
62/// always correspond to a syntactic place expression. For example, when
63/// processing a pattern, a `Place` can be used to refer to the sub-value
64/// currently being inspected.
65///
66/// This is an HIR version of [`rustc_middle::mir::Place`].
67#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Place<'tcx> {
    #[inline]
    fn clone(&self) -> Place<'tcx> {
        Place {
            base_ty: ::core::clone::Clone::clone(&self.base_ty),
            base: ::core::clone::Clone::clone(&self.base),
            projections: ::core::clone::Clone::clone(&self.projections),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Place<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "Place",
            "base_ty", &self.base_ty, "base", &self.base, "projections",
            &&self.projections)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Place<'tcx> {
    #[inline]
    fn eq(&self, other: &Place<'tcx>) -> bool {
        self.base_ty == other.base_ty && self.base == other.base &&
            self.projections == other.projections
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for Place<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<Ty<'tcx>>;
        let _: ::core::cmp::AssertParamIsEq<PlaceBase>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Projection<'tcx>>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for Place<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        ::core::hash::Hash::hash(&self.base_ty, state);
        ::core::hash::Hash::hash(&self.base, state);
        ::core::hash::Hash::hash(&self.projections, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for Place<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Place {
                        base_ty: ref __binding_0,
                        base: ref __binding_1,
                        projections: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for Place<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                Place {
                    base_ty: ::rustc_serialize::Decodable::decode(__decoder),
                    base: ::rustc_serialize::Decodable::decode(__decoder),
                    projections: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Place<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Place {
                        base_ty: ref __binding_0,
                        base: ref __binding_1,
                        projections: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
68#[derive(const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Place<'tcx> {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        Place {
                            base_ty: __binding_0,
                            base: __binding_1,
                            projections: __binding_2 } => {
                            Place {
                                base_ty: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                base: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                projections: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    Place {
                        base_ty: __binding_0,
                        base: __binding_1,
                        projections: __binding_2 } => {
                        Place {
                            base_ty: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            base: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            projections: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Place<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Place {
                        base_ty: ref __binding_0,
                        base: ref __binding_1,
                        projections: ref __binding_2 } => {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable)]
69pub struct Place<'tcx> {
70    /// The type of the `PlaceBase`
71    pub base_ty: Ty<'tcx>,
72    /// The "outermost" place that holds this value.
73    pub base: PlaceBase,
74    /// How this place is derived from the base place.
75    pub projections: Vec<Projection<'tcx>>,
76}
77
78/// A `PlaceWithHirId` represents how a value is located in memory. This does not
79/// always correspond to a syntactic place expression. For example, when
80/// processing a pattern, a `Place` can be used to refer to the sub-value
81/// currently being inspected.
82///
83/// This is an HIR version of [`rustc_middle::mir::Place`].
84#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for PlaceWithHirId<'tcx> {
    #[inline]
    fn clone(&self) -> PlaceWithHirId<'tcx> {
        PlaceWithHirId {
            hir_id: ::core::clone::Clone::clone(&self.hir_id),
            place: ::core::clone::Clone::clone(&self.place),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PlaceWithHirId<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "PlaceWithHirId", "hir_id", &self.hir_id, "place", &&self.place)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for PlaceWithHirId<'tcx> {
    #[inline]
    fn eq(&self, other: &PlaceWithHirId<'tcx>) -> bool {
        self.hir_id == other.hir_id && self.place == other.place
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for PlaceWithHirId<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<HirId>;
        let _: ::core::cmp::AssertParamIsEq<Place<'tcx>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for PlaceWithHirId<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        ::core::hash::Hash::hash(&self.hir_id, state);
        ::core::hash::Hash::hash(&self.place, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for PlaceWithHirId<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    PlaceWithHirId {
                        hir_id: ref __binding_0, place: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for PlaceWithHirId<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                PlaceWithHirId {
                    hir_id: ::rustc_serialize::Decodable::decode(__decoder),
                    place: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PlaceWithHirId<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    PlaceWithHirId {
                        hir_id: ref __binding_0, place: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
85pub struct PlaceWithHirId<'tcx> {
86    /// `HirId` of the expression or pattern producing this value.
87    pub hir_id: HirId,
88
89    /// Information about the `Place`.
90    pub place: Place<'tcx>,
91}
92
93impl<'tcx> PlaceWithHirId<'tcx> {
94    pub fn new(
95        hir_id: HirId,
96        base_ty: Ty<'tcx>,
97        base: PlaceBase,
98        projections: Vec<Projection<'tcx>>,
99    ) -> PlaceWithHirId<'tcx> {
100        PlaceWithHirId { hir_id, place: Place { base_ty, base, projections } }
101    }
102}
103
104impl<'tcx> Place<'tcx> {
105    /// Returns an iterator of the types that have to be dereferenced to access
106    /// the `Place`.
107    ///
108    /// The types are in the reverse order that they are applied. So if
109    /// `x: &*const u32` and the `Place` is `**x`, then the types returned are
110    ///`*const u32` then `&*const u32`.
111    pub fn deref_tys(&self) -> impl Iterator<Item = Ty<'tcx>> {
112        self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| {
113            if ProjectionKind::Deref == proj.kind {
114                Some(self.ty_before_projection(index))
115            } else {
116                None
117            }
118        })
119    }
120
121    /// Returns the type of this `Place` after all projections have been applied.
122    pub fn ty(&self) -> Ty<'tcx> {
123        self.projections.last().map_or(self.base_ty, |proj| proj.ty)
124    }
125
126    /// Returns the type of this `Place` immediately before `projection_index`th projection
127    /// is applied.
128    pub fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> {
129        if !(projection_index < self.projections.len()) {
    ::core::panicking::panic("assertion failed: projection_index < self.projections.len()")
};assert!(projection_index < self.projections.len());
130        if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty }
131    }
132}