Skip to main content

rustc_middle/
thir.rs

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