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::{StableHash, 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                #[stable_hash]
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, StableHash, 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> ::rustc_data_structures::stable_hasher::StableHash for
            Thir<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__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> ::rustc_data_structures::stable_hasher::StableHash for
            BodyTy<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    BodyTy::Const(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    BodyTy::Fn(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    BodyTy::GlobalAsm(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, #[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> ::rustc_data_structures::stable_hasher::StableHash for
            Param<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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 ::rustc_data_structures::stable_hasher::StableHash for Block {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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> ::rustc_data_structures::stable_hasher::StableHash for
            AdtExpr<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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> ::rustc_data_structures::stable_hasher::StableHash for
            AdtExprBase<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    AdtExprBase::None => {}
                    AdtExprBase::Base(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AdtExprBase::DefaultFields(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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> ::rustc_data_structures::stable_hasher::StableHash for
            ClosureExpr<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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> ::rustc_data_structures::stable_hasher::StableHash for
            InlineAsmExpr<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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 ::rustc_data_structures::stable_hasher::StableHash for
            BlockSafety {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    BlockSafety::Safe => {}
                    BlockSafety::BuiltinUnsafe => {}
                    BlockSafety::ExplicitUnsafe(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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> ::rustc_data_structures::stable_hasher::StableHash for
            Stmt<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Stmt { kind: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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> ::rustc_data_structures::stable_hasher::StableHash for
            StmtKind<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    StmtKind::Expr {
                        scope: ref __binding_0, expr: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                        { __binding_6.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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_fields_are_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 ::rustc_data_structures::stable_hasher::StableHash for LocalVarId
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    LocalVarId(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, 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> ::rustc_data_structures::stable_hasher::StableHash for
            Expr<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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::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),
                },
            ExprKind::Reborrow {
                source: __self_0, mutability: __self_1, target: __self_2 } =>
                ExprKind::Reborrow {
                    source: ::core::clone::Clone::clone(__self_0),
                    mutability: ::core::clone::Clone::clone(__self_1),
                    target: ::core::clone::Clone::clone(__self_2),
                },
        }
    }
}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::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),
            ExprKind::Reborrow {
                source: __self_0, mutability: __self_1, target: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Reborrow", "source", __self_0, "mutability", __self_1,
                    "target", &__self_2),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hasher::StableHash for
            ExprKind<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    ExprKind::Scope {
                        region_scope: ref __binding_0,
                        hir_id: ref __binding_1,
                        value: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ByUse {
                        expr: ref __binding_0, span: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Deref { arg: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Binary {
                        op: ref __binding_0,
                        lhs: ref __binding_1,
                        rhs: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::LogicalOp {
                        op: ref __binding_0,
                        lhs: ref __binding_1,
                        rhs: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Unary { op: ref __binding_0, arg: ref __binding_1
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Cast { source: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Use { source: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::NeverToAny { source: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::PointerCoercion {
                        cast: ref __binding_0,
                        source: ref __binding_1,
                        is_from_as_cast: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Loop { body: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::LoopMatch {
                        state: ref __binding_0,
                        region_scope: ref __binding_1,
                        match_data: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Let { expr: ref __binding_0, pat: ref __binding_1
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Match {
                        scrutinee: ref __binding_0,
                        arms: ref __binding_1,
                        match_source: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Block { block: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Assign {
                        lhs: ref __binding_0, rhs: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::AssignOp {
                        op: ref __binding_0,
                        lhs: ref __binding_1,
                        rhs: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Field {
                        lhs: ref __binding_0,
                        variant_index: ref __binding_1,
                        name: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Index {
                        lhs: ref __binding_0, index: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::VarRef { id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::UpvarRef {
                        closure_def_id: ref __binding_0, var_hir_id: ref __binding_1
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Borrow {
                        borrow_kind: ref __binding_0, arg: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::RawBorrow {
                        mutability: ref __binding_0, arg: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Break {
                        label: ref __binding_0, value: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Continue { label: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ConstContinue {
                        label: ref __binding_0, value: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Return { value: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Become { value: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ConstBlock {
                        did: ref __binding_0, args: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Repeat {
                        value: ref __binding_0, count: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Array { fields: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Tuple { fields: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Adt(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::PlaceTypeAscription {
                        source: ref __binding_0,
                        user_ty: ref __binding_1,
                        user_ty_span: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ValueTypeAscription {
                        source: ref __binding_0,
                        user_ty: ref __binding_1,
                        user_ty_span: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::PlaceUnwrapUnsafeBinder { source: ref __binding_0
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ValueUnwrapUnsafeBinder { source: ref __binding_0
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::WrapUnsafeBinder { source: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Closure(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Literal {
                        lit: ref __binding_0, neg: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::NonHirLiteral {
                        lit: ref __binding_0, user_ty: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ZstLiteral { user_ty: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::NamedConst {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        user_ty: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ConstParam {
                        param: ref __binding_0, def_id: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::StaticRef {
                        alloc_id: ref __binding_0,
                        ty: ref __binding_1,
                        def_id: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::InlineAsm(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::ThreadLocalRef(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Yield { value: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ExprKind::Reborrow {
                        source: ref __binding_0,
                        mutability: ref __binding_1,
                        target: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
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    /// An `if` expression.
272    If {
273        if_then_scope: region::Scope,
274        cond: ExprId,
275        /// `then` is always `ExprKind::Block`.
276        then: ExprId,
277        /// If present, the `else_opt` expr is always `ExprKind::Block` (for
278        /// `else`) or `ExprKind::If` (for `else if`).
279        else_opt: Option<ExprId>,
280    },
281    /// A function call. Method calls and overloaded operators are converted to plain function calls.
282    Call {
283        /// The type of the function. This is often a [`FnDef`] or a [`FnPtr`].
284        ///
285        /// [`FnDef`]: ty::TyKind::FnDef
286        /// [`FnPtr`]: ty::TyKind::FnPtr
287        ty: Ty<'tcx>,
288        /// The function itself.
289        fun: ExprId,
290        /// The arguments passed to the function.
291        ///
292        /// Note: in some cases (like calling a closure), the function call `f(...args)` gets
293        /// rewritten as a call to a function trait method (e.g. `FnOnce::call_once(f, (...args))`).
294        args: Box<[ExprId]>,
295        /// Whether this is from an overloaded operator rather than a
296        /// function call from HIR. `true` for overloaded function call.
297        from_hir_call: bool,
298        /// The span of the function, without the dot and receiver
299        /// (e.g. `foo(a, b)` in `x.foo(a, b)`).
300        fn_span: Span,
301    },
302    /// A use expression `x.use`.
303    ByUse {
304        /// The expression on which use is applied.
305        expr: ExprId,
306        /// The span of use, without the dot and receiver
307        /// (e.g. `use` in `x.use`).
308        span: Span,
309    },
310    /// A *non-overloaded* dereference.
311    Deref {
312        arg: ExprId,
313    },
314    /// A *non-overloaded* binary operation.
315    Binary {
316        op: BinOp,
317        lhs: ExprId,
318        rhs: ExprId,
319    },
320    /// A logical operation. This is distinct from `BinaryOp` because
321    /// the operands need to be lazily evaluated.
322    LogicalOp {
323        op: LogicalOp,
324        lhs: ExprId,
325        rhs: ExprId,
326    },
327    /// A *non-overloaded* unary operation. Note that here the deref (`*`)
328    /// operator is represented by `ExprKind::Deref`.
329    Unary {
330        op: UnOp,
331        arg: ExprId,
332    },
333    /// A cast: `<source> as <type>`. The type we cast to is the type of
334    /// the parent expression.
335    Cast {
336        source: ExprId,
337    },
338    /// Forces its contents to be treated as a value expression, not a place
339    /// expression. This is inserted in some places where an operation would
340    /// otherwise be erased completely (e.g. some no-op casts), but we still
341    /// need to ensure that its operand is treated as a value and not a place.
342    Use {
343        source: ExprId,
344    },
345    /// A coercion from `!` to any type.
346    NeverToAny {
347        source: ExprId,
348    },
349    /// A pointer coercion. More information can be found in [`PointerCoercion`].
350    /// Pointer casts that cannot be done by coercions are represented by [`ExprKind::Cast`].
351    PointerCoercion {
352        cast: PointerCoercion,
353        source: ExprId,
354        /// Whether this coercion is written with an `as` cast in the source code.
355        is_from_as_cast: bool,
356    },
357    /// A `loop` expression.
358    Loop {
359        body: ExprId,
360    },
361    /// A `#[loop_match] loop { state = 'blk: { match state { ... } } }` expression.
362    LoopMatch {
363        /// The state variable that is updated.
364        /// The `match_data.scrutinee` is the same variable, but with a different span.
365        state: ExprId,
366        region_scope: region::Scope,
367        match_data: Box<LoopMatchMatchData>,
368    },
369    /// Special expression representing the `let` part of an `if let` or similar construct
370    /// (including `if let` guards in match arms, and let-chains formed by `&&`).
371    ///
372    /// This isn't considered a real expression in surface Rust syntax, so it can
373    /// only appear in specific situations, such as within the condition of an `if`.
374    ///
375    /// (Not to be confused with [`StmtKind::Let`], which is a normal `let` statement.)
376    Let {
377        expr: ExprId,
378        pat: Box<Pat<'tcx>>,
379    },
380    /// A `match` expression.
381    Match {
382        scrutinee: ExprId,
383        arms: Box<[ArmId]>,
384        match_source: MatchSource,
385    },
386    /// A block.
387    Block {
388        block: BlockId,
389    },
390    /// An assignment: `lhs = rhs`.
391    Assign {
392        lhs: ExprId,
393        rhs: ExprId,
394    },
395    /// A *non-overloaded* operation assignment, e.g. `lhs += rhs`.
396    AssignOp {
397        op: AssignOp,
398        lhs: ExprId,
399        rhs: ExprId,
400    },
401    /// Access to a field of a struct, a tuple, an union, or an enum.
402    Field {
403        lhs: ExprId,
404        /// Variant containing the field.
405        variant_index: VariantIdx,
406        /// This can be a named (`.foo`) or unnamed (`.0`) field.
407        name: FieldIdx,
408    },
409    /// A *non-overloaded* indexing operation.
410    Index {
411        lhs: ExprId,
412        index: ExprId,
413    },
414    /// A local variable.
415    VarRef {
416        id: LocalVarId,
417    },
418    /// Used to represent upvars mentioned in a closure/coroutine
419    UpvarRef {
420        /// DefId of the closure/coroutine
421        closure_def_id: DefId,
422
423        /// HirId of the root variable
424        var_hir_id: LocalVarId,
425    },
426    /// A borrow, e.g. `&arg`.
427    Borrow {
428        borrow_kind: BorrowKind,
429        arg: ExprId,
430    },
431    /// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
432    RawBorrow {
433        mutability: hir::Mutability,
434        arg: ExprId,
435    },
436    /// A `break` expression.
437    Break {
438        label: region::Scope,
439        value: Option<ExprId>,
440    },
441    /// A `continue` expression.
442    Continue {
443        label: region::Scope,
444    },
445    /// A `#[const_continue] break` expression.
446    ConstContinue {
447        label: region::Scope,
448        value: ExprId,
449    },
450    /// A `return` expression.
451    Return {
452        value: Option<ExprId>,
453    },
454    /// A `become` expression.
455    Become {
456        value: ExprId,
457    },
458    /// An inline `const` block, e.g. `const {}`.
459    ConstBlock {
460        did: DefId,
461        args: GenericArgsRef<'tcx>,
462    },
463    /// An array literal constructed from one repeated element, e.g. `[1; 5]`.
464    Repeat {
465        value: ExprId,
466        count: ty::Const<'tcx>,
467    },
468    /// An array, e.g. `[a, b, c, d]`.
469    Array {
470        fields: Box<[ExprId]>,
471    },
472    /// A tuple, e.g. `(a, b, c, d)`.
473    Tuple {
474        fields: Box<[ExprId]>,
475    },
476    /// An ADT constructor, e.g. `Foo {x: 1, y: 2}`.
477    Adt(Box<AdtExpr<'tcx>>),
478    /// A type ascription on a place.
479    PlaceTypeAscription {
480        source: ExprId,
481        /// Type that the user gave to this expression
482        user_ty: UserTy<'tcx>,
483        user_ty_span: Span,
484    },
485    /// A type ascription on a value, e.g. `type_ascribe!(42, i32)` or `42 as i32`.
486    ValueTypeAscription {
487        source: ExprId,
488        /// Type that the user gave to this expression
489        user_ty: UserTy<'tcx>,
490        user_ty_span: Span,
491    },
492    /// An unsafe binder cast on a place, e.g. `unwrap_binder!(*ptr)`.
493    PlaceUnwrapUnsafeBinder {
494        source: ExprId,
495    },
496    /// An unsafe binder cast on a value, e.g. `unwrap_binder!(rvalue())`,
497    /// which makes a temporary.
498    ValueUnwrapUnsafeBinder {
499        source: ExprId,
500    },
501    /// Construct an unsafe binder, e.g. `wrap_binder(&ref)`.
502    WrapUnsafeBinder {
503        source: ExprId,
504    },
505    /// A closure definition.
506    Closure(Box<ClosureExpr<'tcx>>),
507    /// A literal.
508    Literal {
509        lit: hir::Lit,
510        neg: bool,
511    },
512    /// For literals that don't correspond to anything in the HIR
513    NonHirLiteral {
514        lit: ty::ScalarInt,
515        user_ty: UserTy<'tcx>,
516    },
517    /// A literal of a ZST type.
518    ZstLiteral {
519        user_ty: UserTy<'tcx>,
520    },
521    /// Associated constants and named constants
522    NamedConst {
523        def_id: DefId,
524        args: GenericArgsRef<'tcx>,
525        user_ty: UserTy<'tcx>,
526    },
527    ConstParam {
528        param: ty::ParamConst,
529        def_id: DefId,
530    },
531    // FIXME improve docs for `StaticRef` by distinguishing it from `NamedConst`
532    /// A literal containing the address of a `static`.
533    ///
534    /// This is only distinguished from `Literal` so that we can register some
535    /// info for diagnostics.
536    StaticRef {
537        alloc_id: AllocId,
538        ty: Ty<'tcx>,
539        def_id: DefId,
540    },
541    /// Inline assembly, i.e. `asm!()`.
542    InlineAsm(Box<InlineAsmExpr<'tcx>>),
543    /// An expression taking a reference to a thread local.
544    ThreadLocalRef(DefId),
545    /// A `yield` expression.
546    Yield {
547        value: ExprId,
548    },
549    /// Use of an ADT that implements the Reborrow (for Mut) or CoerceShared traits (for Not). This
550    /// expression is produced by the [`Adjust::GenericReborrow`] in places where normally the ADT
551    /// would be moved or assigned over. Instead, this produces an [`Rvalue::Reborrow`] which
552    /// produces a bitwise copy of the source ADT and disables the source for the copy's lifetime.
553    ///
554    /// [`Adjust::GenericReborrow`]: crate::ty::adjustment::Adjust::GenericReborrow
555    /// [`Rvalue::Reborrow`]: mir::Rvalue::Reborrow
556    Reborrow {
557        source: ExprId,
558        mutability: Mutability,
559        target: Ty<'tcx>,
560    },
561}
562
563/// Represents the association of a field identifier and an expression.
564///
565/// This is used in struct constructors.
566#[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 ::rustc_data_structures::stable_hasher::StableHash for FieldExpr
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FieldExpr { name: ref __binding_0, expr: ref __binding_1 }
                        => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
567pub struct FieldExpr {
568    pub name: FieldIdx,
569    pub expr: ExprId,
570}
571
572#[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> ::rustc_data_structures::stable_hasher::StableHash for
            FruInfo<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FruInfo {
                        base: ref __binding_0, field_types: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
573pub struct FruInfo<'tcx> {
574    pub base: ExprId,
575    pub field_types: Box<[Ty<'tcx>]>,
576}
577
578/// A `match` arm.
579#[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> ::rustc_data_structures::stable_hasher::StableHash for
            Arm<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
580pub struct Arm<'tcx> {
581    pub pattern: Box<Pat<'tcx>>,
582    pub guard: Option<ExprId>,
583    pub body: ExprId,
584    pub hir_id: HirId,
585    pub scope: region::Scope,
586    pub span: Span,
587}
588
589/// The `match` part of a `#[loop_match]`
590#[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 ::rustc_data_structures::stable_hasher::StableHash for
            LoopMatchMatchData {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
591pub struct LoopMatchMatchData {
592    pub scrutinee: ExprId,
593    pub arms: Box<[ArmId]>,
594    pub span: Span,
595}
596
597#[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 ::rustc_data_structures::stable_hasher::StableHash for LogicalOp
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self { LogicalOp::And => {} LogicalOp::Or => {} }
            }
        }
    };StableHash)]
598pub enum LogicalOp {
599    /// The `&&` operator.
600    And,
601    /// The `||` operator.
602    Or,
603}
604
605#[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> ::rustc_data_structures::stable_hasher::StableHash for
            InlineAsmOperand<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    InlineAsmOperand::In {
                        reg: ref __binding_0, expr: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    InlineAsmOperand::Out {
                        reg: ref __binding_0,
                        late: ref __binding_1,
                        expr: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    InlineAsmOperand::InOut {
                        reg: ref __binding_0,
                        late: ref __binding_1,
                        expr: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    InlineAsmOperand::SplitInOut {
                        reg: ref __binding_0,
                        late: ref __binding_1,
                        in_expr: ref __binding_2,
                        out_expr: ref __binding_3 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                    }
                    InlineAsmOperand::Const {
                        value: ref __binding_0, span: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    InlineAsmOperand::SymFn { value: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    InlineAsmOperand::SymStatic { def_id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    InlineAsmOperand::Label { block: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
606pub enum InlineAsmOperand<'tcx> {
607    In {
608        reg: InlineAsmRegOrRegClass,
609        expr: ExprId,
610    },
611    Out {
612        reg: InlineAsmRegOrRegClass,
613        late: bool,
614        expr: Option<ExprId>,
615    },
616    InOut {
617        reg: InlineAsmRegOrRegClass,
618        late: bool,
619        expr: ExprId,
620    },
621    SplitInOut {
622        reg: InlineAsmRegOrRegClass,
623        late: bool,
624        in_expr: ExprId,
625        out_expr: Option<ExprId>,
626    },
627    Const {
628        value: mir::Const<'tcx>,
629        span: Span,
630    },
631    SymFn {
632        value: ExprId,
633    },
634    SymStatic {
635        def_id: DefId,
636    },
637    Label {
638        block: BlockId,
639    },
640}
641
642#[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> ::rustc_data_structures::stable_hasher::StableHash for
            FieldPat<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FieldPat { field: ref __binding_0, pattern: ref __binding_1
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, 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)]
643pub struct FieldPat<'tcx> {
644    pub field: FieldIdx,
645    pub pattern: Pat<'tcx>,
646}
647
648/// Additional per-node data that is not present on most THIR pattern nodes.
649#[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> ::rustc_data_structures::stable_hasher::StableHash for
            PatExtra<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    PatExtra {
                        expanded_const: ref __binding_0,
                        ascriptions: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, 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)]
650pub struct PatExtra<'tcx> {
651    /// If present, this node represents a named constant that was lowered to
652    /// a pattern using `const_to_pat`.
653    ///
654    /// This is used by some diagnostics for non-exhaustive matches, to map
655    /// the pattern node back to the `DefId` of its original constant.
656    pub expanded_const: Option<DefId>,
657
658    /// User-written types that must be preserved into MIR so that they can be
659    /// checked.
660    pub ascriptions: Vec<Ascription<'tcx>>,
661}
662
663#[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> ::rustc_data_structures::stable_hasher::StableHash for
            Pat<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, 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)]
664pub struct Pat<'tcx> {
665    pub ty: Ty<'tcx>,
666    pub span: Span,
667    pub extra: Option<Box<PatExtra<'tcx>>>,
668    pub kind: PatKind<'tcx>,
669}
670
671impl<'tcx> Pat<'tcx> {
672    pub fn simple_ident(&self) -> Option<Symbol> {
673        match self.kind {
674            PatKind::Binding {
675                name, mode: BindingMode(ByRef::No, _), subpattern: None, ..
676            } => Some(name),
677            _ => None,
678        }
679    }
680
681    /// Call `f` on every "binding" in a pattern, e.g., on `a` in
682    /// `match foo() { Some(a) => (), None => () }`
683    pub fn each_binding(&self, mut f: impl FnMut(Symbol, ByRef, Ty<'tcx>, Span)) {
684        self.walk_always(|p| {
685            if let PatKind::Binding { name, mode, ty, .. } = p.kind {
686                f(name, mode.0, ty, p.span);
687            }
688        });
689    }
690
691    /// Walk the pattern in left-to-right order.
692    ///
693    /// If `it(pat)` returns `false`, the children are not visited.
694    pub fn walk(&self, mut it: impl FnMut(&Pat<'tcx>) -> bool) {
695        self.walk_(&mut it)
696    }
697
698    fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
699        if !it(self) {
700            return;
701        }
702
703        for_each_immediate_subpat(self, |p| p.walk_(it));
704    }
705
706    /// Whether the pattern has a `PatKind::Error` nested within.
707    pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> {
708        let mut error = None;
709        self.walk(|pat| {
710            if let PatKind::Error(e) = pat.kind
711                && error.is_none()
712            {
713                error = Some(e);
714            }
715            error.is_none()
716        });
717        match error {
718            None => Ok(()),
719            Some(e) => Err(e),
720        }
721    }
722
723    /// Walk the pattern in left-to-right order.
724    ///
725    /// If you always want to recurse, prefer this method over `walk`.
726    pub fn walk_always(&self, mut it: impl FnMut(&Pat<'tcx>)) {
727        self.walk(|p| {
728            it(p);
729            true
730        })
731    }
732
733    /// Whether this a never pattern.
734    pub fn is_never_pattern(&self) -> bool {
735        let mut is_never_pattern = false;
736        self.walk(|pat| match &pat.kind {
737            PatKind::Never => {
738                is_never_pattern = true;
739                false
740            }
741            PatKind::Or { pats } => {
742                is_never_pattern = pats.iter().all(|p| p.is_never_pattern());
743                false
744            }
745            _ => true,
746        });
747        is_never_pattern
748    }
749}
750
751#[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> ::rustc_data_structures::stable_hasher::StableHash for
            Ascription<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Ascription {
                        annotation: ref __binding_0, variance: ref __binding_1 } =>
                        {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, 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)]
752pub struct Ascription<'tcx> {
753    pub annotation: CanonicalUserTypeAnnotation<'tcx>,
754    /// Variance to use when relating the `user_ty` to the **type of the value being
755    /// matched**. Typically, this is `Variance::Covariant`, since the value being matched must
756    /// have a type that is some subtype of the ascribed type.
757    ///
758    /// Note that this variance does not apply for any bindings within subpatterns. The type
759    /// assigned to those bindings must be exactly equal to the `user_ty` given here.
760    ///
761    /// The only place where this field is not `Covariant` is when matching constants, where
762    /// we currently use `Contravariant` -- this is because the constant type just needs to
763    /// be "comparable" to the type of the input value. So, for example:
764    ///
765    /// ```text
766    /// match x { "foo" => .. }
767    /// ```
768    ///
769    /// requires that `&'static str <: T_x`, where `T_x` is the type of `x`. Really, we should
770    /// probably be checking for a `PartialEq` impl instead, but this preserves the behavior
771    /// of the old type-check for now. See #57280 for details.
772    pub variance: ty::Variance,
773}
774
775#[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::Guard { subpattern: __self_0, condition: __self_1 } =>
                PatKind::Guard {
                    subpattern: ::core::clone::Clone::clone(__self_0),
                    condition: ::core::clone::Clone::clone(__self_1),
                },
            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::Guard { subpattern: __self_0, condition: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Guard",
                    "subpattern", __self_0, "condition", &__self_1),
            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> ::rustc_data_structures::stable_hasher::StableHash for
            PatKind<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                        { __binding_6.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Variant {
                        adt_def: ref __binding_0,
                        args: ref __binding_1,
                        variant_index: ref __binding_2,
                        subpatterns: ref __binding_3 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Leaf { subpatterns: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Deref {
                        pin: ref __binding_0, subpattern: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::DerefPattern {
                        subpattern: ref __binding_0, borrow: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Constant { value: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Range(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Slice {
                        prefix: ref __binding_0,
                        slice: ref __binding_1,
                        suffix: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Array {
                        prefix: ref __binding_0,
                        slice: ref __binding_1,
                        suffix: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Or { pats: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Guard {
                        subpattern: ref __binding_0, condition: ref __binding_1 } =>
                        {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    PatKind::Never => {}
                    PatKind::Error(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, 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::Guard { 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::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)]
776pub enum PatKind<'tcx> {
777    /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
778    Missing,
779
780    /// A wildcard pattern: `_`.
781    Wild,
782
783    /// `x`, `ref x`, `x @ P`, etc.
784    Binding {
785        name: Symbol,
786        #[type_visitable(ignore)]
787        mode: BindingMode,
788        #[type_visitable(ignore)]
789        var: LocalVarId,
790        ty: Ty<'tcx>,
791        subpattern: Option<Box<Pat<'tcx>>>,
792
793        /// Is this the leftmost occurrence of the binding, i.e., is `var` the
794        /// `HirId` of this pattern?
795        ///
796        /// (The same binding can occur multiple times in different branches of
797        /// an or-pattern, but only one of them will be primary.)
798        is_primary: bool,
799        /// Is this binding a shorthand struct pattern, i.e. `Foo { a }`?
800        is_shorthand: bool,
801    },
802
803    /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
804    /// multiple variants.
805    Variant {
806        adt_def: AdtDef<'tcx>,
807        args: GenericArgsRef<'tcx>,
808        variant_index: VariantIdx,
809        subpatterns: Vec<FieldPat<'tcx>>,
810    },
811
812    /// `(...)`, `Foo(...)`, `Foo{...}`, or `Foo`, where `Foo` is a variant name from an ADT with
813    /// a single variant.
814    Leaf {
815        subpatterns: Vec<FieldPat<'tcx>>,
816    },
817
818    /// Explicit or implicit `&P` or `&mut P`, for some subpattern `P`.
819    ///
820    /// Implicit `&`/`&mut` patterns can be inserted by match-ergonomics.
821    ///
822    /// With `feature(pin_ergonomics)`, this can also be `&pin const P` or
823    /// `&pin mut P`, as indicated by the `pin` field.
824    Deref {
825        #[type_visitable(ignore)]
826        pin: hir::Pinnedness,
827        subpattern: Box<Pat<'tcx>>,
828    },
829
830    /// Explicit or implicit `deref!(..)` pattern, under `feature(deref_patterns)`.
831    /// Represents a call to `Deref` or `DerefMut`, or a deref-move of `Box`.
832    ///
833    /// `box P` patterns also lower to this, under `feature(box_patterns)`.
834    DerefPattern {
835        subpattern: Box<Pat<'tcx>>,
836        /// Whether the pattern scrutinee needs to be borrowed in order to call `Deref::deref` or
837        /// `DerefMut::deref_mut`, and if so, which. This is `DerefPatBorrowMode::Box` for deref patterns on
838        /// boxes; they are lowered using a built-in deref rather than a method call, thus they
839        /// don't borrow the scrutinee.
840        #[type_visitable(ignore)]
841        borrow: DerefPatBorrowMode,
842    },
843
844    /// One of the following:
845    /// * `&str`, which will be handled as a string pattern and thus
846    ///   exhaustiveness checking will detect if you use the same string twice in different
847    ///   patterns.
848    /// * integer, bool, char or float, which will be handled by
849    ///   exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
850    ///   much simpler.
851    /// * raw pointers derived from integers, other raw pointers will have already resulted in an
852    ///   error.
853    Constant {
854        value: ty::Value<'tcx>,
855    },
856
857    Range(Arc<PatRange<'tcx>>),
858
859    /// Matches against a slice, checking the length and extracting elements.
860    /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
861    /// e.g., `&[ref xs @ ..]`.
862    Slice {
863        prefix: Box<[Pat<'tcx>]>,
864        slice: Option<Box<Pat<'tcx>>>,
865        suffix: Box<[Pat<'tcx>]>,
866    },
867
868    /// Fixed match against an array; irrefutable.
869    Array {
870        prefix: Box<[Pat<'tcx>]>,
871        slice: Option<Box<Pat<'tcx>>>,
872        suffix: Box<[Pat<'tcx>]>,
873    },
874
875    /// An or-pattern, e.g. `p | q`.
876    /// Invariant: `pats.len() >= 2`.
877    Or {
878        pats: Box<[Pat<'tcx>]>,
879    },
880
881    /// A guard pattern, e.g. `x if guard(x)`
882    Guard {
883        subpattern: Box<Pat<'tcx>>,
884        #[type_visitable(ignore)]
885        condition: ExprId,
886    },
887
888    /// A never pattern `!`.
889    Never,
890
891    /// An error has been encountered during lowering. We probably shouldn't report more lints
892    /// related to this pattern.
893    Error(ErrorGuaranteed),
894}
895
896#[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 ::rustc_data_structures::stable_hasher::StableHash for
            DerefPatBorrowMode {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    DerefPatBorrowMode::Borrow(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    DerefPatBorrowMode::Box => {}
                }
            }
        }
    };StableHash)]
897pub enum DerefPatBorrowMode {
898    Borrow(Mutability),
899    Box,
900}
901
902/// A range pattern.
903/// The boundaries must be of the same type and that type must be numeric.
904#[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> ::rustc_data_structures::stable_hasher::StableHash for
            PatRange<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __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.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, 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)]
905pub struct PatRange<'tcx> {
906    /// Must not be `PosInfinity`.
907    pub lo: PatRangeBoundary<'tcx>,
908    /// Must not be `NegInfinity`.
909    pub hi: PatRangeBoundary<'tcx>,
910    #[type_visitable(ignore)]
911    pub end: RangeEnd,
912    pub ty: Ty<'tcx>,
913}
914
915impl<'tcx> PatRange<'tcx> {
916    /// Whether this range covers the full extent of possible values (best-effort, we ignore floats).
917    #[inline]
918    pub fn is_full_range(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
919        let (min, max, size, bias) = match *self.ty.kind() {
920            ty::Char => (0, std::char::MAX as u128, Size::from_bits(32), 0),
921            ty::Int(ity) => {
922                let size = Integer::from_int_ty(&tcx, ity).size();
923                let max = size.truncate(u128::MAX);
924                let bias = 1u128 << (size.bits() - 1);
925                (0, max, size, bias)
926            }
927            ty::Uint(uty) => {
928                let size = Integer::from_uint_ty(&tcx, uty).size();
929                let max = size.unsigned_int_max();
930                (0, max, size, 0)
931            }
932            _ => return None,
933        };
934
935        // We want to compare ranges numerically, but the order of the bitwise representation of
936        // signed integers does not match their numeric order. Thus, to correct the ordering, we
937        // need to shift the range of signed integers to correct the comparison. This is achieved by
938        // XORing with a bias (see pattern/deconstruct_pat.rs for another pertinent example of this
939        // pattern).
940        //
941        // Also, for performance, it's important to only do the second `try_to_bits` if necessary.
942        let lo_is_min = match self.lo {
943            PatRangeBoundary::NegInfinity => true,
944            PatRangeBoundary::Finite(value) => {
945                let lo = value.to_leaf().to_bits(size) ^ bias;
946                lo <= min
947            }
948            PatRangeBoundary::PosInfinity => false,
949        };
950        if lo_is_min {
951            let hi_is_max = match self.hi {
952                PatRangeBoundary::NegInfinity => false,
953                PatRangeBoundary::Finite(value) => {
954                    let hi = value.to_leaf().to_bits(size) ^ bias;
955                    hi > max || hi == max && self.end == RangeEnd::Included
956                }
957                PatRangeBoundary::PosInfinity => true,
958            };
959            if hi_is_max {
960                return Some(true);
961            }
962        }
963        Some(false)
964    }
965
966    #[inline]
967    pub fn contains(&self, value: ty::Value<'tcx>, tcx: TyCtxt<'tcx>) -> Option<bool> {
968        use Ordering::*;
969        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);
970        let ty = self.ty;
971        let value = PatRangeBoundary::Finite(value.valtree);
972        // For performance, it's important to only do the second comparison if necessary.
973        Some(
974            match self.lo.compare_with(value, ty, tcx)? {
975                Less | Equal => true,
976                Greater => false,
977            } && match value.compare_with(self.hi, ty, tcx)? {
978                Less => true,
979                Equal => self.end == RangeEnd::Included,
980                Greater => false,
981            },
982        )
983    }
984
985    #[inline]
986    pub fn overlaps(&self, other: &Self, tcx: TyCtxt<'tcx>) -> Option<bool> {
987        use Ordering::*;
988        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);
989        // For performance, it's important to only do the second comparison if necessary.
990        Some(
991            match other.lo.compare_with(self.hi, self.ty, tcx)? {
992                Less => true,
993                Equal => self.end == RangeEnd::Included,
994                Greater => false,
995            } && match self.lo.compare_with(other.hi, self.ty, tcx)? {
996                Less => true,
997                Equal => other.end == RangeEnd::Included,
998                Greater => false,
999            },
1000        )
1001    }
1002}
1003
1004impl<'tcx> fmt::Display for PatRange<'tcx> {
1005    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1006        if let &PatRangeBoundary::Finite(valtree) = &self.lo {
1007            let value = ty::Value { ty: self.ty, valtree };
1008            f.write_fmt(format_args!("{0}", value))write!(f, "{value}")?;
1009        }
1010        if let &PatRangeBoundary::Finite(valtree) = &self.hi {
1011            f.write_fmt(format_args!("{0}", self.end))write!(f, "{}", self.end)?;
1012            let value = ty::Value { ty: self.ty, valtree };
1013            f.write_fmt(format_args!("{0}", value))write!(f, "{value}")?;
1014        } else {
1015            // `0..` is parsed as an inclusive range, we must display it correctly.
1016            f.write_fmt(format_args!(".."))write!(f, "..")?;
1017        }
1018        Ok(())
1019    }
1020}
1021
1022/// A (possibly open) boundary of a range pattern.
1023/// If present, the const must be of a numeric type.
1024#[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> ::rustc_data_structures::stable_hasher::StableHash for
            PatRangeBoundary<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    PatRangeBoundary::Finite(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    PatRangeBoundary::NegInfinity => {}
                    PatRangeBoundary::PosInfinity => {}
                }
            }
        }
    };StableHash, 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)]
1025pub enum PatRangeBoundary<'tcx> {
1026    /// The type of this valtree is stored in the surrounding `PatRange`.
1027    Finite(ty::ValTree<'tcx>),
1028    NegInfinity,
1029    PosInfinity,
1030}
1031
1032impl<'tcx> PatRangeBoundary<'tcx> {
1033    #[inline]
1034    pub fn is_finite(self) -> bool {
1035        #[allow(non_exhaustive_omitted_patterns)] match self {
    Self::Finite(..) => true,
    _ => false,
}matches!(self, Self::Finite(..))
1036    }
1037    #[inline]
1038    pub fn as_finite(self) -> Option<ty::ValTree<'tcx>> {
1039        match self {
1040            Self::Finite(value) => Some(value),
1041            Self::NegInfinity | Self::PosInfinity => None,
1042        }
1043    }
1044    pub fn to_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> u128 {
1045        match self {
1046            Self::Finite(value) => value.to_leaf().to_bits_unchecked(),
1047            Self::NegInfinity => {
1048                // Unwrap is ok because the type is known to be numeric.
1049                ty.numeric_min_and_max_as_bits(tcx).unwrap().0
1050            }
1051            Self::PosInfinity => {
1052                // Unwrap is ok because the type is known to be numeric.
1053                ty.numeric_min_and_max_as_bits(tcx).unwrap().1
1054            }
1055        }
1056    }
1057
1058    x;#[instrument(skip(tcx), level = "debug", ret)]
1059    pub fn compare_with(self, other: Self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Ordering> {
1060        use PatRangeBoundary::*;
1061        match (self, other) {
1062            // When comparing with infinities, we must remember that `0u8..` and `0u8..=255`
1063            // describe the same range. These two shortcuts are ok, but for the rest we must check
1064            // bit values.
1065            (PosInfinity, PosInfinity) => return Some(Ordering::Equal),
1066            (NegInfinity, NegInfinity) => return Some(Ordering::Equal),
1067
1068            // This code is hot when compiling matches with many ranges. So we
1069            // special-case extraction of evaluated scalars for speed, for types where
1070            // we can do scalar comparisons. E.g. `unicode-normalization` has
1071            // many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared
1072            // in this way.
1073            (Finite(a), Finite(b)) if matches!(ty.kind(), ty::Int(_) | ty::Uint(_) | ty::Char) => {
1074                if let (Some(a), Some(b)) = (a.try_to_leaf(), b.try_to_leaf()) {
1075                    let sz = ty.primitive_size(tcx);
1076                    let cmp = match ty.kind() {
1077                        ty::Uint(_) | ty::Char => a.to_uint(sz).cmp(&b.to_uint(sz)),
1078                        ty::Int(_) => a.to_int(sz).cmp(&b.to_int(sz)),
1079                        _ => unreachable!(),
1080                    };
1081                    return Some(cmp);
1082                }
1083            }
1084            _ => {}
1085        }
1086
1087        let a = self.to_bits(ty, tcx);
1088        let b = other.to_bits(ty, tcx);
1089
1090        match ty.kind() {
1091            ty::Float(ty::FloatTy::F16) => {
1092                use rustc_apfloat::Float;
1093                let a = rustc_apfloat::ieee::Half::from_bits(a);
1094                let b = rustc_apfloat::ieee::Half::from_bits(b);
1095                a.partial_cmp(&b)
1096            }
1097            ty::Float(ty::FloatTy::F32) => {
1098                use rustc_apfloat::Float;
1099                let a = rustc_apfloat::ieee::Single::from_bits(a);
1100                let b = rustc_apfloat::ieee::Single::from_bits(b);
1101                a.partial_cmp(&b)
1102            }
1103            ty::Float(ty::FloatTy::F64) => {
1104                use rustc_apfloat::Float;
1105                let a = rustc_apfloat::ieee::Double::from_bits(a);
1106                let b = rustc_apfloat::ieee::Double::from_bits(b);
1107                a.partial_cmp(&b)
1108            }
1109            ty::Float(ty::FloatTy::F128) => {
1110                use rustc_apfloat::Float;
1111                let a = rustc_apfloat::ieee::Quad::from_bits(a);
1112                let b = rustc_apfloat::ieee::Quad::from_bits(b);
1113                a.partial_cmp(&b)
1114            }
1115            ty::Int(ity) => {
1116                let size = rustc_abi::Integer::from_int_ty(&tcx, *ity).size();
1117                let a = size.sign_extend(a) as i128;
1118                let b = size.sign_extend(b) as i128;
1119                Some(a.cmp(&b))
1120            }
1121            ty::Uint(_) | ty::Char => Some(a.cmp(&b)),
1122            _ => bug!(),
1123        }
1124    }
1125}
1126
1127// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
1128#[cfg(target_pointer_width = "64")]
1129mod size_asserts {
1130    use rustc_data_structures::static_assert_size;
1131
1132    use super::*;
1133    // tidy-alphabetical-start
1134    const _: [(); 48] = [(); ::std::mem::size_of::<Block>()];static_assert_size!(Block, 48);
1135    const _: [(); 64] = [(); ::std::mem::size_of::<Expr<'_>>()];static_assert_size!(Expr<'_>, 64);
1136    const _: [(); 40] = [(); ::std::mem::size_of::<ExprKind<'_>>()];static_assert_size!(ExprKind<'_>, 40);
1137    const _: [(); 72] = [(); ::std::mem::size_of::<Pat<'_>>()];static_assert_size!(Pat<'_>, 72);
1138    const _: [(); 48] = [(); ::std::mem::size_of::<PatKind<'_>>()];static_assert_size!(PatKind<'_>, 48);
1139    const _: [(); 48] = [(); ::std::mem::size_of::<Stmt<'_>>()];static_assert_size!(Stmt<'_>, 48);
1140    const _: [(); 48] = [(); ::std::mem::size_of::<StmtKind<'_>>()];static_assert_size!(StmtKind<'_>, 48);
1141    // tidy-alphabetical-end
1142}