Skip to main content

rustc_middle/
thir.rs

1//! THIR datatypes and definitions. See the [rustc dev guide] for more info.
2//!
3//! If you compare the THIR [`ExprKind`] to [`hir::ExprKind`], you will see it is
4//! a good bit simpler. In fact, a number of the more straight-forward
5//! MIR simplifications are already done in the lowering to THIR. For
6//! example, method calls and overloaded operators are absent: they are
7//! expected to be converted into [`ExprKind::Call`] instances.
8//!
9//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html
10
11use std::cmp::Ordering;
12use std::fmt;
13use std::ops::Index;
14use std::sync::Arc;
15
16use rustc_abi::{FieldIdx, Integer, Size, VariantIdx};
17use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece, Mutability};
18use rustc_hir as hir;
19use rustc_hir::def_id::DefId;
20use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
21use rustc_index::{IndexVec, newtype_index};
22use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
23use rustc_span::def_id::LocalDefId;
24use rustc_span::{ErrorGuaranteed, Span, Symbol};
25use rustc_target::asm::InlineAsmRegOrRegClass;
26use tracing::instrument;
27
28use crate::middle::region;
29use crate::mir::interpret::AllocId;
30use crate::mir::{self, AssignOp, BinOp, BorrowKind, FakeReadCause, UnOp};
31use crate::thir::visit::for_each_immediate_subpat;
32use crate::ty::adjustment::PointerCoercion;
33use crate::ty::layout::IntegerExt;
34use crate::ty::{
35    self, AdtDef, CanonicalUserType, CanonicalUserTypeAnnotation, FnSig, GenericArgsRef, Ty,
36    TyCtxt, UpvarArgs,
37};
38
39pub mod visit;
40
41macro_rules! thir_with_elements {
42    (
43        $($name:ident: $id:ty => $value:ty => $format:literal,)*
44    ) => {
45        $(
46            newtype_index! {
47                #[derive(HashStable)]
48                #[debug_format = $format]
49                pub struct $id {}
50            }
51        )*
52
53        // Note: Making `Thir` implement `Clone` is useful for external tools that need access to
54        // THIR bodies even after the `Steal` query result has been stolen.
55        // One such tool is https://github.com/rust-corpus/qrates/.
56        /// A container for a THIR body.
57        ///
58        /// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
59        #[derive(Debug, HashStable, Clone)]
60        pub struct Thir<'tcx> {
61            pub body_type: BodyTy<'tcx>,
62            $(
63                pub $name: IndexVec<$id, $value>,
64            )*
65        }
66
67        impl<'tcx> Thir<'tcx> {
68            pub fn new(body_type: BodyTy<'tcx>) -> Thir<'tcx> {
69                Thir {
70                    body_type,
71                    $(
72                        $name: IndexVec::new(),
73                    )*
74                }
75            }
76        }
77
78        $(
79            impl<'tcx> Index<$id> for Thir<'tcx> {
80                type Output = $value;
81                fn index(&self, index: $id) -> &Self::Output {
82                    &self.$name[index]
83                }
84            }
85        )*
86    }
87}
88
89impl ::std::fmt::Debug for ParamId {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("p{0}", self.as_u32()))
    }
}
/// A container for a THIR body.
///
/// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
pub struct Thir<'tcx> {
    pub body_type: BodyTy<'tcx>,
    pub arms: IndexVec<ArmId, Arm<'tcx>>,
    pub blocks: IndexVec<BlockId, Block>,
    pub exprs: IndexVec<ExprId, Expr<'tcx>>,
    pub stmts: IndexVec<StmtId, Stmt<'tcx>>,
    pub params: IndexVec<ParamId, Param<'tcx>>,
}
#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Thir<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["body_type", "arms", "blocks", "exprs", "stmts", "params"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.body_type, &self.arms, &self.blocks, &self.exprs,
                        &self.stmts, &&self.params];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Thir", names,
            values)
    }
}
const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Thir<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Thir {
                        body_type: ref __binding_0,
                        arms: ref __binding_1,
                        blocks: ref __binding_2,
                        exprs: ref __binding_3,
                        stmts: ref __binding_4,
                        params: ref __binding_5 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                        { __binding_5.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Thir<'tcx> {
    #[inline]
    fn clone(&self) -> Thir<'tcx> {
        Thir {
            body_type: ::core::clone::Clone::clone(&self.body_type),
            arms: ::core::clone::Clone::clone(&self.arms),
            blocks: ::core::clone::Clone::clone(&self.blocks),
            exprs: ::core::clone::Clone::clone(&self.exprs),
            stmts: ::core::clone::Clone::clone(&self.stmts),
            params: ::core::clone::Clone::clone(&self.params),
        }
    }
}
impl<'tcx> Thir<'tcx> {
    pub fn new(body_type: BodyTy<'tcx>) -> Thir<'tcx> {
        Thir {
            body_type,
            arms: IndexVec::new(),
            blocks: IndexVec::new(),
            exprs: IndexVec::new(),
            stmts: IndexVec::new(),
            params: IndexVec::new(),
        }
    }
}
impl<'tcx> Index<ArmId> for Thir<'tcx> {
    type Output = Arm<'tcx>;
    fn index(&self, index: ArmId) -> &Self::Output { &self.arms[index] }
}
impl<'tcx> Index<BlockId> for Thir<'tcx> {
    type Output = Block;
    fn index(&self, index: BlockId) -> &Self::Output { &self.blocks[index] }
}
impl<'tcx> Index<ExprId> for Thir<'tcx> {
    type Output = Expr<'tcx>;
    fn index(&self, index: ExprId) -> &Self::Output { &self.exprs[index] }
}
impl<'tcx> Index<StmtId> for Thir<'tcx> {
    type Output = Stmt<'tcx>;
    fn index(&self, index: StmtId) -> &Self::Output { &self.stmts[index] }
}
impl<'tcx> Index<ParamId> for Thir<'tcx> {
    type Output = Param<'tcx>;
    fn index(&self, index: ParamId) -> &Self::Output { &self.params[index] }
}thir_with_elements! {
90    arms: ArmId => Arm<'tcx> => "a{}",
91    blocks: BlockId => Block => "b{}",
92    exprs: ExprId => Expr<'tcx> => "e{}",
93    stmts: StmtId => Stmt<'tcx> => "s{}",
94    params: ParamId => Param<'tcx> => "p{}",
95}
96
97#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for BodyTy<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            BodyTy::Const(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Const",
                    &__self_0),
            BodyTy::Fn(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Fn",
                    &__self_0),
            BodyTy::GlobalAsm(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "GlobalAsm", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for BodyTy<'tcx> {
            #[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 {
                    BodyTy::Const(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    BodyTy::Fn(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    BodyTy::GlobalAsm(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for BodyTy<'tcx> {
    #[inline]
    fn clone(&self) -> BodyTy<'tcx> {
        match self {
            BodyTy::Const(__self_0) =>
                BodyTy::Const(::core::clone::Clone::clone(__self_0)),
            BodyTy::Fn(__self_0) =>
                BodyTy::Fn(::core::clone::Clone::clone(__self_0)),
            BodyTy::GlobalAsm(__self_0) =>
                BodyTy::GlobalAsm(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
98pub enum BodyTy<'tcx> {
99    Const(Ty<'tcx>),
100    Fn(FnSig<'tcx>),
101    GlobalAsm(Ty<'tcx>),
102}
103
104/// Description of a type-checked function parameter.
105#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Param<'tcx> {
    #[inline]
    fn clone(&self) -> Param<'tcx> {
        Param {
            pat: ::core::clone::Clone::clone(&self.pat),
            ty: ::core::clone::Clone::clone(&self.ty),
            ty_span: ::core::clone::Clone::clone(&self.ty_span),
            self_kind: ::core::clone::Clone::clone(&self.self_kind),
            hir_id: ::core::clone::Clone::clone(&self.hir_id),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Param<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f, "Param", "pat",
            &self.pat, "ty", &self.ty, "ty_span", &self.ty_span, "self_kind",
            &self.self_kind, "hir_id", &&self.hir_id)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Param<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Param {
                        pat: ref __binding_0,
                        ty: ref __binding_1,
                        ty_span: ref __binding_2,
                        self_kind: ref __binding_3,
                        hir_id: ref __binding_4 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
106pub struct Param<'tcx> {
107    /// The pattern that appears in the parameter list, or None for implicit parameters.
108    pub pat: Option<Box<Pat<'tcx>>>,
109    /// The possibly inferred type.
110    pub ty: Ty<'tcx>,
111    /// Span of the explicitly provided type, or None if inferred for closures.
112    pub ty_span: Option<Span>,
113    /// Whether this param is `self`, and how it is bound.
114    pub self_kind: Option<hir::ImplicitSelfKind>,
115    /// HirId for lints.
116    pub hir_id: Option<HirId>,
117}
118
119#[derive(#[automatically_derived]
impl ::core::clone::Clone for Block {
    #[inline]
    fn clone(&self) -> Block {
        Block {
            targeted_by_break: ::core::clone::Clone::clone(&self.targeted_by_break),
            region_scope: ::core::clone::Clone::clone(&self.region_scope),
            span: ::core::clone::Clone::clone(&self.span),
            stmts: ::core::clone::Clone::clone(&self.stmts),
            expr: ::core::clone::Clone::clone(&self.expr),
            safety_mode: ::core::clone::Clone::clone(&self.safety_mode),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Block {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["targeted_by_break", "region_scope", "span", "stmts", "expr",
                        "safety_mode"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.targeted_by_break, &self.region_scope, &self.span,
                        &self.stmts, &self.expr, &&self.safety_mode];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Block", names,
            values)
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Block {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Block {
                        targeted_by_break: ref __binding_0,
                        region_scope: ref __binding_1,
                        span: ref __binding_2,
                        stmts: ref __binding_3,
                        expr: ref __binding_4,
                        safety_mode: ref __binding_5 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                        { __binding_5.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
120pub struct Block {
121    /// Whether the block itself has a label. Used by `label: {}`
122    /// and `try` blocks.
123    ///
124    /// This does *not* include labels on loops, e.g. `'label: loop {}`.
125    pub targeted_by_break: bool,
126    pub region_scope: region::Scope,
127    /// The span of the block, including the opening braces,
128    /// the label, and the `unsafe` keyword, if present.
129    pub span: Span,
130    /// The statements in the blocK.
131    pub stmts: Box<[StmtId]>,
132    /// The trailing expression of the block, if any.
133    pub expr: Option<ExprId>,
134    pub safety_mode: BlockSafety,
135}
136
137type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
138
139#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for AdtExpr<'tcx> {
    #[inline]
    fn clone(&self) -> AdtExpr<'tcx> {
        AdtExpr {
            adt_def: ::core::clone::Clone::clone(&self.adt_def),
            variant_index: ::core::clone::Clone::clone(&self.variant_index),
            args: ::core::clone::Clone::clone(&self.args),
            user_ty: ::core::clone::Clone::clone(&self.user_ty),
            fields: ::core::clone::Clone::clone(&self.fields),
            base: ::core::clone::Clone::clone(&self.base),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for AdtExpr<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["adt_def", "variant_index", "args", "user_ty", "fields",
                        "base"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.adt_def, &self.variant_index, &self.args, &self.user_ty,
                        &self.fields, &&self.base];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "AdtExpr",
            names, values)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for AdtExpr<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    AdtExpr {
                        adt_def: ref __binding_0,
                        variant_index: ref __binding_1,
                        args: ref __binding_2,
                        user_ty: ref __binding_3,
                        fields: ref __binding_4,
                        base: ref __binding_5 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                        { __binding_5.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
140pub struct AdtExpr<'tcx> {
141    /// The ADT we're constructing.
142    pub adt_def: AdtDef<'tcx>,
143    /// The variant of the ADT.
144    pub variant_index: VariantIdx,
145    pub args: GenericArgsRef<'tcx>,
146
147    /// Optional user-given args: for something like `let x =
148    /// Bar::<T> { ... }`.
149    pub user_ty: UserTy<'tcx>,
150
151    pub fields: Box<[FieldExpr]>,
152    /// The base, e.g. `Foo {x: 1, ..base}`.
153    pub base: AdtExprBase<'tcx>,
154}
155
156#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for AdtExprBase<'tcx> {
    #[inline]
    fn clone(&self) -> AdtExprBase<'tcx> {
        match self {
            AdtExprBase::None => AdtExprBase::None,
            AdtExprBase::Base(__self_0) =>
                AdtExprBase::Base(::core::clone::Clone::clone(__self_0)),
            AdtExprBase::DefaultFields(__self_0) =>
                AdtExprBase::DefaultFields(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for AdtExprBase<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            AdtExprBase::None => ::core::fmt::Formatter::write_str(f, "None"),
            AdtExprBase::Base(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Base",
                    &__self_0),
            AdtExprBase::DefaultFields(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "DefaultFields", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for AdtExprBase<'tcx> {
            #[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 {
                    AdtExprBase::None => {}
                    AdtExprBase::Base(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    AdtExprBase::DefaultFields(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
157pub enum AdtExprBase<'tcx> {
158    /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
159    None,
160    /// A struct expression with a "base", an expression of the same type as the outer struct that
161    /// will be used to populate any fields not explicitly mentioned: `Foo { ..base }`
162    Base(FruInfo<'tcx>),
163    /// A struct expression with a `..` tail but no "base" expression. The values from the struct
164    /// fields' default values will be used to populate any fields not explicitly mentioned:
165    /// `Foo { .. }`.
166    DefaultFields(Box<[Ty<'tcx>]>),
167}
168
169#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for ClosureExpr<'tcx> {
    #[inline]
    fn clone(&self) -> ClosureExpr<'tcx> {
        ClosureExpr {
            closure_id: ::core::clone::Clone::clone(&self.closure_id),
            args: ::core::clone::Clone::clone(&self.args),
            upvars: ::core::clone::Clone::clone(&self.upvars),
            movability: ::core::clone::Clone::clone(&self.movability),
            fake_reads: ::core::clone::Clone::clone(&self.fake_reads),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ClosureExpr<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f, "ClosureExpr",
            "closure_id", &self.closure_id, "args", &self.args, "upvars",
            &self.upvars, "movability", &self.movability, "fake_reads",
            &&self.fake_reads)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for ClosureExpr<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    ClosureExpr {
                        closure_id: ref __binding_0,
                        args: ref __binding_1,
                        upvars: ref __binding_2,
                        movability: ref __binding_3,
                        fake_reads: ref __binding_4 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
170pub struct ClosureExpr<'tcx> {
171    pub closure_id: LocalDefId,
172    pub args: UpvarArgs<'tcx>,
173    pub upvars: Box<[ExprId]>,
174    pub movability: Option<hir::Movability>,
175    pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>,
176}
177
178#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for InlineAsmExpr<'tcx> {
    #[inline]
    fn clone(&self) -> InlineAsmExpr<'tcx> {
        InlineAsmExpr {
            asm_macro: ::core::clone::Clone::clone(&self.asm_macro),
            template: ::core::clone::Clone::clone(&self.template),
            operands: ::core::clone::Clone::clone(&self.operands),
            options: ::core::clone::Clone::clone(&self.options),
            line_spans: ::core::clone::Clone::clone(&self.line_spans),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InlineAsmExpr<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f, "InlineAsmExpr",
            "asm_macro", &self.asm_macro, "template", &self.template,
            "operands", &self.operands, "options", &self.options,
            "line_spans", &&self.line_spans)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for InlineAsmExpr<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    InlineAsmExpr {
                        asm_macro: ref __binding_0,
                        template: ref __binding_1,
                        operands: ref __binding_2,
                        options: ref __binding_3,
                        line_spans: ref __binding_4 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
179pub struct InlineAsmExpr<'tcx> {
180    pub asm_macro: AsmMacro,
181    pub template: &'tcx [InlineAsmTemplatePiece],
182    pub operands: Box<[InlineAsmOperand<'tcx>]>,
183    pub options: InlineAsmOptions,
184    pub line_spans: &'tcx [Span],
185}
186
187#[derive(#[automatically_derived]
impl ::core::marker::Copy for BlockSafety { }Copy, #[automatically_derived]
impl ::core::clone::Clone for BlockSafety {
    #[inline]
    fn clone(&self) -> BlockSafety {
        let _: ::core::clone::AssertParamIsClone<HirId>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for BlockSafety {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            BlockSafety::Safe => ::core::fmt::Formatter::write_str(f, "Safe"),
            BlockSafety::BuiltinUnsafe =>
                ::core::fmt::Formatter::write_str(f, "BuiltinUnsafe"),
            BlockSafety::ExplicitUnsafe(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ExplicitUnsafe", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for BlockSafety {
            #[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 {
                    BlockSafety::Safe => {}
                    BlockSafety::BuiltinUnsafe => {}
                    BlockSafety::ExplicitUnsafe(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
188pub enum BlockSafety {
189    Safe,
190    /// A compiler-generated unsafe block
191    BuiltinUnsafe,
192    /// An `unsafe` block. The `HirId` is the ID of the block.
193    ExplicitUnsafe(HirId),
194}
195
196#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Stmt<'tcx> {
    #[inline]
    fn clone(&self) -> Stmt<'tcx> {
        Stmt { kind: ::core::clone::Clone::clone(&self.kind) }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Stmt<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Stmt", "kind",
            &&self.kind)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Stmt<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Stmt { kind: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
197pub struct Stmt<'tcx> {
198    pub kind: StmtKind<'tcx>,
199}
200
201#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for StmtKind<'tcx> {
    #[inline]
    fn clone(&self) -> StmtKind<'tcx> {
        match self {
            StmtKind::Expr { scope: __self_0, expr: __self_1 } =>
                StmtKind::Expr {
                    scope: ::core::clone::Clone::clone(__self_0),
                    expr: ::core::clone::Clone::clone(__self_1),
                },
            StmtKind::Let {
                remainder_scope: __self_0,
                init_scope: __self_1,
                pattern: __self_2,
                initializer: __self_3,
                else_block: __self_4,
                hir_id: __self_5,
                span: __self_6 } =>
                StmtKind::Let {
                    remainder_scope: ::core::clone::Clone::clone(__self_0),
                    init_scope: ::core::clone::Clone::clone(__self_1),
                    pattern: ::core::clone::Clone::clone(__self_2),
                    initializer: ::core::clone::Clone::clone(__self_3),
                    else_block: ::core::clone::Clone::clone(__self_4),
                    hir_id: ::core::clone::Clone::clone(__self_5),
                    span: ::core::clone::Clone::clone(__self_6),
                },
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for StmtKind<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            StmtKind::Expr { scope: __self_0, expr: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Expr",
                    "scope", __self_0, "expr", &__self_1),
            StmtKind::Let {
                remainder_scope: __self_0,
                init_scope: __self_1,
                pattern: __self_2,
                initializer: __self_3,
                else_block: __self_4,
                hir_id: __self_5,
                span: __self_6 } => {
                let names: &'static _ =
                    &["remainder_scope", "init_scope", "pattern", "initializer",
                                "else_block", "hir_id", "span"];
                let values: &[&dyn ::core::fmt::Debug] =
                    &[__self_0, __self_1, __self_2, __self_3, __self_4,
                                __self_5, &__self_6];
                ::core::fmt::Formatter::debug_struct_fields_finish(f, "Let",
                    names, values)
            }
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for StmtKind<'tcx> {
            #[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 {
                    StmtKind::Expr {
                        scope: ref __binding_0, expr: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    StmtKind::Let {
                        remainder_scope: ref __binding_0,
                        init_scope: ref __binding_1,
                        pattern: ref __binding_2,
                        initializer: ref __binding_3,
                        else_block: ref __binding_4,
                        hir_id: ref __binding_5,
                        span: ref __binding_6 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                        { __binding_5.hash_stable(__hcx, __hasher); }
                        { __binding_6.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
202pub enum StmtKind<'tcx> {
203    /// An expression with a trailing semicolon.
204    Expr {
205        /// The scope for this statement; may be used as lifetime of temporaries.
206        scope: region::Scope,
207
208        /// The expression being evaluated in this statement.
209        expr: ExprId,
210    },
211
212    /// A `let` binding.
213    Let {
214        /// The scope for variables bound in this `let`; it covers this and
215        /// all the remaining statements in the block.
216        remainder_scope: region::Scope,
217
218        /// The scope for the initialization itself; might be used as
219        /// lifetime of temporaries.
220        init_scope: region::Scope,
221
222        /// `let <PAT> = ...`
223        ///
224        /// If a type annotation is included, it is added as an ascription pattern.
225        pattern: Box<Pat<'tcx>>,
226
227        /// `let pat: ty = <INIT>`
228        initializer: Option<ExprId>,
229
230        /// `let pat: ty = <INIT> else { <ELSE> }`
231        else_block: Option<BlockId>,
232
233        /// The [`HirId`] for this `let` statement.
234        hir_id: HirId,
235
236        /// Span of the `let <PAT> = <INIT>` part.
237        span: Span,
238    },
239}
240
241#[derive(#[automatically_derived]
impl ::core::clone::Clone for LocalVarId {
    #[inline]
    fn clone(&self) -> LocalVarId {
        let _: ::core::clone::AssertParamIsClone<HirId>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for LocalVarId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "LocalVarId",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for LocalVarId { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for LocalVarId {
    #[inline]
    fn eq(&self, other: &LocalVarId) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for LocalVarId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<HirId>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for LocalVarId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for LocalVarId {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    LocalVarId(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for LocalVarId {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    LocalVarId(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 LocalVarId {
            fn decode(__decoder: &mut __D) -> Self {
                LocalVarId(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };TyDecodable)]
242pub struct LocalVarId(pub HirId);
243
244/// A THIR expression.
245#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Expr<'tcx> {
    #[inline]
    fn clone(&self) -> Expr<'tcx> {
        Expr {
            kind: ::core::clone::Clone::clone(&self.kind),
            ty: ::core::clone::Clone::clone(&self.ty),
            temp_scope_id: ::core::clone::Clone::clone(&self.temp_scope_id),
            span: ::core::clone::Clone::clone(&self.span),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Expr<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "Expr", "kind",
            &self.kind, "ty", &self.ty, "temp_scope_id", &self.temp_scope_id,
            "span", &&self.span)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Expr<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Expr {
                        kind: ref __binding_0,
                        ty: ref __binding_1,
                        temp_scope_id: ref __binding_2,
                        span: ref __binding_3 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
246pub struct Expr<'tcx> {
247    /// kind of expression
248    pub kind: ExprKind<'tcx>,
249
250    /// The type of this expression
251    pub ty: Ty<'tcx>,
252
253    /// The id of the HIR expression whose [temporary scope] should be used for this expression.
254    ///
255    /// [temporary scope]: https://doc.rust-lang.org/reference/destructors.html#temporary-scopes
256    pub temp_scope_id: hir::ItemLocalId,
257
258    /// span of the expression in the source
259    pub span: Span,
260}
261
262#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for ExprKind<'tcx> {
    #[inline]
    fn clone(&self) -> ExprKind<'tcx> {
        match self {
            ExprKind::Scope {
                region_scope: __self_0, hir_id: __self_1, value: __self_2 } =>
                ExprKind::Scope {
                    region_scope: ::core::clone::Clone::clone(__self_0),
                    hir_id: ::core::clone::Clone::clone(__self_1),
                    value: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::Box { value: __self_0 } =>
                ExprKind::Box {
                    value: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::If {
                if_then_scope: __self_0,
                cond: __self_1,
                then: __self_2,
                else_opt: __self_3 } =>
                ExprKind::If {
                    if_then_scope: ::core::clone::Clone::clone(__self_0),
                    cond: ::core::clone::Clone::clone(__self_1),
                    then: ::core::clone::Clone::clone(__self_2),
                    else_opt: ::core::clone::Clone::clone(__self_3),
                },
            ExprKind::Call {
                ty: __self_0,
                fun: __self_1,
                args: __self_2,
                from_hir_call: __self_3,
                fn_span: __self_4 } =>
                ExprKind::Call {
                    ty: ::core::clone::Clone::clone(__self_0),
                    fun: ::core::clone::Clone::clone(__self_1),
                    args: ::core::clone::Clone::clone(__self_2),
                    from_hir_call: ::core::clone::Clone::clone(__self_3),
                    fn_span: ::core::clone::Clone::clone(__self_4),
                },
            ExprKind::ByUse { expr: __self_0, span: __self_1 } =>
                ExprKind::ByUse {
                    expr: ::core::clone::Clone::clone(__self_0),
                    span: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Deref { arg: __self_0 } =>
                ExprKind::Deref {
                    arg: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::Binary { op: __self_0, lhs: __self_1, rhs: __self_2 } =>
                ExprKind::Binary {
                    op: ::core::clone::Clone::clone(__self_0),
                    lhs: ::core::clone::Clone::clone(__self_1),
                    rhs: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::LogicalOp { op: __self_0, lhs: __self_1, rhs: __self_2 }
                =>
                ExprKind::LogicalOp {
                    op: ::core::clone::Clone::clone(__self_0),
                    lhs: ::core::clone::Clone::clone(__self_1),
                    rhs: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::Unary { op: __self_0, arg: __self_1 } =>
                ExprKind::Unary {
                    op: ::core::clone::Clone::clone(__self_0),
                    arg: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Cast { source: __self_0 } =>
                ExprKind::Cast {
                    source: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::Use { source: __self_0 } =>
                ExprKind::Use {
                    source: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::NeverToAny { source: __self_0 } =>
                ExprKind::NeverToAny {
                    source: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::PointerCoercion {
                cast: __self_0, source: __self_1, is_from_as_cast: __self_2 }
                =>
                ExprKind::PointerCoercion {
                    cast: ::core::clone::Clone::clone(__self_0),
                    source: ::core::clone::Clone::clone(__self_1),
                    is_from_as_cast: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::Loop { body: __self_0 } =>
                ExprKind::Loop {
                    body: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::LoopMatch {
                state: __self_0, region_scope: __self_1, match_data: __self_2
                } =>
                ExprKind::LoopMatch {
                    state: ::core::clone::Clone::clone(__self_0),
                    region_scope: ::core::clone::Clone::clone(__self_1),
                    match_data: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::Let { expr: __self_0, pat: __self_1 } =>
                ExprKind::Let {
                    expr: ::core::clone::Clone::clone(__self_0),
                    pat: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Match {
                scrutinee: __self_0, arms: __self_1, match_source: __self_2 }
                =>
                ExprKind::Match {
                    scrutinee: ::core::clone::Clone::clone(__self_0),
                    arms: ::core::clone::Clone::clone(__self_1),
                    match_source: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::Block { block: __self_0 } =>
                ExprKind::Block {
                    block: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::Assign { lhs: __self_0, rhs: __self_1 } =>
                ExprKind::Assign {
                    lhs: ::core::clone::Clone::clone(__self_0),
                    rhs: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::AssignOp { op: __self_0, lhs: __self_1, rhs: __self_2 }
                =>
                ExprKind::AssignOp {
                    op: ::core::clone::Clone::clone(__self_0),
                    lhs: ::core::clone::Clone::clone(__self_1),
                    rhs: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::Field {
                lhs: __self_0, variant_index: __self_1, name: __self_2 } =>
                ExprKind::Field {
                    lhs: ::core::clone::Clone::clone(__self_0),
                    variant_index: ::core::clone::Clone::clone(__self_1),
                    name: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::Index { lhs: __self_0, index: __self_1 } =>
                ExprKind::Index {
                    lhs: ::core::clone::Clone::clone(__self_0),
                    index: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::VarRef { id: __self_0 } =>
                ExprKind::VarRef {
                    id: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::UpvarRef {
                closure_def_id: __self_0, var_hir_id: __self_1 } =>
                ExprKind::UpvarRef {
                    closure_def_id: ::core::clone::Clone::clone(__self_0),
                    var_hir_id: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Borrow { borrow_kind: __self_0, arg: __self_1 } =>
                ExprKind::Borrow {
                    borrow_kind: ::core::clone::Clone::clone(__self_0),
                    arg: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::RawBorrow { mutability: __self_0, arg: __self_1 } =>
                ExprKind::RawBorrow {
                    mutability: ::core::clone::Clone::clone(__self_0),
                    arg: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Break { label: __self_0, value: __self_1 } =>
                ExprKind::Break {
                    label: ::core::clone::Clone::clone(__self_0),
                    value: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Continue { label: __self_0 } =>
                ExprKind::Continue {
                    label: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::ConstContinue { label: __self_0, value: __self_1 } =>
                ExprKind::ConstContinue {
                    label: ::core::clone::Clone::clone(__self_0),
                    value: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Return { value: __self_0 } =>
                ExprKind::Return {
                    value: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::Become { value: __self_0 } =>
                ExprKind::Become {
                    value: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::ConstBlock { did: __self_0, args: __self_1 } =>
                ExprKind::ConstBlock {
                    did: ::core::clone::Clone::clone(__self_0),
                    args: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Repeat { value: __self_0, count: __self_1 } =>
                ExprKind::Repeat {
                    value: ::core::clone::Clone::clone(__self_0),
                    count: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::Array { fields: __self_0 } =>
                ExprKind::Array {
                    fields: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::Tuple { fields: __self_0 } =>
                ExprKind::Tuple {
                    fields: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::Adt(__self_0) =>
                ExprKind::Adt(::core::clone::Clone::clone(__self_0)),
            ExprKind::PlaceTypeAscription {
                source: __self_0, user_ty: __self_1, user_ty_span: __self_2 }
                =>
                ExprKind::PlaceTypeAscription {
                    source: ::core::clone::Clone::clone(__self_0),
                    user_ty: ::core::clone::Clone::clone(__self_1),
                    user_ty_span: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::ValueTypeAscription {
                source: __self_0, user_ty: __self_1, user_ty_span: __self_2 }
                =>
                ExprKind::ValueTypeAscription {
                    source: ::core::clone::Clone::clone(__self_0),
                    user_ty: ::core::clone::Clone::clone(__self_1),
                    user_ty_span: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::PlaceUnwrapUnsafeBinder { source: __self_0 } =>
                ExprKind::PlaceUnwrapUnsafeBinder {
                    source: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::ValueUnwrapUnsafeBinder { source: __self_0 } =>
                ExprKind::ValueUnwrapUnsafeBinder {
                    source: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::WrapUnsafeBinder { source: __self_0 } =>
                ExprKind::WrapUnsafeBinder {
                    source: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::Closure(__self_0) =>
                ExprKind::Closure(::core::clone::Clone::clone(__self_0)),
            ExprKind::Literal { lit: __self_0, neg: __self_1 } =>
                ExprKind::Literal {
                    lit: ::core::clone::Clone::clone(__self_0),
                    neg: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::NonHirLiteral { lit: __self_0, user_ty: __self_1 } =>
                ExprKind::NonHirLiteral {
                    lit: ::core::clone::Clone::clone(__self_0),
                    user_ty: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::ZstLiteral { user_ty: __self_0 } =>
                ExprKind::ZstLiteral {
                    user_ty: ::core::clone::Clone::clone(__self_0),
                },
            ExprKind::NamedConst {
                def_id: __self_0, args: __self_1, user_ty: __self_2 } =>
                ExprKind::NamedConst {
                    def_id: ::core::clone::Clone::clone(__self_0),
                    args: ::core::clone::Clone::clone(__self_1),
                    user_ty: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::ConstParam { param: __self_0, def_id: __self_1 } =>
                ExprKind::ConstParam {
                    param: ::core::clone::Clone::clone(__self_0),
                    def_id: ::core::clone::Clone::clone(__self_1),
                },
            ExprKind::StaticRef {
                alloc_id: __self_0, ty: __self_1, def_id: __self_2 } =>
                ExprKind::StaticRef {
                    alloc_id: ::core::clone::Clone::clone(__self_0),
                    ty: ::core::clone::Clone::clone(__self_1),
                    def_id: ::core::clone::Clone::clone(__self_2),
                },
            ExprKind::InlineAsm(__self_0) =>
                ExprKind::InlineAsm(::core::clone::Clone::clone(__self_0)),
            ExprKind::ThreadLocalRef(__self_0) =>
                ExprKind::ThreadLocalRef(::core::clone::Clone::clone(__self_0)),
            ExprKind::Yield { value: __self_0 } =>
                ExprKind::Yield {
                    value: ::core::clone::Clone::clone(__self_0),
                },
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ExprKind<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ExprKind::Scope {
                region_scope: __self_0, hir_id: __self_1, value: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Scope",
                    "region_scope", __self_0, "hir_id", __self_1, "value",
                    &__self_2),
            ExprKind::Box { value: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Box",
                    "value", &__self_0),
            ExprKind::If {
                if_then_scope: __self_0,
                cond: __self_1,
                then: __self_2,
                else_opt: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f, "If",
                    "if_then_scope", __self_0, "cond", __self_1, "then",
                    __self_2, "else_opt", &__self_3),
            ExprKind::Call {
                ty: __self_0,
                fun: __self_1,
                args: __self_2,
                from_hir_call: __self_3,
                fn_span: __self_4 } =>
                ::core::fmt::Formatter::debug_struct_field5_finish(f, "Call",
                    "ty", __self_0, "fun", __self_1, "args", __self_2,
                    "from_hir_call", __self_3, "fn_span", &__self_4),
            ExprKind::ByUse { expr: __self_0, span: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "ByUse",
                    "expr", __self_0, "span", &__self_1),
            ExprKind::Deref { arg: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Deref",
                    "arg", &__self_0),
            ExprKind::Binary { op: __self_0, lhs: __self_1, rhs: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Binary", "op", __self_0, "lhs", __self_1, "rhs",
                    &__self_2),
            ExprKind::LogicalOp { op: __self_0, lhs: __self_1, rhs: __self_2 }
                =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "LogicalOp", "op", __self_0, "lhs", __self_1, "rhs",
                    &__self_2),
            ExprKind::Unary { op: __self_0, arg: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Unary",
                    "op", __self_0, "arg", &__self_1),
            ExprKind::Cast { source: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Cast",
                    "source", &__self_0),
            ExprKind::Use { source: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Use",
                    "source", &__self_0),
            ExprKind::NeverToAny { source: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "NeverToAny", "source", &__self_0),
            ExprKind::PointerCoercion {
                cast: __self_0, source: __self_1, is_from_as_cast: __self_2 }
                =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "PointerCoercion", "cast", __self_0, "source", __self_1,
                    "is_from_as_cast", &__self_2),
            ExprKind::Loop { body: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Loop",
                    "body", &__self_0),
            ExprKind::LoopMatch {
                state: __self_0, region_scope: __self_1, match_data: __self_2
                } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "LoopMatch", "state", __self_0, "region_scope", __self_1,
                    "match_data", &__self_2),
            ExprKind::Let { expr: __self_0, pat: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Let",
                    "expr", __self_0, "pat", &__self_1),
            ExprKind::Match {
                scrutinee: __self_0, arms: __self_1, match_source: __self_2 }
                =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Match",
                    "scrutinee", __self_0, "arms", __self_1, "match_source",
                    &__self_2),
            ExprKind::Block { block: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Block",
                    "block", &__self_0),
            ExprKind::Assign { lhs: __self_0, rhs: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Assign", "lhs", __self_0, "rhs", &__self_1),
            ExprKind::AssignOp { op: __self_0, lhs: __self_1, rhs: __self_2 }
                =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "AssignOp", "op", __self_0, "lhs", __self_1, "rhs",
                    &__self_2),
            ExprKind::Field {
                lhs: __self_0, variant_index: __self_1, name: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Field",
                    "lhs", __self_0, "variant_index", __self_1, "name",
                    &__self_2),
            ExprKind::Index { lhs: __self_0, index: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Index",
                    "lhs", __self_0, "index", &__self_1),
            ExprKind::VarRef { id: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "VarRef", "id", &__self_0),
            ExprKind::UpvarRef {
                closure_def_id: __self_0, var_hir_id: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "UpvarRef", "closure_def_id", __self_0, "var_hir_id",
                    &__self_1),
            ExprKind::Borrow { borrow_kind: __self_0, arg: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Borrow", "borrow_kind", __self_0, "arg", &__self_1),
            ExprKind::RawBorrow { mutability: __self_0, arg: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "RawBorrow", "mutability", __self_0, "arg", &__self_1),
            ExprKind::Break { label: __self_0, value: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Break",
                    "label", __self_0, "value", &__self_1),
            ExprKind::Continue { label: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Continue", "label", &__self_0),
            ExprKind::ConstContinue { label: __self_0, value: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "ConstContinue", "label", __self_0, "value", &__self_1),
            ExprKind::Return { value: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Return", "value", &__self_0),
            ExprKind::Become { value: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Become", "value", &__self_0),
            ExprKind::ConstBlock { did: __self_0, args: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "ConstBlock", "did", __self_0, "args", &__self_1),
            ExprKind::Repeat { value: __self_0, count: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Repeat", "value", __self_0, "count", &__self_1),
            ExprKind::Array { fields: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Array",
                    "fields", &__self_0),
            ExprKind::Tuple { fields: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Tuple",
                    "fields", &__self_0),
            ExprKind::Adt(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Adt",
                    &__self_0),
            ExprKind::PlaceTypeAscription {
                source: __self_0, user_ty: __self_1, user_ty_span: __self_2 }
                =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "PlaceTypeAscription", "source", __self_0, "user_ty",
                    __self_1, "user_ty_span", &__self_2),
            ExprKind::ValueTypeAscription {
                source: __self_0, user_ty: __self_1, user_ty_span: __self_2 }
                =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "ValueTypeAscription", "source", __self_0, "user_ty",
                    __self_1, "user_ty_span", &__self_2),
            ExprKind::PlaceUnwrapUnsafeBinder { source: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "PlaceUnwrapUnsafeBinder", "source", &__self_0),
            ExprKind::ValueUnwrapUnsafeBinder { source: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "ValueUnwrapUnsafeBinder", "source", &__self_0),
            ExprKind::WrapUnsafeBinder { source: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "WrapUnsafeBinder", "source", &__self_0),
            ExprKind::Closure(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Closure", &__self_0),
            ExprKind::Literal { lit: __self_0, neg: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Literal", "lit", __self_0, "neg", &__self_1),
            ExprKind::NonHirLiteral { lit: __self_0, user_ty: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "NonHirLiteral", "lit", __self_0, "user_ty", &__self_1),
            ExprKind::ZstLiteral { user_ty: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "ZstLiteral", "user_ty", &__self_0),
            ExprKind::NamedConst {
                def_id: __self_0, args: __self_1, user_ty: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "NamedConst", "def_id", __self_0, "args", __self_1,
                    "user_ty", &__self_2),
            ExprKind::ConstParam { param: __self_0, def_id: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "ConstParam", "param", __self_0, "def_id", &__self_1),
            ExprKind::StaticRef {
                alloc_id: __self_0, ty: __self_1, def_id: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "StaticRef", "alloc_id", __self_0, "ty", __self_1, "def_id",
                    &__self_2),
            ExprKind::InlineAsm(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "InlineAsm", &__self_0),
            ExprKind::ThreadLocalRef(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ThreadLocalRef", &__self_0),
            ExprKind::Yield { value: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Yield",
                    "value", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for ExprKind<'tcx> {
            #[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 {
                    ExprKind::Scope {
                        region_scope: ref __binding_0,
                        hir_id: ref __binding_1,
                        value: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Box { value: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::If {
                        if_then_scope: ref __binding_0,
                        cond: ref __binding_1,
                        then: ref __binding_2,
                        else_opt: ref __binding_3 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Call {
                        ty: ref __binding_0,
                        fun: ref __binding_1,
                        args: ref __binding_2,
                        from_hir_call: ref __binding_3,
                        fn_span: ref __binding_4 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ByUse {
                        expr: ref __binding_0, span: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Deref { arg: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Binary {
                        op: ref __binding_0,
                        lhs: ref __binding_1,
                        rhs: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::LogicalOp {
                        op: ref __binding_0,
                        lhs: ref __binding_1,
                        rhs: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Unary { op: ref __binding_0, arg: ref __binding_1
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Cast { source: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Use { source: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::NeverToAny { source: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::PointerCoercion {
                        cast: ref __binding_0,
                        source: ref __binding_1,
                        is_from_as_cast: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Loop { body: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::LoopMatch {
                        state: ref __binding_0,
                        region_scope: ref __binding_1,
                        match_data: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Let { expr: ref __binding_0, pat: ref __binding_1
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Match {
                        scrutinee: ref __binding_0,
                        arms: ref __binding_1,
                        match_source: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Block { block: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Assign {
                        lhs: ref __binding_0, rhs: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::AssignOp {
                        op: ref __binding_0,
                        lhs: ref __binding_1,
                        rhs: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Field {
                        lhs: ref __binding_0,
                        variant_index: ref __binding_1,
                        name: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Index {
                        lhs: ref __binding_0, index: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::VarRef { id: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::UpvarRef {
                        closure_def_id: ref __binding_0, var_hir_id: ref __binding_1
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Borrow {
                        borrow_kind: ref __binding_0, arg: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::RawBorrow {
                        mutability: ref __binding_0, arg: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Break {
                        label: ref __binding_0, value: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Continue { label: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ConstContinue {
                        label: ref __binding_0, value: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Return { value: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Become { value: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ConstBlock {
                        did: ref __binding_0, args: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Repeat {
                        value: ref __binding_0, count: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Array { fields: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Tuple { fields: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Adt(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::PlaceTypeAscription {
                        source: ref __binding_0,
                        user_ty: ref __binding_1,
                        user_ty_span: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ValueTypeAscription {
                        source: ref __binding_0,
                        user_ty: ref __binding_1,
                        user_ty_span: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::PlaceUnwrapUnsafeBinder { source: ref __binding_0
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ValueUnwrapUnsafeBinder { source: ref __binding_0
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::WrapUnsafeBinder { source: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Closure(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Literal {
                        lit: ref __binding_0, neg: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::NonHirLiteral {
                        lit: ref __binding_0, user_ty: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ZstLiteral { user_ty: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::NamedConst {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        user_ty: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ConstParam {
                        param: ref __binding_0, def_id: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::StaticRef {
                        alloc_id: ref __binding_0,
                        ty: ref __binding_1,
                        def_id: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::InlineAsm(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::ThreadLocalRef(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExprKind::Yield { value: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
263pub enum ExprKind<'tcx> {
264    /// `Scope`s are used to explicitly mark destruction scopes,
265    /// and to track the `HirId` of the expressions within the scope.
266    Scope {
267        region_scope: region::Scope,
268        hir_id: HirId,
269        value: ExprId,
270    },
271    /// A `box <value>` expression.
272    Box {
273        value: ExprId,
274    },
275    /// An `if` expression.
276    If {
277        if_then_scope: region::Scope,
278        cond: ExprId,
279        /// `then` is always `ExprKind::Block`.
280        then: ExprId,
281        /// If present, the `else_opt` expr is always `ExprKind::Block` (for
282        /// `else`) or `ExprKind::If` (for `else if`).
283        else_opt: Option<ExprId>,
284    },
285    /// A function call. Method calls and overloaded operators are converted to plain function calls.
286    Call {
287        /// The type of the function. This is often a [`FnDef`] or a [`FnPtr`].
288        ///
289        /// [`FnDef`]: ty::TyKind::FnDef
290        /// [`FnPtr`]: ty::TyKind::FnPtr
291        ty: Ty<'tcx>,
292        /// The function itself.
293        fun: ExprId,
294        /// The arguments passed to the function.
295        ///
296        /// Note: in some cases (like calling a closure), the function call `f(...args)` gets
297        /// rewritten as a call to a function trait method (e.g. `FnOnce::call_once(f, (...args))`).
298        args: Box<[ExprId]>,
299        /// Whether this is from an overloaded operator rather than a
300        /// function call from HIR. `true` for overloaded function call.
301        from_hir_call: bool,
302        /// The span of the function, without the dot and receiver
303        /// (e.g. `foo(a, b)` in `x.foo(a, b)`).
304        fn_span: Span,
305    },
306    /// A use expression `x.use`.
307    ByUse {
308        /// The expression on which use is applied.
309        expr: ExprId,
310        /// The span of use, without the dot and receiver
311        /// (e.g. `use` in `x.use`).
312        span: Span,
313    },
314    /// A *non-overloaded* dereference.
315    Deref {
316        arg: ExprId,
317    },
318    /// A *non-overloaded* binary operation.
319    Binary {
320        op: BinOp,
321        lhs: ExprId,
322        rhs: ExprId,
323    },
324    /// A logical operation. This is distinct from `BinaryOp` because
325    /// the operands need to be lazily evaluated.
326    LogicalOp {
327        op: LogicalOp,
328        lhs: ExprId,
329        rhs: ExprId,
330    },
331    /// A *non-overloaded* unary operation. Note that here the deref (`*`)
332    /// operator is represented by `ExprKind::Deref`.
333    Unary {
334        op: UnOp,
335        arg: ExprId,
336    },
337    /// A cast: `<source> as <type>`. The type we cast to is the type of
338    /// the parent expression.
339    Cast {
340        source: ExprId,
341    },
342    /// Forces its contents to be treated as a value expression, not a place
343    /// expression. This is inserted in some places where an operation would
344    /// otherwise be erased completely (e.g. some no-op casts), but we still
345    /// need to ensure that its operand is treated as a value and not a place.
346    Use {
347        source: ExprId,
348    },
349    /// A coercion from `!` to any type.
350    NeverToAny {
351        source: ExprId,
352    },
353    /// A pointer coercion. More information can be found in [`PointerCoercion`].
354    /// Pointer casts that cannot be done by coercions are represented by [`ExprKind::Cast`].
355    PointerCoercion {
356        cast: PointerCoercion,
357        source: ExprId,
358        /// Whether this coercion is written with an `as` cast in the source code.
359        is_from_as_cast: bool,
360    },
361    /// A `loop` expression.
362    Loop {
363        body: ExprId,
364    },
365    /// A `#[loop_match] loop { state = 'blk: { match state { ... } } }` expression.
366    LoopMatch {
367        /// The state variable that is updated.
368        /// The `match_data.scrutinee` is the same variable, but with a different span.
369        state: ExprId,
370        region_scope: region::Scope,
371        match_data: Box<LoopMatchMatchData>,
372    },
373    /// Special expression representing the `let` part of an `if let` or similar construct
374    /// (including `if let` guards in match arms, and let-chains formed by `&&`).
375    ///
376    /// This isn't considered a real expression in surface Rust syntax, so it can
377    /// only appear in specific situations, such as within the condition of an `if`.
378    ///
379    /// (Not to be confused with [`StmtKind::Let`], which is a normal `let` statement.)
380    Let {
381        expr: ExprId,
382        pat: Box<Pat<'tcx>>,
383    },
384    /// A `match` expression.
385    Match {
386        scrutinee: ExprId,
387        arms: Box<[ArmId]>,
388        match_source: MatchSource,
389    },
390    /// A block.
391    Block {
392        block: BlockId,
393    },
394    /// An assignment: `lhs = rhs`.
395    Assign {
396        lhs: ExprId,
397        rhs: ExprId,
398    },
399    /// A *non-overloaded* operation assignment, e.g. `lhs += rhs`.
400    AssignOp {
401        op: AssignOp,
402        lhs: ExprId,
403        rhs: ExprId,
404    },
405    /// Access to a field of a struct, a tuple, an union, or an enum.
406    Field {
407        lhs: ExprId,
408        /// Variant containing the field.
409        variant_index: VariantIdx,
410        /// This can be a named (`.foo`) or unnamed (`.0`) field.
411        name: FieldIdx,
412    },
413    /// A *non-overloaded* indexing operation.
414    Index {
415        lhs: ExprId,
416        index: ExprId,
417    },
418    /// A local variable.
419    VarRef {
420        id: LocalVarId,
421    },
422    /// Used to represent upvars mentioned in a closure/coroutine
423    UpvarRef {
424        /// DefId of the closure/coroutine
425        closure_def_id: DefId,
426
427        /// HirId of the root variable
428        var_hir_id: LocalVarId,
429    },
430    /// A borrow, e.g. `&arg`.
431    Borrow {
432        borrow_kind: BorrowKind,
433        arg: ExprId,
434    },
435    /// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
436    RawBorrow {
437        mutability: hir::Mutability,
438        arg: ExprId,
439    },
440    /// A `break` expression.
441    Break {
442        label: region::Scope,
443        value: Option<ExprId>,
444    },
445    /// A `continue` expression.
446    Continue {
447        label: region::Scope,
448    },
449    /// A `#[const_continue] break` expression.
450    ConstContinue {
451        label: region::Scope,
452        value: ExprId,
453    },
454    /// A `return` expression.
455    Return {
456        value: Option<ExprId>,
457    },
458    /// A `become` expression.
459    Become {
460        value: ExprId,
461    },
462    /// An inline `const` block, e.g. `const {}`.
463    ConstBlock {
464        did: DefId,
465        args: GenericArgsRef<'tcx>,
466    },
467    /// An array literal constructed from one repeated element, e.g. `[1; 5]`.
468    Repeat {
469        value: ExprId,
470        count: ty::Const<'tcx>,
471    },
472    /// An array, e.g. `[a, b, c, d]`.
473    Array {
474        fields: Box<[ExprId]>,
475    },
476    /// A tuple, e.g. `(a, b, c, d)`.
477    Tuple {
478        fields: Box<[ExprId]>,
479    },
480    /// An ADT constructor, e.g. `Foo {x: 1, y: 2}`.
481    Adt(Box<AdtExpr<'tcx>>),
482    /// A type ascription on a place.
483    PlaceTypeAscription {
484        source: ExprId,
485        /// Type that the user gave to this expression
486        user_ty: UserTy<'tcx>,
487        user_ty_span: Span,
488    },
489    /// A type ascription on a value, e.g. `type_ascribe!(42, i32)` or `42 as i32`.
490    ValueTypeAscription {
491        source: ExprId,
492        /// Type that the user gave to this expression
493        user_ty: UserTy<'tcx>,
494        user_ty_span: Span,
495    },
496    /// An unsafe binder cast on a place, e.g. `unwrap_binder!(*ptr)`.
497    PlaceUnwrapUnsafeBinder {
498        source: ExprId,
499    },
500    /// An unsafe binder cast on a value, e.g. `unwrap_binder!(rvalue())`,
501    /// which makes a temporary.
502    ValueUnwrapUnsafeBinder {
503        source: ExprId,
504    },
505    /// Construct an unsafe binder, e.g. `wrap_binder(&ref)`.
506    WrapUnsafeBinder {
507        source: ExprId,
508    },
509    /// A closure definition.
510    Closure(Box<ClosureExpr<'tcx>>),
511    /// A literal.
512    Literal {
513        lit: hir::Lit,
514        neg: bool,
515    },
516    /// For literals that don't correspond to anything in the HIR
517    NonHirLiteral {
518        lit: ty::ScalarInt,
519        user_ty: UserTy<'tcx>,
520    },
521    /// A literal of a ZST type.
522    ZstLiteral {
523        user_ty: UserTy<'tcx>,
524    },
525    /// Associated constants and named constants
526    NamedConst {
527        def_id: DefId,
528        args: GenericArgsRef<'tcx>,
529        user_ty: UserTy<'tcx>,
530    },
531    ConstParam {
532        param: ty::ParamConst,
533        def_id: DefId,
534    },
535    // FIXME improve docs for `StaticRef` by distinguishing it from `NamedConst`
536    /// A literal containing the address of a `static`.
537    ///
538    /// This is only distinguished from `Literal` so that we can register some
539    /// info for diagnostics.
540    StaticRef {
541        alloc_id: AllocId,
542        ty: Ty<'tcx>,
543        def_id: DefId,
544    },
545    /// Inline assembly, i.e. `asm!()`.
546    InlineAsm(Box<InlineAsmExpr<'tcx>>),
547    /// An expression taking a reference to a thread local.
548    ThreadLocalRef(DefId),
549    /// A `yield` expression.
550    Yield {
551        value: ExprId,
552    },
553}
554
555/// Represents the association of a field identifier and an expression.
556///
557/// This is used in struct constructors.
558#[derive(#[automatically_derived]
impl ::core::clone::Clone for FieldExpr {
    #[inline]
    fn clone(&self) -> FieldExpr {
        FieldExpr {
            name: ::core::clone::Clone::clone(&self.name),
            expr: ::core::clone::Clone::clone(&self.expr),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for FieldExpr {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "FieldExpr",
            "name", &self.name, "expr", &&self.expr)
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for FieldExpr {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FieldExpr { name: ref __binding_0, expr: ref __binding_1 }
                        => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
559pub struct FieldExpr {
560    pub name: FieldIdx,
561    pub expr: ExprId,
562}
563
564#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for FruInfo<'tcx> {
    #[inline]
    fn clone(&self) -> FruInfo<'tcx> {
        FruInfo {
            base: ::core::clone::Clone::clone(&self.base),
            field_types: ::core::clone::Clone::clone(&self.field_types),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for FruInfo<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "FruInfo",
            "base", &self.base, "field_types", &&self.field_types)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for FruInfo<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FruInfo {
                        base: ref __binding_0, field_types: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
565pub struct FruInfo<'tcx> {
566    pub base: ExprId,
567    pub field_types: Box<[Ty<'tcx>]>,
568}
569
570/// A `match` arm.
571#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Arm<'tcx> {
    #[inline]
    fn clone(&self) -> Arm<'tcx> {
        Arm {
            pattern: ::core::clone::Clone::clone(&self.pattern),
            guard: ::core::clone::Clone::clone(&self.guard),
            body: ::core::clone::Clone::clone(&self.body),
            hir_id: ::core::clone::Clone::clone(&self.hir_id),
            scope: ::core::clone::Clone::clone(&self.scope),
            span: ::core::clone::Clone::clone(&self.span),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Arm<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["pattern", "guard", "body", "hir_id", "scope", "span"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.pattern, &self.guard, &self.body, &self.hir_id,
                        &self.scope, &&self.span];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Arm", names,
            values)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Arm<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Arm {
                        pattern: ref __binding_0,
                        guard: ref __binding_1,
                        body: ref __binding_2,
                        hir_id: ref __binding_3,
                        scope: ref __binding_4,
                        span: ref __binding_5 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                        { __binding_5.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
572pub struct Arm<'tcx> {
573    pub pattern: Box<Pat<'tcx>>,
574    pub guard: Option<ExprId>,
575    pub body: ExprId,
576    pub hir_id: HirId,
577    pub scope: region::Scope,
578    pub span: Span,
579}
580
581/// The `match` part of a `#[loop_match]`
582#[derive(#[automatically_derived]
impl ::core::clone::Clone for LoopMatchMatchData {
    #[inline]
    fn clone(&self) -> LoopMatchMatchData {
        LoopMatchMatchData {
            scrutinee: ::core::clone::Clone::clone(&self.scrutinee),
            arms: ::core::clone::Clone::clone(&self.arms),
            span: ::core::clone::Clone::clone(&self.span),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for LoopMatchMatchData {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "LoopMatchMatchData", "scrutinee", &self.scrutinee, "arms",
            &self.arms, "span", &&self.span)
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for LoopMatchMatchData {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    LoopMatchMatchData {
                        scrutinee: ref __binding_0,
                        arms: ref __binding_1,
                        span: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
583pub struct LoopMatchMatchData {
584    pub scrutinee: ExprId,
585    pub arms: Box<[ArmId]>,
586    pub span: Span,
587}
588
589#[derive(#[automatically_derived]
impl ::core::marker::Copy for LogicalOp { }Copy, #[automatically_derived]
impl ::core::clone::Clone for LogicalOp {
    #[inline]
    fn clone(&self) -> LogicalOp { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for LogicalOp {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self { LogicalOp::And => "And", LogicalOp::Or => "Or", })
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for LogicalOp {
            #[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 { LogicalOp::And => {} LogicalOp::Or => {} }
            }
        }
    };HashStable)]
590pub enum LogicalOp {
591    /// The `&&` operator.
592    And,
593    /// The `||` operator.
594    Or,
595}
596
597#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for InlineAsmOperand<'tcx> {
    #[inline]
    fn clone(&self) -> InlineAsmOperand<'tcx> {
        match self {
            InlineAsmOperand::In { reg: __self_0, expr: __self_1 } =>
                InlineAsmOperand::In {
                    reg: ::core::clone::Clone::clone(__self_0),
                    expr: ::core::clone::Clone::clone(__self_1),
                },
            InlineAsmOperand::Out {
                reg: __self_0, late: __self_1, expr: __self_2 } =>
                InlineAsmOperand::Out {
                    reg: ::core::clone::Clone::clone(__self_0),
                    late: ::core::clone::Clone::clone(__self_1),
                    expr: ::core::clone::Clone::clone(__self_2),
                },
            InlineAsmOperand::InOut {
                reg: __self_0, late: __self_1, expr: __self_2 } =>
                InlineAsmOperand::InOut {
                    reg: ::core::clone::Clone::clone(__self_0),
                    late: ::core::clone::Clone::clone(__self_1),
                    expr: ::core::clone::Clone::clone(__self_2),
                },
            InlineAsmOperand::SplitInOut {
                reg: __self_0,
                late: __self_1,
                in_expr: __self_2,
                out_expr: __self_3 } =>
                InlineAsmOperand::SplitInOut {
                    reg: ::core::clone::Clone::clone(__self_0),
                    late: ::core::clone::Clone::clone(__self_1),
                    in_expr: ::core::clone::Clone::clone(__self_2),
                    out_expr: ::core::clone::Clone::clone(__self_3),
                },
            InlineAsmOperand::Const { value: __self_0, span: __self_1 } =>
                InlineAsmOperand::Const {
                    value: ::core::clone::Clone::clone(__self_0),
                    span: ::core::clone::Clone::clone(__self_1),
                },
            InlineAsmOperand::SymFn { value: __self_0 } =>
                InlineAsmOperand::SymFn {
                    value: ::core::clone::Clone::clone(__self_0),
                },
            InlineAsmOperand::SymStatic { def_id: __self_0 } =>
                InlineAsmOperand::SymStatic {
                    def_id: ::core::clone::Clone::clone(__self_0),
                },
            InlineAsmOperand::Label { block: __self_0 } =>
                InlineAsmOperand::Label {
                    block: ::core::clone::Clone::clone(__self_0),
                },
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InlineAsmOperand<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            InlineAsmOperand::In { reg: __self_0, expr: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "In",
                    "reg", __self_0, "expr", &__self_1),
            InlineAsmOperand::Out {
                reg: __self_0, late: __self_1, expr: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Out",
                    "reg", __self_0, "late", __self_1, "expr", &__self_2),
            InlineAsmOperand::InOut {
                reg: __self_0, late: __self_1, expr: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "InOut",
                    "reg", __self_0, "late", __self_1, "expr", &__self_2),
            InlineAsmOperand::SplitInOut {
                reg: __self_0,
                late: __self_1,
                in_expr: __self_2,
                out_expr: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "SplitInOut", "reg", __self_0, "late", __self_1, "in_expr",
                    __self_2, "out_expr", &__self_3),
            InlineAsmOperand::Const { value: __self_0, span: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Const",
                    "value", __self_0, "span", &__self_1),
            InlineAsmOperand::SymFn { value: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "SymFn",
                    "value", &__self_0),
            InlineAsmOperand::SymStatic { def_id: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "SymStatic", "def_id", &__self_0),
            InlineAsmOperand::Label { block: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Label",
                    "block", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for InlineAsmOperand<'tcx> {
            #[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 {
                    InlineAsmOperand::In {
                        reg: ref __binding_0, expr: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    InlineAsmOperand::Out {
                        reg: ref __binding_0,
                        late: ref __binding_1,
                        expr: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    InlineAsmOperand::InOut {
                        reg: ref __binding_0,
                        late: ref __binding_1,
                        expr: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    InlineAsmOperand::SplitInOut {
                        reg: ref __binding_0,
                        late: ref __binding_1,
                        in_expr: ref __binding_2,
                        out_expr: ref __binding_3 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                    }
                    InlineAsmOperand::Const {
                        value: ref __binding_0, span: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    InlineAsmOperand::SymFn { value: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    InlineAsmOperand::SymStatic { def_id: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    InlineAsmOperand::Label { block: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
598pub enum InlineAsmOperand<'tcx> {
599    In {
600        reg: InlineAsmRegOrRegClass,
601        expr: ExprId,
602    },
603    Out {
604        reg: InlineAsmRegOrRegClass,
605        late: bool,
606        expr: Option<ExprId>,
607    },
608    InOut {
609        reg: InlineAsmRegOrRegClass,
610        late: bool,
611        expr: ExprId,
612    },
613    SplitInOut {
614        reg: InlineAsmRegOrRegClass,
615        late: bool,
616        in_expr: ExprId,
617        out_expr: Option<ExprId>,
618    },
619    Const {
620        value: mir::Const<'tcx>,
621        span: Span,
622    },
623    SymFn {
624        value: ExprId,
625    },
626    SymStatic {
627        def_id: DefId,
628    },
629    Label {
630        block: BlockId,
631    },
632}
633
634#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for FieldPat<'tcx> {
    #[inline]
    fn clone(&self) -> FieldPat<'tcx> {
        FieldPat {
            field: ::core::clone::Clone::clone(&self.field),
            pattern: ::core::clone::Clone::clone(&self.pattern),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for FieldPat<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "FieldPat",
            "field", &self.field, "pattern", &&self.pattern)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for FieldPat<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FieldPat { field: ref __binding_0, pattern: ref __binding_1
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for FieldPat<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    FieldPat { field: ref __binding_0, pattern: 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)]
635pub struct FieldPat<'tcx> {
636    pub field: FieldIdx,
637    pub pattern: Pat<'tcx>,
638}
639
640/// Additional per-node data that is not present on most THIR pattern nodes.
641#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for PatExtra<'tcx> {
    #[inline]
    fn clone(&self) -> PatExtra<'tcx> {
        PatExtra {
            expanded_const: ::core::clone::Clone::clone(&self.expanded_const),
            ascriptions: ::core::clone::Clone::clone(&self.ascriptions),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PatExtra<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "PatExtra",
            "expanded_const", &self.expanded_const, "ascriptions",
            &&self.ascriptions)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::default::Default for PatExtra<'tcx> {
    #[inline]
    fn default() -> PatExtra<'tcx> {
        PatExtra {
            expanded_const: ::core::default::Default::default(),
            ascriptions: ::core::default::Default::default(),
        }
    }
}Default, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PatExtra<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    PatExtra {
                        expanded_const: ref __binding_0,
                        ascriptions: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatExtra<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    PatExtra {
                        expanded_const: ref __binding_0,
                        ascriptions: 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)]
642pub struct PatExtra<'tcx> {
643    /// If present, this node represents a named constant that was lowered to
644    /// a pattern using `const_to_pat`.
645    ///
646    /// This is used by some diagnostics for non-exhaustive matches, to map
647    /// the pattern node back to the `DefId` of its original constant.
648    pub expanded_const: Option<DefId>,
649
650    /// User-written types that must be preserved into MIR so that they can be
651    /// checked.
652    pub ascriptions: Vec<Ascription<'tcx>>,
653}
654
655#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Pat<'tcx> {
    #[inline]
    fn clone(&self) -> Pat<'tcx> {
        Pat {
            ty: ::core::clone::Clone::clone(&self.ty),
            span: ::core::clone::Clone::clone(&self.span),
            extra: ::core::clone::Clone::clone(&self.extra),
            kind: ::core::clone::Clone::clone(&self.kind),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Pat<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "Pat", "ty",
            &self.ty, "span", &self.span, "extra", &self.extra, "kind",
            &&self.kind)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Pat<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Pat {
                        ty: ref __binding_0,
                        span: ref __binding_1,
                        extra: ref __binding_2,
                        kind: ref __binding_3 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Pat<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Pat {
                        ty: ref __binding_0,
                        span: ref __binding_1,
                        extra: ref __binding_2,
                        kind: ref __binding_3 } => {
                        {
                            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);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_3,
                                        __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)]
656pub struct Pat<'tcx> {
657    pub ty: Ty<'tcx>,
658    pub span: Span,
659    pub extra: Option<Box<PatExtra<'tcx>>>,
660    pub kind: PatKind<'tcx>,
661}
662
663impl<'tcx> Pat<'tcx> {
664    pub fn simple_ident(&self) -> Option<Symbol> {
665        match self.kind {
666            PatKind::Binding {
667                name, mode: BindingMode(ByRef::No, _), subpattern: None, ..
668            } => Some(name),
669            _ => None,
670        }
671    }
672
673    /// Call `f` on every "binding" in a pattern, e.g., on `a` in
674    /// `match foo() { Some(a) => (), None => () }`
675    pub fn each_binding(&self, mut f: impl FnMut(Symbol, ByRef, Ty<'tcx>, Span)) {
676        self.walk_always(|p| {
677            if let PatKind::Binding { name, mode, ty, .. } = p.kind {
678                f(name, mode.0, ty, p.span);
679            }
680        });
681    }
682
683    /// Walk the pattern in left-to-right order.
684    ///
685    /// If `it(pat)` returns `false`, the children are not visited.
686    pub fn walk(&self, mut it: impl FnMut(&Pat<'tcx>) -> bool) {
687        self.walk_(&mut it)
688    }
689
690    fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
691        if !it(self) {
692            return;
693        }
694
695        for_each_immediate_subpat(self, |p| p.walk_(it));
696    }
697
698    /// Whether the pattern has a `PatKind::Error` nested within.
699    pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> {
700        let mut error = None;
701        self.walk(|pat| {
702            if let PatKind::Error(e) = pat.kind
703                && error.is_none()
704            {
705                error = Some(e);
706            }
707            error.is_none()
708        });
709        match error {
710            None => Ok(()),
711            Some(e) => Err(e),
712        }
713    }
714
715    /// Walk the pattern in left-to-right order.
716    ///
717    /// If you always want to recurse, prefer this method over `walk`.
718    pub fn walk_always(&self, mut it: impl FnMut(&Pat<'tcx>)) {
719        self.walk(|p| {
720            it(p);
721            true
722        })
723    }
724
725    /// Whether this a never pattern.
726    pub fn is_never_pattern(&self) -> bool {
727        let mut is_never_pattern = false;
728        self.walk(|pat| match &pat.kind {
729            PatKind::Never => {
730                is_never_pattern = true;
731                false
732            }
733            PatKind::Or { pats } => {
734                is_never_pattern = pats.iter().all(|p| p.is_never_pattern());
735                false
736            }
737            _ => true,
738        });
739        is_never_pattern
740    }
741}
742
743#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Ascription<'tcx> {
    #[inline]
    fn clone(&self) -> Ascription<'tcx> {
        Ascription {
            annotation: ::core::clone::Clone::clone(&self.annotation),
            variance: ::core::clone::Clone::clone(&self.variance),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Ascription<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Ascription",
            "annotation", &self.annotation, "variance", &&self.variance)
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Ascription<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Ascription {
                        annotation: ref __binding_0, variance: ref __binding_1 } =>
                        {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for Ascription<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Ascription {
                        annotation: ref __binding_0, variance: 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)]
744pub struct Ascription<'tcx> {
745    pub annotation: CanonicalUserTypeAnnotation<'tcx>,
746    /// Variance to use when relating the `user_ty` to the **type of the value being
747    /// matched**. Typically, this is `Variance::Covariant`, since the value being matched must
748    /// have a type that is some subtype of the ascribed type.
749    ///
750    /// Note that this variance does not apply for any bindings within subpatterns. The type
751    /// assigned to those bindings must be exactly equal to the `user_ty` given here.
752    ///
753    /// The only place where this field is not `Covariant` is when matching constants, where
754    /// we currently use `Contravariant` -- this is because the constant type just needs to
755    /// be "comparable" to the type of the input value. So, for example:
756    ///
757    /// ```text
758    /// match x { "foo" => .. }
759    /// ```
760    ///
761    /// requires that `&'static str <: T_x`, where `T_x` is the type of `x`. Really, we should
762    /// probably be checking for a `PartialEq` impl instead, but this preserves the behavior
763    /// of the old type-check for now. See #57280 for details.
764    pub variance: ty::Variance,
765}
766
767#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for PatKind<'tcx> {
    #[inline]
    fn clone(&self) -> PatKind<'tcx> {
        match self {
            PatKind::Missing => PatKind::Missing,
            PatKind::Wild => PatKind::Wild,
            PatKind::Binding {
                name: __self_0,
                mode: __self_1,
                var: __self_2,
                ty: __self_3,
                subpattern: __self_4,
                is_primary: __self_5,
                is_shorthand: __self_6 } =>
                PatKind::Binding {
                    name: ::core::clone::Clone::clone(__self_0),
                    mode: ::core::clone::Clone::clone(__self_1),
                    var: ::core::clone::Clone::clone(__self_2),
                    ty: ::core::clone::Clone::clone(__self_3),
                    subpattern: ::core::clone::Clone::clone(__self_4),
                    is_primary: ::core::clone::Clone::clone(__self_5),
                    is_shorthand: ::core::clone::Clone::clone(__self_6),
                },
            PatKind::Variant {
                adt_def: __self_0,
                args: __self_1,
                variant_index: __self_2,
                subpatterns: __self_3 } =>
                PatKind::Variant {
                    adt_def: ::core::clone::Clone::clone(__self_0),
                    args: ::core::clone::Clone::clone(__self_1),
                    variant_index: ::core::clone::Clone::clone(__self_2),
                    subpatterns: ::core::clone::Clone::clone(__self_3),
                },
            PatKind::Leaf { subpatterns: __self_0 } =>
                PatKind::Leaf {
                    subpatterns: ::core::clone::Clone::clone(__self_0),
                },
            PatKind::Deref { pin: __self_0, subpattern: __self_1 } =>
                PatKind::Deref {
                    pin: ::core::clone::Clone::clone(__self_0),
                    subpattern: ::core::clone::Clone::clone(__self_1),
                },
            PatKind::DerefPattern { subpattern: __self_0, borrow: __self_1 }
                =>
                PatKind::DerefPattern {
                    subpattern: ::core::clone::Clone::clone(__self_0),
                    borrow: ::core::clone::Clone::clone(__self_1),
                },
            PatKind::Constant { value: __self_0 } =>
                PatKind::Constant {
                    value: ::core::clone::Clone::clone(__self_0),
                },
            PatKind::Range(__self_0) =>
                PatKind::Range(::core::clone::Clone::clone(__self_0)),
            PatKind::Slice {
                prefix: __self_0, slice: __self_1, suffix: __self_2 } =>
                PatKind::Slice {
                    prefix: ::core::clone::Clone::clone(__self_0),
                    slice: ::core::clone::Clone::clone(__self_1),
                    suffix: ::core::clone::Clone::clone(__self_2),
                },
            PatKind::Array {
                prefix: __self_0, slice: __self_1, suffix: __self_2 } =>
                PatKind::Array {
                    prefix: ::core::clone::Clone::clone(__self_0),
                    slice: ::core::clone::Clone::clone(__self_1),
                    suffix: ::core::clone::Clone::clone(__self_2),
                },
            PatKind::Or { pats: __self_0 } =>
                PatKind::Or { pats: ::core::clone::Clone::clone(__self_0) },
            PatKind::Never => PatKind::Never,
            PatKind::Error(__self_0) =>
                PatKind::Error(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PatKind<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            PatKind::Missing =>
                ::core::fmt::Formatter::write_str(f, "Missing"),
            PatKind::Wild => ::core::fmt::Formatter::write_str(f, "Wild"),
            PatKind::Binding {
                name: __self_0,
                mode: __self_1,
                var: __self_2,
                ty: __self_3,
                subpattern: __self_4,
                is_primary: __self_5,
                is_shorthand: __self_6 } => {
                let names: &'static _ =
                    &["name", "mode", "var", "ty", "subpattern", "is_primary",
                                "is_shorthand"];
                let values: &[&dyn ::core::fmt::Debug] =
                    &[__self_0, __self_1, __self_2, __self_3, __self_4,
                                __self_5, &__self_6];
                ::core::fmt::Formatter::debug_struct_fields_finish(f,
                    "Binding", names, values)
            }
            PatKind::Variant {
                adt_def: __self_0,
                args: __self_1,
                variant_index: __self_2,
                subpatterns: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "Variant", "adt_def", __self_0, "args", __self_1,
                    "variant_index", __self_2, "subpatterns", &__self_3),
            PatKind::Leaf { subpatterns: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Leaf",
                    "subpatterns", &__self_0),
            PatKind::Deref { pin: __self_0, subpattern: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Deref",
                    "pin", __self_0, "subpattern", &__self_1),
            PatKind::DerefPattern { subpattern: __self_0, borrow: __self_1 }
                =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "DerefPattern", "subpattern", __self_0, "borrow",
                    &__self_1),
            PatKind::Constant { value: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Constant", "value", &__self_0),
            PatKind::Range(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Range",
                    &__self_0),
            PatKind::Slice {
                prefix: __self_0, slice: __self_1, suffix: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Slice",
                    "prefix", __self_0, "slice", __self_1, "suffix", &__self_2),
            PatKind::Array {
                prefix: __self_0, slice: __self_1, suffix: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Array",
                    "prefix", __self_0, "slice", __self_1, "suffix", &__self_2),
            PatKind::Or { pats: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Or",
                    "pats", &__self_0),
            PatKind::Never => ::core::fmt::Formatter::write_str(f, "Never"),
            PatKind::Error(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Error",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PatKind<'tcx> {
            #[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 {
                    PatKind::Missing => {}
                    PatKind::Wild => {}
                    PatKind::Binding {
                        name: ref __binding_0,
                        mode: ref __binding_1,
                        var: ref __binding_2,
                        ty: ref __binding_3,
                        subpattern: ref __binding_4,
                        is_primary: ref __binding_5,
                        is_shorthand: ref __binding_6 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                        { __binding_5.hash_stable(__hcx, __hasher); }
                        { __binding_6.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Variant {
                        adt_def: ref __binding_0,
                        args: ref __binding_1,
                        variant_index: ref __binding_2,
                        subpatterns: ref __binding_3 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Leaf { subpatterns: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Deref {
                        pin: ref __binding_0, subpattern: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::DerefPattern {
                        subpattern: ref __binding_0, borrow: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Constant { value: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Range(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Slice {
                        prefix: ref __binding_0,
                        slice: ref __binding_1,
                        suffix: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Array {
                        prefix: ref __binding_0,
                        slice: ref __binding_1,
                        suffix: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Or { pats: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PatKind::Never => {}
                    PatKind::Error(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatKind<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    PatKind::Missing => {}
                    PatKind::Wild => {}
                    PatKind::Binding {
                        name: ref __binding_0,
                        ty: ref __binding_3,
                        subpattern: ref __binding_4,
                        is_primary: ref __binding_5,
                        is_shorthand: ref __binding_6, .. } => {
                        {
                            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_3,
                                        __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_4,
                                        __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_5,
                                        __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_6,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                    PatKind::Variant {
                        adt_def: ref __binding_0,
                        args: ref __binding_1,
                        variant_index: ref __binding_2,
                        subpatterns: ref __binding_3 } => {
                        {
                            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);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_3,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                    PatKind::Leaf { subpatterns: 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);
                                }
                            }
                        }
                    }
                    PatKind::Deref { subpattern: ref __binding_1, .. } => {
                        {
                            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);
                                }
                            }
                        }
                    }
                    PatKind::DerefPattern { subpattern: 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);
                                }
                            }
                        }
                    }
                    PatKind::Constant { value: 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);
                                }
                            }
                        }
                    }
                    PatKind::Range(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);
                                }
                            }
                        }
                    }
                    PatKind::Slice {
                        prefix: ref __binding_0,
                        slice: ref __binding_1,
                        suffix: 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);
                                }
                            }
                        }
                    }
                    PatKind::Array {
                        prefix: ref __binding_0,
                        slice: ref __binding_1,
                        suffix: 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);
                                }
                            }
                        }
                    }
                    PatKind::Or { pats: 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);
                                }
                            }
                        }
                    }
                    PatKind::Never => {}
                    PatKind::Error(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)]
768pub enum PatKind<'tcx> {
769    /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
770    Missing,
771
772    /// A wildcard pattern: `_`.
773    Wild,
774
775    /// `x`, `ref x`, `x @ P`, etc.
776    Binding {
777        name: Symbol,
778        #[type_visitable(ignore)]
779        mode: BindingMode,
780        #[type_visitable(ignore)]
781        var: LocalVarId,
782        ty: Ty<'tcx>,
783        subpattern: Option<Box<Pat<'tcx>>>,
784
785        /// Is this the leftmost occurrence of the binding, i.e., is `var` the
786        /// `HirId` of this pattern?
787        ///
788        /// (The same binding can occur multiple times in different branches of
789        /// an or-pattern, but only one of them will be primary.)
790        is_primary: bool,
791        /// Is this binding a shorthand struct pattern, i.e. `Foo { a }`?
792        is_shorthand: bool,
793    },
794
795    /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
796    /// multiple variants.
797    Variant {
798        adt_def: AdtDef<'tcx>,
799        args: GenericArgsRef<'tcx>,
800        variant_index: VariantIdx,
801        subpatterns: Vec<FieldPat<'tcx>>,
802    },
803
804    /// `(...)`, `Foo(...)`, `Foo{...}`, or `Foo`, where `Foo` is a variant name from an ADT with
805    /// a single variant.
806    Leaf {
807        subpatterns: Vec<FieldPat<'tcx>>,
808    },
809
810    /// Explicit or implicit `&P` or `&mut P`, for some subpattern `P`.
811    ///
812    /// Implicit `&`/`&mut` patterns can be inserted by match-ergonomics.
813    ///
814    /// With `feature(pin_ergonomics)`, this can also be `&pin const P` or
815    /// `&pin mut P`, as indicated by the `pin` field.
816    Deref {
817        #[type_visitable(ignore)]
818        pin: hir::Pinnedness,
819        subpattern: Box<Pat<'tcx>>,
820    },
821
822    /// Explicit or implicit `deref!(..)` pattern, under `feature(deref_patterns)`.
823    /// Represents a call to `Deref` or `DerefMut`, or a deref-move of `Box`.
824    ///
825    /// `box P` patterns also lower to this, under `feature(box_patterns)`.
826    DerefPattern {
827        subpattern: Box<Pat<'tcx>>,
828        /// Whether the pattern scrutinee needs to be borrowed in order to call `Deref::deref` or
829        /// `DerefMut::deref_mut`, and if so, which. This is `DerefPatBorrowMode::Box` for deref patterns on
830        /// boxes; they are lowered using a built-in deref rather than a method call, thus they
831        /// don't borrow the scrutinee.
832        #[type_visitable(ignore)]
833        borrow: DerefPatBorrowMode,
834    },
835
836    /// One of the following:
837    /// * `&str`, which will be handled as a string pattern and thus
838    ///   exhaustiveness checking will detect if you use the same string twice in different
839    ///   patterns.
840    /// * integer, bool, char or float, which will be handled by
841    ///   exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
842    ///   much simpler.
843    /// * raw pointers derived from integers, other raw pointers will have already resulted in an
844    ///   error.
845    Constant {
846        value: ty::Value<'tcx>,
847    },
848
849    Range(Arc<PatRange<'tcx>>),
850
851    /// Matches against a slice, checking the length and extracting elements.
852    /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
853    /// e.g., `&[ref xs @ ..]`.
854    Slice {
855        prefix: Box<[Pat<'tcx>]>,
856        slice: Option<Box<Pat<'tcx>>>,
857        suffix: Box<[Pat<'tcx>]>,
858    },
859
860    /// Fixed match against an array; irrefutable.
861    Array {
862        prefix: Box<[Pat<'tcx>]>,
863        slice: Option<Box<Pat<'tcx>>>,
864        suffix: Box<[Pat<'tcx>]>,
865    },
866
867    /// An or-pattern, e.g. `p | q`.
868    /// Invariant: `pats.len() >= 2`.
869    Or {
870        pats: Box<[Pat<'tcx>]>,
871    },
872
873    /// A never pattern `!`.
874    Never,
875
876    /// An error has been encountered during lowering. We probably shouldn't report more lints
877    /// related to this pattern.
878    Error(ErrorGuaranteed),
879}
880
881#[derive(#[automatically_derived]
impl ::core::marker::Copy for DerefPatBorrowMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for DerefPatBorrowMode {
    #[inline]
    fn clone(&self) -> DerefPatBorrowMode {
        let _: ::core::clone::AssertParamIsClone<Mutability>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DerefPatBorrowMode {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            DerefPatBorrowMode::Borrow(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Borrow",
                    &__self_0),
            DerefPatBorrowMode::Box =>
                ::core::fmt::Formatter::write_str(f, "Box"),
        }
    }
}Debug, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for DerefPatBorrowMode {
            #[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 {
                    DerefPatBorrowMode::Borrow(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    DerefPatBorrowMode::Box => {}
                }
            }
        }
    };HashStable)]
882pub enum DerefPatBorrowMode {
883    Borrow(Mutability),
884    Box,
885}
886
887/// A range pattern.
888/// The boundaries must be of the same type and that type must be numeric.
889#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for PatRange<'tcx> {
    #[inline]
    fn clone(&self) -> PatRange<'tcx> {
        PatRange {
            lo: ::core::clone::Clone::clone(&self.lo),
            hi: ::core::clone::Clone::clone(&self.hi),
            end: ::core::clone::Clone::clone(&self.end),
            ty: ::core::clone::Clone::clone(&self.ty),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PatRange<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "PatRange",
            "lo", &self.lo, "hi", &self.hi, "end", &self.end, "ty", &&self.ty)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for PatRange<'tcx> {
    #[inline]
    fn eq(&self, other: &PatRange<'tcx>) -> bool {
        self.lo == other.lo && self.hi == other.hi && self.end == other.end &&
            self.ty == other.ty
    }
}PartialEq, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PatRange<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    PatRange {
                        lo: ref __binding_0,
                        hi: ref __binding_1,
                        end: ref __binding_2,
                        ty: ref __binding_3 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatRange<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    PatRange {
                        lo: ref __binding_0,
                        hi: ref __binding_1,
                        ty: ref __binding_3, .. } => {
                        {
                            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_3,
                                        __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)]
890pub struct PatRange<'tcx> {
891    /// Must not be `PosInfinity`.
892    pub lo: PatRangeBoundary<'tcx>,
893    /// Must not be `NegInfinity`.
894    pub hi: PatRangeBoundary<'tcx>,
895    #[type_visitable(ignore)]
896    pub end: RangeEnd,
897    pub ty: Ty<'tcx>,
898}
899
900impl<'tcx> PatRange<'tcx> {
901    /// Whether this range covers the full extent of possible values (best-effort, we ignore floats).
902    #[inline]
903    pub fn is_full_range(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
904        let (min, max, size, bias) = match *self.ty.kind() {
905            ty::Char => (0, std::char::MAX as u128, Size::from_bits(32), 0),
906            ty::Int(ity) => {
907                let size = Integer::from_int_ty(&tcx, ity).size();
908                let max = size.truncate(u128::MAX);
909                let bias = 1u128 << (size.bits() - 1);
910                (0, max, size, bias)
911            }
912            ty::Uint(uty) => {
913                let size = Integer::from_uint_ty(&tcx, uty).size();
914                let max = size.unsigned_int_max();
915                (0, max, size, 0)
916            }
917            _ => return None,
918        };
919
920        // We want to compare ranges numerically, but the order of the bitwise representation of
921        // signed integers does not match their numeric order. Thus, to correct the ordering, we
922        // need to shift the range of signed integers to correct the comparison. This is achieved by
923        // XORing with a bias (see pattern/deconstruct_pat.rs for another pertinent example of this
924        // pattern).
925        //
926        // Also, for performance, it's important to only do the second `try_to_bits` if necessary.
927        let lo_is_min = match self.lo {
928            PatRangeBoundary::NegInfinity => true,
929            PatRangeBoundary::Finite(value) => {
930                let lo = value.to_leaf().to_bits(size) ^ bias;
931                lo <= min
932            }
933            PatRangeBoundary::PosInfinity => false,
934        };
935        if lo_is_min {
936            let hi_is_max = match self.hi {
937                PatRangeBoundary::NegInfinity => false,
938                PatRangeBoundary::Finite(value) => {
939                    let hi = value.to_leaf().to_bits(size) ^ bias;
940                    hi > max || hi == max && self.end == RangeEnd::Included
941                }
942                PatRangeBoundary::PosInfinity => true,
943            };
944            if hi_is_max {
945                return Some(true);
946            }
947        }
948        Some(false)
949    }
950
951    #[inline]
952    pub fn contains(&self, value: ty::Value<'tcx>, tcx: TyCtxt<'tcx>) -> Option<bool> {
953        use Ordering::*;
954        if true {
    match (&value.ty, &self.ty) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(value.ty, self.ty);
955        let ty = self.ty;
956        let value = PatRangeBoundary::Finite(value.valtree);
957        // For performance, it's important to only do the second comparison if necessary.
958        Some(
959            match self.lo.compare_with(value, ty, tcx)? {
960                Less | Equal => true,
961                Greater => false,
962            } && match value.compare_with(self.hi, ty, tcx)? {
963                Less => true,
964                Equal => self.end == RangeEnd::Included,
965                Greater => false,
966            },
967        )
968    }
969
970    #[inline]
971    pub fn overlaps(&self, other: &Self, tcx: TyCtxt<'tcx>) -> Option<bool> {
972        use Ordering::*;
973        if true {
    match (&self.ty, &other.ty) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(self.ty, other.ty);
974        // For performance, it's important to only do the second comparison if necessary.
975        Some(
976            match other.lo.compare_with(self.hi, self.ty, tcx)? {
977                Less => true,
978                Equal => self.end == RangeEnd::Included,
979                Greater => false,
980            } && match self.lo.compare_with(other.hi, self.ty, tcx)? {
981                Less => true,
982                Equal => other.end == RangeEnd::Included,
983                Greater => false,
984            },
985        )
986    }
987}
988
989impl<'tcx> fmt::Display for PatRange<'tcx> {
990    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
991        if let &PatRangeBoundary::Finite(valtree) = &self.lo {
992            let value = ty::Value { ty: self.ty, valtree };
993            f.write_fmt(format_args!("{0}", value))write!(f, "{value}")?;
994        }
995        if let &PatRangeBoundary::Finite(valtree) = &self.hi {
996            f.write_fmt(format_args!("{0}", self.end))write!(f, "{}", self.end)?;
997            let value = ty::Value { ty: self.ty, valtree };
998            f.write_fmt(format_args!("{0}", value))write!(f, "{value}")?;
999        } else {
1000            // `0..` is parsed as an inclusive range, we must display it correctly.
1001            f.write_fmt(format_args!(".."))write!(f, "..")?;
1002        }
1003        Ok(())
1004    }
1005}
1006
1007/// A (possibly open) boundary of a range pattern.
1008/// If present, the const must be of a numeric type.
1009#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for PatRangeBoundary<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for PatRangeBoundary<'tcx> {
    #[inline]
    fn clone(&self) -> PatRangeBoundary<'tcx> {
        let _: ::core::clone::AssertParamIsClone<ty::ValTree<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PatRangeBoundary<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            PatRangeBoundary::Finite(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Finite",
                    &__self_0),
            PatRangeBoundary::NegInfinity =>
                ::core::fmt::Formatter::write_str(f, "NegInfinity"),
            PatRangeBoundary::PosInfinity =>
                ::core::fmt::Formatter::write_str(f, "PosInfinity"),
        }
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for PatRangeBoundary<'tcx> {
    #[inline]
    fn eq(&self, other: &PatRangeBoundary<'tcx>) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (PatRangeBoundary::Finite(__self_0),
                    PatRangeBoundary::Finite(__arg1_0)) => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for PatRangeBoundary<'tcx> {
            #[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 {
                    PatRangeBoundary::Finite(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    PatRangeBoundary::NegInfinity => {}
                    PatRangeBoundary::PosInfinity => {}
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for PatRangeBoundary<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    PatRangeBoundary::Finite(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);
                                }
                            }
                        }
                    }
                    PatRangeBoundary::NegInfinity => {}
                    PatRangeBoundary::PosInfinity => {}
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable)]
1010pub enum PatRangeBoundary<'tcx> {
1011    /// The type of this valtree is stored in the surrounding `PatRange`.
1012    Finite(ty::ValTree<'tcx>),
1013    NegInfinity,
1014    PosInfinity,
1015}
1016
1017impl<'tcx> PatRangeBoundary<'tcx> {
1018    #[inline]
1019    pub fn is_finite(self) -> bool {
1020        #[allow(non_exhaustive_omitted_patterns)] match self {
    Self::Finite(..) => true,
    _ => false,
}matches!(self, Self::Finite(..))
1021    }
1022    #[inline]
1023    pub fn as_finite(self) -> Option<ty::ValTree<'tcx>> {
1024        match self {
1025            Self::Finite(value) => Some(value),
1026            Self::NegInfinity | Self::PosInfinity => None,
1027        }
1028    }
1029    pub fn to_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> u128 {
1030        match self {
1031            Self::Finite(value) => value.to_leaf().to_bits_unchecked(),
1032            Self::NegInfinity => {
1033                // Unwrap is ok because the type is known to be numeric.
1034                ty.numeric_min_and_max_as_bits(tcx).unwrap().0
1035            }
1036            Self::PosInfinity => {
1037                // Unwrap is ok because the type is known to be numeric.
1038                ty.numeric_min_and_max_as_bits(tcx).unwrap().1
1039            }
1040        }
1041    }
1042
1043    x;#[instrument(skip(tcx), level = "debug", ret)]
1044    pub fn compare_with(self, other: Self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Ordering> {
1045        use PatRangeBoundary::*;
1046        match (self, other) {
1047            // When comparing with infinities, we must remember that `0u8..` and `0u8..=255`
1048            // describe the same range. These two shortcuts are ok, but for the rest we must check
1049            // bit values.
1050            (PosInfinity, PosInfinity) => return Some(Ordering::Equal),
1051            (NegInfinity, NegInfinity) => return Some(Ordering::Equal),
1052
1053            // This code is hot when compiling matches with many ranges. So we
1054            // special-case extraction of evaluated scalars for speed, for types where
1055            // we can do scalar comparisons. E.g. `unicode-normalization` has
1056            // many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared
1057            // in this way.
1058            (Finite(a), Finite(b)) if matches!(ty.kind(), ty::Int(_) | ty::Uint(_) | ty::Char) => {
1059                if let (Some(a), Some(b)) = (a.try_to_leaf(), b.try_to_leaf()) {
1060                    let sz = ty.primitive_size(tcx);
1061                    let cmp = match ty.kind() {
1062                        ty::Uint(_) | ty::Char => a.to_uint(sz).cmp(&b.to_uint(sz)),
1063                        ty::Int(_) => a.to_int(sz).cmp(&b.to_int(sz)),
1064                        _ => unreachable!(),
1065                    };
1066                    return Some(cmp);
1067                }
1068            }
1069            _ => {}
1070        }
1071
1072        let a = self.to_bits(ty, tcx);
1073        let b = other.to_bits(ty, tcx);
1074
1075        match ty.kind() {
1076            ty::Float(ty::FloatTy::F16) => {
1077                use rustc_apfloat::Float;
1078                let a = rustc_apfloat::ieee::Half::from_bits(a);
1079                let b = rustc_apfloat::ieee::Half::from_bits(b);
1080                a.partial_cmp(&b)
1081            }
1082            ty::Float(ty::FloatTy::F32) => {
1083                use rustc_apfloat::Float;
1084                let a = rustc_apfloat::ieee::Single::from_bits(a);
1085                let b = rustc_apfloat::ieee::Single::from_bits(b);
1086                a.partial_cmp(&b)
1087            }
1088            ty::Float(ty::FloatTy::F64) => {
1089                use rustc_apfloat::Float;
1090                let a = rustc_apfloat::ieee::Double::from_bits(a);
1091                let b = rustc_apfloat::ieee::Double::from_bits(b);
1092                a.partial_cmp(&b)
1093            }
1094            ty::Float(ty::FloatTy::F128) => {
1095                use rustc_apfloat::Float;
1096                let a = rustc_apfloat::ieee::Quad::from_bits(a);
1097                let b = rustc_apfloat::ieee::Quad::from_bits(b);
1098                a.partial_cmp(&b)
1099            }
1100            ty::Int(ity) => {
1101                let size = rustc_abi::Integer::from_int_ty(&tcx, *ity).size();
1102                let a = size.sign_extend(a) as i128;
1103                let b = size.sign_extend(b) as i128;
1104                Some(a.cmp(&b))
1105            }
1106            ty::Uint(_) | ty::Char => Some(a.cmp(&b)),
1107            _ => bug!(),
1108        }
1109    }
1110}
1111
1112// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
1113#[cfg(target_pointer_width = "64")]
1114mod size_asserts {
1115    use rustc_data_structures::static_assert_size;
1116
1117    use super::*;
1118    // tidy-alphabetical-start
1119    const _: [(); 48] = [(); ::std::mem::size_of::<Block>()];static_assert_size!(Block, 48);
1120    const _: [(); 64] = [(); ::std::mem::size_of::<Expr<'_>>()];static_assert_size!(Expr<'_>, 64);
1121    const _: [(); 40] = [(); ::std::mem::size_of::<ExprKind<'_>>()];static_assert_size!(ExprKind<'_>, 40);
1122    const _: [(); 72] = [(); ::std::mem::size_of::<Pat<'_>>()];static_assert_size!(Pat<'_>, 72);
1123    const _: [(); 48] = [(); ::std::mem::size_of::<PatKind<'_>>()];static_assert_size!(PatKind<'_>, 48);
1124    const _: [(); 48] = [(); ::std::mem::size_of::<Stmt<'_>>()];static_assert_size!(Stmt<'_>, 48);
1125    const _: [(); 48] = [(); ::std::mem::size_of::<StmtKind<'_>>()];static_assert_size!(StmtKind<'_>, 48);
1126    // tidy-alphabetical-end
1127}