Skip to main content

rustc_middle/ty/
adjustment.rs

1use rustc_abi::FieldIdx;
2use rustc_hir as hir;
3use rustc_hir::def_id::DefId;
4use rustc_hir::lang_items::LangItem;
5use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
6use rustc_span::Span;
7
8use crate::ty::{Ty, TyCtxt};
9
10#[derive(#[automatically_derived]
impl ::core::clone::Clone for PointerCoercion {
    #[inline]
    fn clone(&self) -> PointerCoercion {
        let _: ::core::clone::AssertParamIsClone<hir::Safety>;
        let _: ::core::clone::AssertParamIsClone<hir::Safety>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PointerCoercion { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for PointerCoercion {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            PointerCoercion::ReifyFnPointer(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ReifyFnPointer", &__self_0),
            PointerCoercion::UnsafeFnPointer =>
                ::core::fmt::Formatter::write_str(f, "UnsafeFnPointer"),
            PointerCoercion::ClosureFnPointer(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ClosureFnPointer", &__self_0),
            PointerCoercion::MutToConstPointer =>
                ::core::fmt::Formatter::write_str(f, "MutToConstPointer"),
            PointerCoercion::ArrayToPointer =>
                ::core::fmt::Formatter::write_str(f, "ArrayToPointer"),
            PointerCoercion::Unsize =>
                ::core::fmt::Formatter::write_str(f, "Unsize"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PointerCoercion {
    #[inline]
    fn eq(&self, other: &PointerCoercion) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (PointerCoercion::ReifyFnPointer(__self_0),
                    PointerCoercion::ReifyFnPointer(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (PointerCoercion::ClosureFnPointer(__self_0),
                    PointerCoercion::ClosureFnPointer(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PointerCoercion {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<hir::Safety>;
        let _: ::core::cmp::AssertParamIsEq<hir::Safety>;
    }
}Eq, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for PointerCoercion {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        PointerCoercion::ReifyFnPointer(ref __binding_0) => {
                            0usize
                        }
                        PointerCoercion::UnsafeFnPointer => { 1usize }
                        PointerCoercion::ClosureFnPointer(ref __binding_0) => {
                            2usize
                        }
                        PointerCoercion::MutToConstPointer => { 3usize }
                        PointerCoercion::ArrayToPointer => { 4usize }
                        PointerCoercion::Unsize => { 5usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    PointerCoercion::ReifyFnPointer(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    PointerCoercion::UnsafeFnPointer => {}
                    PointerCoercion::ClosureFnPointer(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    PointerCoercion::MutToConstPointer => {}
                    PointerCoercion::ArrayToPointer => {}
                    PointerCoercion::Unsize => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for PointerCoercion {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        PointerCoercion::ReifyFnPointer(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => { PointerCoercion::UnsafeFnPointer }
                    2usize => {
                        PointerCoercion::ClosureFnPointer(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => { PointerCoercion::MutToConstPointer }
                    4usize => { PointerCoercion::ArrayToPointer }
                    5usize => { PointerCoercion::Unsize }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `PointerCoercion`, expected 0..6, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::hash::Hash for PointerCoercion {
    #[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 {
            PointerCoercion::ReifyFnPointer(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            PointerCoercion::ClosureFnPointer(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PointerCoercion {
            #[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 {
                    PointerCoercion::ReifyFnPointer(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PointerCoercion::UnsafeFnPointer => {}
                    PointerCoercion::ClosureFnPointer(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PointerCoercion::MutToConstPointer => {}
                    PointerCoercion::ArrayToPointer => {}
                    PointerCoercion::Unsize => {}
                }
            }
        }
    };HashStable)]
11pub enum PointerCoercion {
12    /// Go from a fn-item type to a fn pointer or an unsafe fn pointer.
13    /// It cannot convert an unsafe fn-item to a safe fn pointer.
14    ReifyFnPointer(hir::Safety),
15
16    /// Go from a safe fn pointer to an unsafe fn pointer.
17    UnsafeFnPointer,
18
19    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
20    /// It cannot convert a closure that requires unsafe.
21    ClosureFnPointer(hir::Safety),
22
23    /// Go from a mut raw pointer to a const raw pointer.
24    MutToConstPointer,
25
26    /// Go from `*const [T; N]` to `*const T`
27    ArrayToPointer,
28
29    /// Unsize a pointer/reference value, e.g., `&[T; n]` to
30    /// `&[T]`. Note that the source could be a thin or wide pointer.
31    /// This will do things like convert thin pointers to wide
32    /// pointers, or convert structs containing thin pointers to
33    /// structs containing wide pointers, or convert between wide
34    /// pointers. We don't store the details of how the transform is
35    /// done (in fact, we don't know that, because it might depend on
36    /// the precise type parameters). We just store the target
37    /// type. Codegen backends and miri figure out what has to be done
38    /// based on the precise source/target type at hand.
39    Unsize,
40}
41
42/// Represents coercing a value to a different type of value.
43///
44/// We transform values by following a number of `Adjust` steps in order.
45/// See the documentation on variants of `Adjust` for more details.
46///
47/// Here are some common scenarios:
48///
49/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
50///    Here the pointer will be dereferenced N times (where a dereference can
51///    happen to raw or borrowed pointers or any smart pointer which implements
52///    `Deref`, including `Box<_>`). The types of dereferences is given by
53///    `autoderefs`. It can then be auto-referenced zero or one times, indicated
54///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
55///    `false`.
56///
57/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
58///    with a thin pointer, deref a number of times, unsize the underlying data,
59///    then autoref. The 'unsize' phase may change a fixed length array to a
60///    dynamically sized one, a concrete object to a trait object, or statically
61///    sized struct to a dynamically sized one. E.g., `&[i32; 4]` -> `&[i32]` is
62///    represented by:
63///
64///    ```ignore (illustrative)
65///    Deref(None) -> [i32; 4],
66///    Borrow(AutoBorrow::Ref) -> &[i32; 4],
67///    Unsize -> &[i32],
68///    ```
69///
70///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.
71///    E.g., `struct Foo<T> { x: T }` we can coerce `&Foo<[i32; 4]>` to `&Foo<[i32]>`
72///    The autoderef and -ref are the same as in the above example, but the type
73///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
74///    the underlying conversions from `[i32; 4]` to `[i32]`.
75///
76/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
77///    that case, we have the pointer we need coming in, so there are no
78///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
79///    At some point, of course, `Box` should move out of the compiler, in which
80///    case this is analogous to transforming a struct. E.g., `Box<[i32; 4]>` ->
81///    `Box<[i32]>` is an `Adjust::Unsize` with the target `Box<[i32]>`.
82#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Adjustment<'tcx> {
    #[inline]
    fn clone(&self) -> Adjustment<'tcx> {
        Adjustment {
            kind: ::core::clone::Clone::clone(&self.kind),
            target: ::core::clone::Clone::clone(&self.target),
        }
    }
}Clone, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for Adjustment<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Adjustment { kind: ref __binding_0, target: 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 Adjustment<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                Adjustment {
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                    target: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Adjustment<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Adjustment { kind: ref __binding_0, target: ref __binding_1
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Adjustment<'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 {
                        Adjustment { kind: __binding_0, target: __binding_1 } => {
                            Adjustment {
                                kind: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                target: ::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 {
                    Adjustment { kind: __binding_0, target: __binding_1 } => {
                        Adjustment {
                            kind: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            target: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Adjustment<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Adjustment { kind: ref __binding_0, target: 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)]
83pub struct Adjustment<'tcx> {
84    pub kind: Adjust,
85    pub target: Ty<'tcx>,
86}
87
88impl<'tcx> Adjustment<'tcx> {
89    pub fn is_region_borrow(&self) -> bool {
90        #[allow(non_exhaustive_omitted_patterns)] match self.kind {
    Adjust::Borrow(AutoBorrow::Ref(..)) => true,
    _ => false,
}matches!(self.kind, Adjust::Borrow(AutoBorrow::Ref(..)))
91    }
92}
93
94#[derive(#[automatically_derived]
impl ::core::clone::Clone for Adjust {
    #[inline]
    fn clone(&self) -> Adjust {
        match self {
            Adjust::NeverToAny => Adjust::NeverToAny,
            Adjust::Deref(__self_0) =>
                Adjust::Deref(::core::clone::Clone::clone(__self_0)),
            Adjust::Borrow(__self_0) =>
                Adjust::Borrow(::core::clone::Clone::clone(__self_0)),
            Adjust::Pointer(__self_0) =>
                Adjust::Pointer(::core::clone::Clone::clone(__self_0)),
            Adjust::ReborrowPin(__self_0) =>
                Adjust::ReborrowPin(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Adjust {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Adjust::NeverToAny =>
                ::core::fmt::Formatter::write_str(f, "NeverToAny"),
            Adjust::Deref(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Deref",
                    &__self_0),
            Adjust::Borrow(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Borrow",
                    &__self_0),
            Adjust::Pointer(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Pointer", &__self_0),
            Adjust::ReborrowPin(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ReborrowPin", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for Adjust {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Adjust::NeverToAny => { 0usize }
                        Adjust::Deref(ref __binding_0) => { 1usize }
                        Adjust::Borrow(ref __binding_0) => { 2usize }
                        Adjust::Pointer(ref __binding_0) => { 3usize }
                        Adjust::ReborrowPin(ref __binding_0) => { 4usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Adjust::NeverToAny => {}
                    Adjust::Deref(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Adjust::Borrow(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Adjust::Pointer(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Adjust::ReborrowPin(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 Adjust {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Adjust::NeverToAny }
                    1usize => {
                        Adjust::Deref(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => {
                        Adjust::Borrow(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => {
                        Adjust::Pointer(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    4usize => {
                        Adjust::ReborrowPin(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Adjust`, expected 0..5, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Adjust {
            #[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 {
                    Adjust::NeverToAny => {}
                    Adjust::Deref(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Adjust::Borrow(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Adjust::Pointer(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Adjust::ReborrowPin(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Adjust {
            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 {
                        Adjust::NeverToAny => { Adjust::NeverToAny }
                        Adjust::Deref(__binding_0) => {
                            Adjust::Deref(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        Adjust::Borrow(__binding_0) => {
                            Adjust::Borrow(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        Adjust::Pointer(__binding_0) => {
                            Adjust::Pointer(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        Adjust::ReborrowPin(__binding_0) => {
                            Adjust::ReborrowPin(::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 {
                    Adjust::NeverToAny => { Adjust::NeverToAny }
                    Adjust::Deref(__binding_0) => {
                        Adjust::Deref(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    Adjust::Borrow(__binding_0) => {
                        Adjust::Borrow(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    Adjust::Pointer(__binding_0) => {
                        Adjust::Pointer(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    Adjust::ReborrowPin(__binding_0) => {
                        Adjust::ReborrowPin(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Adjust {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Adjust::NeverToAny => {}
                    Adjust::Deref(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);
                                }
                            }
                        }
                    }
                    Adjust::Borrow(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);
                                }
                            }
                        }
                    }
                    Adjust::Pointer(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);
                                }
                            }
                        }
                    }
                    Adjust::ReborrowPin(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)]
95pub enum Adjust {
96    /// Go from ! to any type.
97    NeverToAny,
98
99    /// Dereference once, producing a place.
100    Deref(DerefAdjustKind),
101
102    /// Take the address and produce either a `&` or `*` pointer.
103    Borrow(AutoBorrow),
104
105    Pointer(PointerCoercion),
106
107    /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
108    ReborrowPin(hir::Mutability),
109}
110
111#[derive(#[automatically_derived]
impl ::core::marker::Copy for DerefAdjustKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for DerefAdjustKind {
    #[inline]
    fn clone(&self) -> DerefAdjustKind {
        let _: ::core::clone::AssertParamIsClone<OverloadedDeref>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DerefAdjustKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            DerefAdjustKind::Builtin =>
                ::core::fmt::Formatter::write_str(f, "Builtin"),
            DerefAdjustKind::Overloaded(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Overloaded", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for DerefAdjustKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        DerefAdjustKind::Builtin => { 0usize }
                        DerefAdjustKind::Overloaded(ref __binding_0) => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    DerefAdjustKind::Builtin => {}
                    DerefAdjustKind::Overloaded(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 DerefAdjustKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { DerefAdjustKind::Builtin }
                    1usize => {
                        DerefAdjustKind::Overloaded(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `DerefAdjustKind`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for DerefAdjustKind {
            #[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 {
                    DerefAdjustKind::Builtin => {}
                    DerefAdjustKind::Overloaded(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for DerefAdjustKind {
            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 {
                        DerefAdjustKind::Builtin => { DerefAdjustKind::Builtin }
                        DerefAdjustKind::Overloaded(__binding_0) => {
                            DerefAdjustKind::Overloaded(::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 {
                    DerefAdjustKind::Builtin => { DerefAdjustKind::Builtin }
                    DerefAdjustKind::Overloaded(__binding_0) => {
                        DerefAdjustKind::Overloaded(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for DerefAdjustKind {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    DerefAdjustKind::Builtin => {}
                    DerefAdjustKind::Overloaded(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)]
112pub enum DerefAdjustKind {
113    Builtin,
114    Overloaded(OverloadedDeref),
115}
116
117/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
118/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
119/// The target type is `U` in both cases, with the region and mutability
120/// being those shared by both the receiver and the returned reference.
121#[derive(#[automatically_derived]
impl ::core::marker::Copy for OverloadedDeref { }Copy, #[automatically_derived]
impl ::core::clone::Clone for OverloadedDeref {
    #[inline]
    fn clone(&self) -> OverloadedDeref {
        let _: ::core::clone::AssertParamIsClone<hir::Mutability>;
        let _: ::core::clone::AssertParamIsClone<Span>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for OverloadedDeref {
    #[inline]
    fn eq(&self, other: &OverloadedDeref) -> bool {
        self.mutbl == other.mutbl && self.span == other.span
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for OverloadedDeref {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "OverloadedDeref", "mutbl", &self.mutbl, "span", &&self.span)
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for OverloadedDeref {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    OverloadedDeref {
                        mutbl: ref __binding_0, span: 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 OverloadedDeref {
            fn decode(__decoder: &mut __D) -> Self {
                OverloadedDeref {
                    mutbl: ::rustc_serialize::Decodable::decode(__decoder),
                    span: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for OverloadedDeref {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    OverloadedDeref {
                        mutbl: ref __binding_0, span: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
122#[derive(const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for OverloadedDeref {
            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 {
                        OverloadedDeref { mutbl: __binding_0, span: __binding_1 } =>
                            {
                            OverloadedDeref {
                                mutbl: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                span: ::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 {
                    OverloadedDeref { mutbl: __binding_0, span: __binding_1 } =>
                        {
                        OverloadedDeref {
                            mutbl: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            span: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for OverloadedDeref {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    OverloadedDeref {
                        mutbl: ref __binding_0, span: 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)]
123pub struct OverloadedDeref {
124    pub mutbl: hir::Mutability,
125    /// The `Span` associated with the field access or method call
126    /// that triggered this overloaded deref.
127    pub span: Span,
128}
129
130impl OverloadedDeref {
131    /// Get the [`DefId`] of the method call for the given `Deref`/`DerefMut` trait
132    /// for this overloaded deref's mutability.
133    pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>) -> DefId {
134        let trait_def_id = match self.mutbl {
135            hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, self.span),
136            hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, self.span),
137        };
138        tcx.associated_items(trait_def_id)
139            .in_definition_order()
140            .find(|item| item.is_fn())
141            .unwrap()
142            .def_id
143    }
144}
145
146/// At least for initial deployment, we want to limit two-phase borrows to
147/// only a few specific cases. Right now, those are mostly "things that desugar"
148/// into method calls:
149/// - using `x.some_method()` syntax, where some_method takes `&mut self`,
150/// - using `Foo::some_method(&mut x, ...)` syntax,
151/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).
152/// Anything else should be rejected until generalized two-phase borrow support
153/// is implemented. Right now, dataflow can't handle the general case where there
154/// is more than one use of a mutable borrow, and we don't want to accept too much
155/// new code via two-phase borrows, so we try to limit where we create two-phase
156/// capable mutable borrows.
157/// See #49434 for tracking.
158#[derive(#[automatically_derived]
impl ::core::marker::Copy for AllowTwoPhase { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AllowTwoPhase {
    #[inline]
    fn clone(&self) -> AllowTwoPhase { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AllowTwoPhase {
    #[inline]
    fn eq(&self, other: &AllowTwoPhase) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for AllowTwoPhase {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AllowTwoPhase::Yes => "Yes",
                AllowTwoPhase::No => "No",
            })
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for AllowTwoPhase {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        AllowTwoPhase::Yes => { 0usize }
                        AllowTwoPhase::No => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    AllowTwoPhase::Yes => {}
                    AllowTwoPhase::No => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for AllowTwoPhase {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { AllowTwoPhase::Yes }
                    1usize => { AllowTwoPhase::No }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AllowTwoPhase`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for AllowTwoPhase {
            #[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 {
                    AllowTwoPhase::Yes => {}
                    AllowTwoPhase::No => {}
                }
            }
        }
    };HashStable)]
159pub enum AllowTwoPhase {
160    Yes,
161    No,
162}
163
164#[derive(#[automatically_derived]
impl ::core::marker::Copy for AutoBorrowMutability { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AutoBorrowMutability {
    #[inline]
    fn clone(&self) -> AutoBorrowMutability {
        let _: ::core::clone::AssertParamIsClone<AllowTwoPhase>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AutoBorrowMutability {
    #[inline]
    fn eq(&self, other: &AutoBorrowMutability) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (AutoBorrowMutability::Mut { allow_two_phase_borrow: __self_0
                    }, AutoBorrowMutability::Mut {
                    allow_two_phase_borrow: __arg1_0 }) => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for AutoBorrowMutability {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            AutoBorrowMutability::Mut { allow_two_phase_borrow: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Mut",
                    "allow_two_phase_borrow", &__self_0),
            AutoBorrowMutability::Not =>
                ::core::fmt::Formatter::write_str(f, "Not"),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for AutoBorrowMutability {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        AutoBorrowMutability::Mut {
                            allow_two_phase_borrow: ref __binding_0 } => {
                            0usize
                        }
                        AutoBorrowMutability::Not => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    AutoBorrowMutability::Mut {
                        allow_two_phase_borrow: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AutoBorrowMutability::Not => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for AutoBorrowMutability {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        AutoBorrowMutability::Mut {
                            allow_two_phase_borrow: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    1usize => { AutoBorrowMutability::Not }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AutoBorrowMutability`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for AutoBorrowMutability {
            #[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 {
                    AutoBorrowMutability::Mut {
                        allow_two_phase_borrow: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    AutoBorrowMutability::Not => {}
                }
            }
        }
    };HashStable)]
165pub enum AutoBorrowMutability {
166    Mut { allow_two_phase_borrow: AllowTwoPhase },
167    Not,
168}
169
170impl AutoBorrowMutability {
171    /// Creates an `AutoBorrowMutability` from a mutability and allowance of two phase borrows.
172    ///
173    /// Note that when `mutbl.is_not()`, `allow_two_phase_borrow` is ignored
174    pub fn new(mutbl: hir::Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {
175        match mutbl {
176            hir::Mutability::Not => Self::Not,
177            hir::Mutability::Mut => Self::Mut { allow_two_phase_borrow },
178        }
179    }
180}
181
182impl From<AutoBorrowMutability> for hir::Mutability {
183    fn from(m: AutoBorrowMutability) -> Self {
184        match m {
185            AutoBorrowMutability::Mut { .. } => hir::Mutability::Mut,
186            AutoBorrowMutability::Not => hir::Mutability::Not,
187        }
188    }
189}
190
191#[derive(#[automatically_derived]
impl ::core::marker::Copy for AutoBorrow { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AutoBorrow {
    #[inline]
    fn clone(&self) -> AutoBorrow {
        let _: ::core::clone::AssertParamIsClone<AutoBorrowMutability>;
        let _: ::core::clone::AssertParamIsClone<hir::Mutability>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AutoBorrow {
    #[inline]
    fn eq(&self, other: &AutoBorrow) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (AutoBorrow::Ref(__self_0), AutoBorrow::Ref(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (AutoBorrow::RawPtr(__self_0), AutoBorrow::RawPtr(__arg1_0))
                    => __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for AutoBorrow {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            AutoBorrow::Ref(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Ref",
                    &__self_0),
            AutoBorrow::RawPtr(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "RawPtr",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for AutoBorrow {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        AutoBorrow::Ref(ref __binding_0) => { 0usize }
                        AutoBorrow::RawPtr(ref __binding_0) => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    AutoBorrow::Ref(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AutoBorrow::RawPtr(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 AutoBorrow {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        AutoBorrow::Ref(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        AutoBorrow::RawPtr(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AutoBorrow`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for AutoBorrow {
            #[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 {
                    AutoBorrow::Ref(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    AutoBorrow::RawPtr(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
192#[derive(const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for AutoBorrow {
            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 {
                        AutoBorrow::Ref(__binding_0) => {
                            AutoBorrow::Ref(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        AutoBorrow::RawPtr(__binding_0) => {
                            AutoBorrow::RawPtr(::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 {
                    AutoBorrow::Ref(__binding_0) => {
                        AutoBorrow::Ref(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    AutoBorrow::RawPtr(__binding_0) => {
                        AutoBorrow::RawPtr(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for AutoBorrow {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    AutoBorrow::Ref(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);
                                }
                            }
                        }
                    }
                    AutoBorrow::RawPtr(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)]
193pub enum AutoBorrow {
194    /// Converts from T to &T.
195    Ref(AutoBorrowMutability),
196
197    /// Converts from T to *T.
198    RawPtr(hir::Mutability),
199}
200
201/// Information for `CoerceUnsized` impls, storing information we
202/// have computed about the coercion.
203///
204/// This struct can be obtained via the `coerce_impl_info` query.
205/// Demanding this struct also has the side-effect of reporting errors
206/// for inappropriate impls.
207#[derive(#[automatically_derived]
impl ::core::clone::Clone for CoerceUnsizedInfo {
    #[inline]
    fn clone(&self) -> CoerceUnsizedInfo {
        let _: ::core::clone::AssertParamIsClone<Option<CustomCoerceUnsized>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoerceUnsizedInfo { }Copy, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for CoerceUnsizedInfo {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    CoerceUnsizedInfo { custom_kind: 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 CoerceUnsizedInfo {
            fn decode(__decoder: &mut __D) -> Self {
                CoerceUnsizedInfo {
                    custom_kind: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::fmt::Debug for CoerceUnsizedInfo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "CoerceUnsizedInfo", "custom_kind", &&self.custom_kind)
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for CoerceUnsizedInfo {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    CoerceUnsizedInfo { custom_kind: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
208pub struct CoerceUnsizedInfo {
209    /// If this is a "custom coerce" impl, then what kind of custom
210    /// coercion is it? This applies to impls of `CoerceUnsized` for
211    /// structs, primarily, where we store a bit of info about which
212    /// fields need to be coerced.
213    pub custom_kind: Option<CustomCoerceUnsized>,
214}
215
216#[derive(#[automatically_derived]
impl ::core::clone::Clone for CustomCoerceUnsized {
    #[inline]
    fn clone(&self) -> CustomCoerceUnsized {
        let _: ::core::clone::AssertParamIsClone<FieldIdx>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CustomCoerceUnsized { }Copy, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for CustomCoerceUnsized {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    CustomCoerceUnsized::Struct(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 CustomCoerceUnsized {
            fn decode(__decoder: &mut __D) -> Self {
                CustomCoerceUnsized::Struct(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::fmt::Debug for CustomCoerceUnsized {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            CustomCoerceUnsized::Struct(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Struct",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for CustomCoerceUnsized {
            #[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 {
                    CustomCoerceUnsized::Struct(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
217pub enum CustomCoerceUnsized {
218    /// Records the index of the field being coerced.
219    Struct(FieldIdx),
220}
221
222/// Represents an implicit coercion applied to the scrutinee of a match before testing a pattern
223/// against it. Currently, this is used only for implicit dereferences.
224#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for PatAdjustment<'tcx> {
    #[inline]
    fn clone(&self) -> PatAdjustment<'tcx> {
        let _: ::core::clone::AssertParamIsClone<PatAdjust>;
        let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for PatAdjustment<'tcx> { }Copy, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for PatAdjustment<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    PatAdjustment {
                        kind: ref __binding_0, source: 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 PatAdjustment<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                PatAdjustment {
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                    source: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PatAdjustment<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    PatAdjustment {
                        kind: ref __binding_0, source: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatAdjustment<'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 {
                        PatAdjustment { kind: __binding_0, source: __binding_1 } =>
                            {
                            PatAdjustment {
                                kind: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                source: ::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 {
                    PatAdjustment { kind: __binding_0, source: __binding_1 } =>
                        {
                        PatAdjustment {
                            kind: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            source: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatAdjustment<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    PatAdjustment {
                        kind: ref __binding_0, source: 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)]
225pub struct PatAdjustment<'tcx> {
226    pub kind: PatAdjust,
227    /// The type of the scrutinee before the adjustment is applied, or the "adjusted type" of the
228    /// pattern.
229    pub source: Ty<'tcx>,
230}
231
232/// Represents implicit coercions of patterns' types, rather than values' types.
233#[derive(#[automatically_derived]
impl ::core::clone::Clone for PatAdjust {
    #[inline]
    fn clone(&self) -> PatAdjust { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PatAdjust { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for PatAdjust {
    #[inline]
    fn eq(&self, other: &PatAdjust) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PatAdjust {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                PatAdjust::BuiltinDeref => "BuiltinDeref",
                PatAdjust::OverloadedDeref => "OverloadedDeref",
                PatAdjust::PinDeref => "PinDeref",
            })
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for PatAdjust {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        PatAdjust::BuiltinDeref => { 0usize }
                        PatAdjust::OverloadedDeref => { 1usize }
                        PatAdjust::PinDeref => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    PatAdjust::BuiltinDeref => {}
                    PatAdjust::OverloadedDeref => {}
                    PatAdjust::PinDeref => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for PatAdjust {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { PatAdjust::BuiltinDeref }
                    1usize => { PatAdjust::OverloadedDeref }
                    2usize => { PatAdjust::PinDeref }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `PatAdjust`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PatAdjust {
            #[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 {
                    PatAdjust::BuiltinDeref => {}
                    PatAdjust::OverloadedDeref => {}
                    PatAdjust::PinDeref => {}
                }
            }
        }
    };HashStable)]
234#[derive(const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatAdjust {
            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 {
                        PatAdjust::BuiltinDeref => { PatAdjust::BuiltinDeref }
                        PatAdjust::OverloadedDeref => { PatAdjust::OverloadedDeref }
                        PatAdjust::PinDeref => { PatAdjust::PinDeref }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    PatAdjust::BuiltinDeref => { PatAdjust::BuiltinDeref }
                    PatAdjust::OverloadedDeref => { PatAdjust::OverloadedDeref }
                    PatAdjust::PinDeref => { PatAdjust::PinDeref }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatAdjust {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    PatAdjust::BuiltinDeref => {}
                    PatAdjust::OverloadedDeref => {}
                    PatAdjust::PinDeref => {}
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable)]
235pub enum PatAdjust {
236    /// An implicit dereference before matching, such as when matching the pattern `0` against a
237    /// scrutinee of type `&u8` or `&mut u8`.
238    BuiltinDeref,
239    /// An implicit call to `Deref(Mut)::deref(_mut)` before matching, such as when matching the
240    /// pattern `[..]` against a scrutinee of type `Vec<T>`.
241    OverloadedDeref,
242    /// An implicit dereference before matching a `&pin` reference (under feature `pin_ergonomics`),
243    /// which will be lowered as a builtin deref of the private field `__pointer` in `Pin`
244    PinDeref,
245}