Skip to main content

rustc_middle/ty/
typeck_results.rs

1use std::collections::hash_map::Entry;
2use std::hash::Hash;
3use std::iter;
4
5use rustc_abi::{FieldIdx, VariantIdx};
6use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
7use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet};
8use rustc_errors::ErrorGuaranteed;
9use rustc_hir::def::{DefKind, Res};
10use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
11use rustc_hir::{
12    self as hir, BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
13    OwnerId,
14};
15use rustc_index::IndexVec;
16use rustc_macros::{Lift, StableHash, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
17use rustc_session::Session;
18use rustc_span::Span;
19
20use crate::hir::place::Place as HirPlace;
21use crate::infer::canonical::Canonical;
22use crate::mir::FakeReadCause;
23use crate::thir::DerefPatBorrowMode;
24use crate::traits::ObligationCause;
25use crate::ty::{
26    self, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, GenericArgKind, GenericArgs,
27    GenericArgsRef, Ty, UserArgs, tls,
28};
29
30#[derive(const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for TypeckResults<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    TypeckResults {
                        hir_owner: ref __binding_0,
                        type_dependent_defs: ref __binding_1,
                        splatted_defs: ref __binding_2,
                        field_indices: ref __binding_3,
                        node_types: ref __binding_4,
                        node_args: ref __binding_5,
                        user_provided_types: ref __binding_6,
                        user_provided_sigs: ref __binding_7,
                        adjustments: ref __binding_8,
                        pat_binding_modes: ref __binding_9,
                        rust_2024_migration_desugared_pats: ref __binding_10,
                        pat_adjustments: ref __binding_11,
                        skipped_ref_pats: ref __binding_12,
                        closure_kind_origins: ref __binding_13,
                        liberated_fn_sigs: ref __binding_14,
                        fru_field_types: ref __binding_15,
                        coercion_casts: ref __binding_16,
                        used_trait_imports: ref __binding_17,
                        tainted_by_errors: ref __binding_18,
                        hidden_types: ref __binding_19,
                        closure_min_captures: ref __binding_20,
                        closure_fake_reads: ref __binding_21,
                        coroutine_stalled_predicates: ref __binding_22,
                        potentially_region_dependent_goals: ref __binding_23,
                        closure_size_eval: ref __binding_24,
                        transmutes_to_check: ref __binding_25,
                        offloads_to_check: ref __binding_26,
                        offset_of_data: ref __binding_27 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_5,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_6,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_7,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_8,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_9,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_10,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_11,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_12,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_13,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_14,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_15,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_16,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_17,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_18,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_19,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_20,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_21,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_22,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_23,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_24,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_25,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_26,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_27,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for TypeckResults<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                TypeckResults {
                    hir_owner: ::rustc_serialize::Decodable::decode(__decoder),
                    type_dependent_defs: ::rustc_serialize::Decodable::decode(__decoder),
                    splatted_defs: ::rustc_serialize::Decodable::decode(__decoder),
                    field_indices: ::rustc_serialize::Decodable::decode(__decoder),
                    node_types: ::rustc_serialize::Decodable::decode(__decoder),
                    node_args: ::rustc_serialize::Decodable::decode(__decoder),
                    user_provided_types: ::rustc_serialize::Decodable::decode(__decoder),
                    user_provided_sigs: ::rustc_serialize::Decodable::decode(__decoder),
                    adjustments: ::rustc_serialize::Decodable::decode(__decoder),
                    pat_binding_modes: ::rustc_serialize::Decodable::decode(__decoder),
                    rust_2024_migration_desugared_pats: ::rustc_serialize::Decodable::decode(__decoder),
                    pat_adjustments: ::rustc_serialize::Decodable::decode(__decoder),
                    skipped_ref_pats: ::rustc_serialize::Decodable::decode(__decoder),
                    closure_kind_origins: ::rustc_serialize::Decodable::decode(__decoder),
                    liberated_fn_sigs: ::rustc_serialize::Decodable::decode(__decoder),
                    fru_field_types: ::rustc_serialize::Decodable::decode(__decoder),
                    coercion_casts: ::rustc_serialize::Decodable::decode(__decoder),
                    used_trait_imports: ::rustc_serialize::Decodable::decode(__decoder),
                    tainted_by_errors: ::rustc_serialize::Decodable::decode(__decoder),
                    hidden_types: ::rustc_serialize::Decodable::decode(__decoder),
                    closure_min_captures: ::rustc_serialize::Decodable::decode(__decoder),
                    closure_fake_reads: ::rustc_serialize::Decodable::decode(__decoder),
                    coroutine_stalled_predicates: ::rustc_serialize::Decodable::decode(__decoder),
                    potentially_region_dependent_goals: ::rustc_serialize::Decodable::decode(__decoder),
                    closure_size_eval: ::rustc_serialize::Decodable::decode(__decoder),
                    transmutes_to_check: ::rustc_serialize::Decodable::decode(__decoder),
                    offloads_to_check: ::rustc_serialize::Decodable::decode(__decoder),
                    offset_of_data: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for TypeckResults<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["hir_owner", "type_dependent_defs", "splatted_defs",
                        "field_indices", "node_types", "node_args",
                        "user_provided_types", "user_provided_sigs", "adjustments",
                        "pat_binding_modes", "rust_2024_migration_desugared_pats",
                        "pat_adjustments", "skipped_ref_pats",
                        "closure_kind_origins", "liberated_fn_sigs",
                        "fru_field_types", "coercion_casts", "used_trait_imports",
                        "tainted_by_errors", "hidden_types", "closure_min_captures",
                        "closure_fake_reads", "coroutine_stalled_predicates",
                        "potentially_region_dependent_goals", "closure_size_eval",
                        "transmutes_to_check", "offloads_to_check",
                        "offset_of_data"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.hir_owner, &self.type_dependent_defs, &self.splatted_defs,
                        &self.field_indices, &self.node_types, &self.node_args,
                        &self.user_provided_types, &self.user_provided_sigs,
                        &self.adjustments, &self.pat_binding_modes,
                        &self.rust_2024_migration_desugared_pats,
                        &self.pat_adjustments, &self.skipped_ref_pats,
                        &self.closure_kind_origins, &self.liberated_fn_sigs,
                        &self.fru_field_types, &self.coercion_casts,
                        &self.used_trait_imports, &self.tainted_by_errors,
                        &self.hidden_types, &self.closure_min_captures,
                        &self.closure_fake_reads,
                        &self.coroutine_stalled_predicates,
                        &self.potentially_region_dependent_goals,
                        &self.closure_size_eval, &self.transmutes_to_check,
                        &self.offloads_to_check, &&self.offset_of_data];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "TypeckResults",
            names, values)
    }
}Debug, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            TypeckResults<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    TypeckResults {
                        hir_owner: ref __binding_0,
                        type_dependent_defs: ref __binding_1,
                        splatted_defs: ref __binding_2,
                        field_indices: ref __binding_3,
                        node_types: ref __binding_4,
                        node_args: ref __binding_5,
                        user_provided_types: ref __binding_6,
                        user_provided_sigs: ref __binding_7,
                        adjustments: ref __binding_8,
                        pat_binding_modes: ref __binding_9,
                        rust_2024_migration_desugared_pats: ref __binding_10,
                        pat_adjustments: ref __binding_11,
                        skipped_ref_pats: ref __binding_12,
                        closure_kind_origins: ref __binding_13,
                        liberated_fn_sigs: ref __binding_14,
                        fru_field_types: ref __binding_15,
                        coercion_casts: ref __binding_16,
                        used_trait_imports: ref __binding_17,
                        tainted_by_errors: ref __binding_18,
                        hidden_types: ref __binding_19,
                        closure_min_captures: ref __binding_20,
                        closure_fake_reads: ref __binding_21,
                        coroutine_stalled_predicates: ref __binding_22,
                        potentially_region_dependent_goals: ref __binding_23,
                        closure_size_eval: ref __binding_24,
                        transmutes_to_check: ref __binding_25,
                        offloads_to_check: ref __binding_26,
                        offset_of_data: ref __binding_27 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                        { __binding_6.stable_hash(__hcx, __hasher); }
                        { __binding_7.stable_hash(__hcx, __hasher); }
                        { __binding_8.stable_hash(__hcx, __hasher); }
                        { __binding_9.stable_hash(__hcx, __hasher); }
                        { __binding_10.stable_hash(__hcx, __hasher); }
                        { __binding_11.stable_hash(__hcx, __hasher); }
                        { __binding_12.stable_hash(__hcx, __hasher); }
                        { __binding_13.stable_hash(__hcx, __hasher); }
                        { __binding_14.stable_hash(__hcx, __hasher); }
                        { __binding_15.stable_hash(__hcx, __hasher); }
                        { __binding_16.stable_hash(__hcx, __hasher); }
                        { __binding_17.stable_hash(__hcx, __hasher); }
                        { __binding_18.stable_hash(__hcx, __hasher); }
                        { __binding_19.stable_hash(__hcx, __hasher); }
                        { __binding_20.stable_hash(__hcx, __hasher); }
                        { __binding_21.stable_hash(__hcx, __hasher); }
                        { __binding_22.stable_hash(__hcx, __hasher); }
                        { __binding_23.stable_hash(__hcx, __hasher); }
                        { __binding_24.stable_hash(__hcx, __hasher); }
                        { __binding_25.stable_hash(__hcx, __hasher); }
                        { __binding_26.stable_hash(__hcx, __hasher); }
                        { __binding_27.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
31pub struct TypeckResults<'tcx> {
32    /// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
33    pub hir_owner: OwnerId,
34
35    /// Resolved definitions for `<T>::X` associated paths and
36    /// method calls, including those of overloaded operators.
37    type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>>,
38
39    /// Resolved definitions for splatted function calls.
40    splatted_defs: ItemLocalMap<Result<SplattedDef<'tcx>, ErrorGuaranteed>>,
41
42    /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
43    /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
44    /// about the field you also need definition of the variant to which the field
45    /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
46    field_indices: ItemLocalMap<FieldIdx>,
47
48    /// Stores the types for various nodes in the AST. Note that this table
49    /// is not guaranteed to be populated outside inference. See
50    /// typeck::check::fn_ctxt for details.
51    node_types: ItemLocalMap<Ty<'tcx>>,
52
53    /// Stores the type parameters which were instantiated to obtain the type
54    /// of this node. This only applies to nodes that refer to entities
55    /// parameterized by type parameters, such as generic fns, types, or
56    /// other items.
57    node_args: ItemLocalMap<GenericArgsRef<'tcx>>,
58
59    /// This will either store the canonicalized types provided by the user
60    /// or the generic parameters that the user explicitly gave (if any) attached
61    /// to `id`. These will not include any inferred values. The canonical form
62    /// is used to capture things like `_` or other unspecified values.
63    ///
64    /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
65    /// canonical generic parameters would include only `for<X> { Vec<X> }`.
66    ///
67    /// See also `AscribeUserType` statement in MIR.
68    user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
69
70    /// Stores the canonicalized types provided by the user. See also
71    /// `AscribeUserType` statement in MIR.
72    pub user_provided_sigs: LocalDefIdMap<CanonicalPolyFnSig<'tcx>>,
73
74    adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
75
76    /// Stores the actual binding mode for all instances of [`BindingMode`].
77    pat_binding_modes: ItemLocalMap<BindingMode>,
78
79    /// Top-level patterns incompatible with Rust 2024's match ergonomics. These will be translated
80    /// to a form valid in all Editions, either as a lint diagnostic or hard error.
81    rust_2024_migration_desugared_pats: ItemLocalMap<Rust2024IncompatiblePatInfo>,
82
83    /// Stores the types which were implicitly dereferenced in pattern binding modes or deref
84    /// patterns for later usage in THIR lowering. For example,
85    ///
86    /// ```
87    /// match &&Some(5i32) {
88    ///     Some(n) => {},
89    ///     _ => {},
90    /// }
91    /// ```
92    /// leads to a `vec![&&Option<i32>, &Option<i32>]` and
93    ///
94    /// ```
95    /// #![feature(deref_patterns)]
96    /// match &Box::new(Some(5i32)) {
97    ///     Some(n) => {},
98    ///     _ => {},
99    /// }
100    /// ```
101    /// leads to a `vec![&Box<Option<i32>>, Box<Option<i32>>]`. Empty vectors are not stored.
102    ///
103    /// See:
104    /// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
105    pat_adjustments: ItemLocalMap<Vec<ty::adjustment::PatAdjustment<'tcx>>>,
106
107    /// Set of reference patterns that match against a match-ergonomics inserted reference
108    /// (as opposed to against a reference in the scrutinee type).
109    skipped_ref_pats: ItemLocalSet,
110
111    /// Records the reasons that we picked the kind of each closure;
112    /// not all closures are present in the map.
113    closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
114
115    /// For each fn, records the "liberated" types of its arguments
116    /// and return type. Liberated means that all bound regions
117    /// (including late-bound regions) are replaced with free
118    /// equivalents. This table is not used in codegen (since regions
119    /// are erased there) and hence is not serialized to metadata.
120    ///
121    /// This table also contains the "revealed" values for any `impl Trait`
122    /// that appear in the signature and whose values are being inferred
123    /// by this function.
124    ///
125    /// # Example
126    ///
127    /// ```rust
128    /// # use std::fmt::Debug;
129    /// fn foo(x: &u32) -> impl Debug { *x }
130    /// ```
131    ///
132    /// The function signature here would be:
133    ///
134    /// ```ignore (illustrative)
135    /// for<'a> fn(&'a u32) -> Foo
136    /// ```
137    ///
138    /// where `Foo` is an opaque type created for this function.
139    ///
140    ///
141    /// The *liberated* form of this would be
142    ///
143    /// ```ignore (illustrative)
144    /// fn(&'a u32) -> u32
145    /// ```
146    ///
147    /// Note that `'a` is not bound (it would be an `ReLateParam`) and
148    /// that the `Foo` opaque type is replaced by its hidden type.
149    liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
150
151    /// For each FRU expression, record the normalized types of the fields
152    /// of the struct - this is needed because it is non-trivial to
153    /// normalize while preserving regions. This table is used only in
154    /// MIR construction and hence is not serialized to metadata.
155    fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
156
157    /// For every coercion cast we add the HIR node ID of the cast
158    /// expression to this set.
159    coercion_casts: ItemLocalSet,
160
161    /// Set of trait imports actually used in the method resolution.
162    /// This is used for warning unused imports.
163    pub used_trait_imports: UnordSet<LocalDefId>,
164
165    /// If any errors occurred while type-checking this body,
166    /// this field will be set to `Some(ErrorGuaranteed)`.
167    pub tainted_by_errors: Option<ErrorGuaranteed>,
168
169    /// All the opaque types that have hidden types set by this function.
170    /// We also store the type here, so that the compiler can use it as a hint
171    /// for figuring out hidden types, even if they are only set in dead code
172    /// (which doesn't show up in MIR).
173    pub hidden_types: FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
174
175    /// Tracks the minimum captures required for a closure;
176    /// see `MinCaptureInformationMap` for more details.
177    pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
178
179    /// Tracks the fake reads required for a closure and the reason for the fake read.
180    /// When performing pattern matching for closures, there are times we don't end up
181    /// reading places that are mentioned in a closure (because of _ patterns). However,
182    /// to ensure the places are initialized, we introduce fake reads.
183    /// Consider these two examples:
184    /// ```ignore (discriminant matching with only wildcard arm)
185    /// let x: u8;
186    /// let c = || match x { _ => () };
187    /// ```
188    /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't
189    /// want to capture it. However, we do still want an error here, because `x` should have
190    /// to be initialized at the point where c is created. Therefore, we add a "fake read"
191    /// instead.
192    /// ```ignore (destructured assignments)
193    /// let c = || {
194    ///     let (t1, t2) = t;
195    /// }
196    /// ```
197    /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but
198    /// we never capture `t`. This becomes an issue when we build MIR as we require
199    /// information on `t` in order to create place `t.0` and `t.1`. We can solve this
200    /// issue by fake reading `t`.
201    pub closure_fake_reads: LocalDefIdMap<Vec<(HirPlace<'tcx>, FakeReadCause, HirId)>>,
202
203    /// Stores the predicates that apply on coroutine witness types.
204    /// formatting modified file tests/ui/coroutine/retain-resume-ref.rs
205    pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
206
207    /// Goals proven during HIR typeck which may be potentially region dependent.
208    ///
209    /// Borrowck *uniquifies* regions which may cause these goal to be ambiguous in MIR
210    /// type check. We ICE if goals fail in borrowck to detect bugs during MIR building or
211    /// missed checks in HIR typeck. To avoid ICE due to region dependence we store all
212    /// goals which may be region dependent and reprove them in case borrowck encounters
213    /// an error.
214    pub potentially_region_dependent_goals:
215        FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
216
217    /// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
218    /// on closure size.
219    pub closure_size_eval: LocalDefIdMap<ClosureSizeProfileData<'tcx>>,
220
221    /// Stores the types involved in calls to `transmute` intrinsic. These are meant to be checked
222    /// outside of typeck and borrowck to avoid cycles with opaque types and coroutine layout
223    /// computation.
224    pub transmutes_to_check: Vec<(Ty<'tcx>, Ty<'tcx>, HirId)>,
225
226    /// Stores the types involved in calls to `offload` intrinsic.
227    pub offloads_to_check: Vec<(Ty<'tcx>, Ty<'tcx>, Ty<'tcx>, HirId)>,
228
229    /// Container types and field indices of `offset_of!` expressions
230    offset_of_data: ItemLocalMap<Vec<(Ty<'tcx>, VariantIdx, FieldIdx)>>,
231}
232
233impl<'tcx> TypeckResults<'tcx> {
234    pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
235        TypeckResults {
236            hir_owner,
237            type_dependent_defs: Default::default(),
238            splatted_defs: Default::default(),
239            field_indices: Default::default(),
240            user_provided_types: Default::default(),
241            user_provided_sigs: Default::default(),
242            node_types: Default::default(),
243            node_args: Default::default(),
244            adjustments: Default::default(),
245            pat_binding_modes: Default::default(),
246            pat_adjustments: Default::default(),
247            rust_2024_migration_desugared_pats: Default::default(),
248            skipped_ref_pats: Default::default(),
249            closure_kind_origins: Default::default(),
250            liberated_fn_sigs: Default::default(),
251            fru_field_types: Default::default(),
252            coercion_casts: Default::default(),
253            used_trait_imports: Default::default(),
254            tainted_by_errors: None,
255            hidden_types: Default::default(),
256            closure_min_captures: Default::default(),
257            closure_fake_reads: Default::default(),
258            coroutine_stalled_predicates: Default::default(),
259            potentially_region_dependent_goals: Default::default(),
260            closure_size_eval: Default::default(),
261            transmutes_to_check: Default::default(),
262            offloads_to_check: Default::default(),
263            offset_of_data: Default::default(),
264        }
265    }
266
267    /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
268    pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: HirId) -> Res {
269        match *qpath {
270            hir::QPath::Resolved(_, path) => path.res,
271            hir::QPath::TypeRelative(..) => self
272                .type_dependent_def(id)
273                .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
274        }
275    }
276
277    pub fn type_dependent_defs(
278        &self,
279    ) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
280        LocalTableInContext { hir_owner: self.hir_owner, data: &self.type_dependent_defs }
281    }
282
283    pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
284        validate_hir_id_for_typeck_results(self.hir_owner, id);
285        self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
286    }
287
288    pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
289        self.type_dependent_def(id).map(|(_, def_id)| def_id)
290    }
291
292    pub fn type_dependent_defs_mut(
293        &mut self,
294    ) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
295        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
296    }
297
298    pub fn splatted_defs(
299        &self,
300    ) -> LocalTableInContext<'_, Result<SplattedDef<'tcx>, ErrorGuaranteed>> {
301        LocalTableInContext { hir_owner: self.hir_owner, data: &self.splatted_defs }
302    }
303
304    pub fn splatted_def(&self, id: HirId) -> Option<SplattedDef<'tcx>> {
305        validate_hir_id_for_typeck_results(self.hir_owner, id);
306        self.splatted_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
307    }
308
309    pub fn splatted_defs_mut(
310        &mut self,
311    ) -> LocalTableInContextMut<'_, Result<SplattedDef<'tcx>, ErrorGuaranteed>> {
312        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.splatted_defs }
313    }
314
315    pub fn field_indices(&self) -> LocalTableInContext<'_, FieldIdx> {
316        LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
317    }
318
319    pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, FieldIdx> {
320        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
321    }
322
323    pub fn field_index(&self, id: HirId) -> FieldIdx {
324        self.field_indices().get(id).cloned().expect("no index for a field")
325    }
326
327    pub fn opt_field_index(&self, id: HirId) -> Option<FieldIdx> {
328        self.field_indices().get(id).cloned()
329    }
330
331    pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
332        LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
333    }
334
335    pub fn user_provided_types_mut(
336        &mut self,
337    ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> {
338        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.user_provided_types }
339    }
340
341    pub fn node_types(&self) -> LocalTableInContext<'_, Ty<'tcx>> {
342        LocalTableInContext { hir_owner: self.hir_owner, data: &self.node_types }
343    }
344
345    pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
346        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
347    }
348
349    pub fn node_type(&self, id: HirId) -> Ty<'tcx> {
350        self.node_type_opt(id).unwrap_or_else(|| {
351            crate::util::bug::bug_fmt(format_args!("node_type: no type for node {0}",
        tls::with(|tcx| tcx.hir_id_to_string(id))))bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir_id_to_string(id)))
352        })
353    }
354
355    pub fn node_type_opt(&self, id: HirId) -> Option<Ty<'tcx>> {
356        validate_hir_id_for_typeck_results(self.hir_owner, id);
357        self.node_types.get(&id.local_id).cloned()
358    }
359
360    pub fn node_args_mut(&mut self) -> LocalTableInContextMut<'_, GenericArgsRef<'tcx>> {
361        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_args }
362    }
363
364    pub fn node_args(&self, id: HirId) -> GenericArgsRef<'tcx> {
365        validate_hir_id_for_typeck_results(self.hir_owner, id);
366        self.node_args.get(&id.local_id).cloned().unwrap_or_else(|| GenericArgs::empty())
367    }
368
369    pub fn node_args_opt(&self, id: HirId) -> Option<GenericArgsRef<'tcx>> {
370        validate_hir_id_for_typeck_results(self.hir_owner, id);
371        self.node_args.get(&id.local_id).cloned()
372    }
373
374    /// Returns the type of a pattern as a monotype. Like [`expr_ty`], this function
375    /// doesn't provide type parameter args.
376    ///
377    /// [`expr_ty`]: TypeckResults::expr_ty
378    pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
379        self.node_type(pat.hir_id)
380    }
381
382    /// Returns the type of an expression as a monotype.
383    ///
384    /// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
385    /// some cases, we insert `Adjustment` annotations such as auto-deref or
386    /// auto-ref. The type returned by this function does not consider such
387    /// adjustments. See [`Self::expr_ty_adjusted`] instead.
388    ///
389    /// NB (2): This type doesn't provide type parameter args; e.g., if you
390    /// ask for the type of `id` in `id(3)`, it will return `fn(&isize) -> isize`
391    /// instead of `fn(ty) -> T with T = isize`.
392    pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
393        self.node_type(expr.hir_id)
394    }
395
396    pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
397        self.node_type_opt(expr.hir_id)
398    }
399
400    pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
401        LocalTableInContext { hir_owner: self.hir_owner, data: &self.adjustments }
402    }
403
404    pub fn adjustments_mut(
405        &mut self,
406    ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
407        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.adjustments }
408    }
409
410    pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
411        validate_hir_id_for_typeck_results(self.hir_owner, expr.hir_id);
412        self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
413    }
414
415    /// Returns the type of `expr`, considering any `Adjustment`
416    /// entry recorded for that expression.
417    pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
418        self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
419    }
420
421    pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
422        self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
423    }
424
425    pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
426        // Only paths and method calls/overloaded operators have
427        // entries in type_dependent_defs, ignore the former here.
428        if let hir::ExprKind::Path(_) = expr.kind {
429            return false;
430        }
431
432        #[allow(non_exhaustive_omitted_patterns)] match self.type_dependent_defs().get(expr.hir_id)
    {
    Some(Ok((DefKind::AssocFn, _))) => true,
    _ => false,
}matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
433    }
434
435    pub fn is_splatted_call(&self, expr: &hir::Expr<'_>) -> bool {
436        #[allow(non_exhaustive_omitted_patterns)] match self.splatted_defs().get(expr.hir_id)
    {
    Some(Ok(_)) => true,
    _ => false,
}matches!(self.splatted_defs().get(expr.hir_id), Some(Ok(_)))
437    }
438
439    /// Returns the computed binding mode for a `PatKind::Binding` pattern
440    /// (after match ergonomics adjustments).
441    pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> BindingMode {
442        self.pat_binding_modes().get(id).copied().unwrap_or_else(|| {
443            s.dcx().span_bug(sp, "missing binding mode");
444        })
445    }
446
447    pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
448        LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
449    }
450
451    pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
452        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
453    }
454
455    pub fn pat_adjustments(
456        &self,
457    ) -> LocalTableInContext<'_, Vec<ty::adjustment::PatAdjustment<'tcx>>> {
458        LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments }
459    }
460
461    pub fn pat_adjustments_mut(
462        &mut self,
463    ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::PatAdjustment<'tcx>>> {
464        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
465    }
466
467    pub fn rust_2024_migration_desugared_pats(
468        &self,
469    ) -> LocalTableInContext<'_, Rust2024IncompatiblePatInfo> {
470        LocalTableInContext {
471            hir_owner: self.hir_owner,
472            data: &self.rust_2024_migration_desugared_pats,
473        }
474    }
475
476    pub fn rust_2024_migration_desugared_pats_mut(
477        &mut self,
478    ) -> LocalTableInContextMut<'_, Rust2024IncompatiblePatInfo> {
479        LocalTableInContextMut {
480            hir_owner: self.hir_owner,
481            data: &mut self.rust_2024_migration_desugared_pats,
482        }
483    }
484
485    pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> {
486        LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats }
487    }
488
489    pub fn skipped_ref_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
490        LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.skipped_ref_pats }
491    }
492
493    /// Does the pattern recursively contain a `ref mut` binding in it?
494    ///
495    /// This is used to determined whether a `deref` pattern should emit a `Deref`
496    /// or `DerefMut` call for its pattern scrutinee.
497    ///
498    /// This is computed from the typeck results since we want to make
499    /// sure to apply any match-ergonomics adjustments, which we cannot
500    /// determine from the HIR alone.
501    pub fn pat_has_ref_mut_binding(&self, pat: &hir::Pat<'_>) -> bool {
502        let mut has_ref_mut = false;
503        pat.walk(|pat| {
504            if let hir::PatKind::Binding(_, id, _, _) = pat.kind
505                && let Some(BindingMode(ByRef::Yes(_, Mutability::Mut), _)) =
506                    self.pat_binding_modes().get(id)
507            {
508                has_ref_mut = true;
509                // No need to continue recursing
510                false
511            } else {
512                true
513            }
514        });
515        has_ref_mut
516    }
517
518    /// How should a deref pattern find the place for its inner pattern to match on?
519    ///
520    /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner
521    /// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`.
522    /// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee;
523    /// in this case, we return `DerefPatBorrowMode::Box`.
524    pub fn deref_pat_borrow_mode(
525        &self,
526        pointer_ty: Ty<'_>,
527        inner: &hir::Pat<'_>,
528    ) -> DerefPatBorrowMode {
529        if pointer_ty.is_box() {
530            DerefPatBorrowMode::Box
531        } else {
532            let mutability =
533                if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };
534            DerefPatBorrowMode::Borrow(mutability)
535        }
536    }
537
538    /// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured
539    /// by the closure.
540    pub fn closure_min_captures_flattened(
541        &self,
542        closure_def_id: LocalDefId,
543    ) -> impl Iterator<Item = &ty::CapturedPlace<'tcx>> {
544        self.closure_min_captures
545            .get(&closure_def_id)
546            .map(|closure_min_captures| closure_min_captures.values())
547            .into_flat_iter()
548            .flatten()
549    }
550
551    pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
552        LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
553    }
554
555    pub fn closure_kind_origins_mut(
556        &mut self,
557    ) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
558        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
559    }
560
561    pub fn liberated_fn_sigs(&self) -> LocalTableInContext<'_, ty::FnSig<'tcx>> {
562        LocalTableInContext { hir_owner: self.hir_owner, data: &self.liberated_fn_sigs }
563    }
564
565    pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<'_, ty::FnSig<'tcx>> {
566        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.liberated_fn_sigs }
567    }
568
569    pub fn fru_field_types(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
570        LocalTableInContext { hir_owner: self.hir_owner, data: &self.fru_field_types }
571    }
572
573    pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
574        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types }
575    }
576
577    pub fn is_coercion_cast(&self, hir_id: HirId) -> bool {
578        validate_hir_id_for_typeck_results(self.hir_owner, hir_id);
579        self.coercion_casts.contains(&hir_id.local_id)
580    }
581
582    pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
583        self.coercion_casts.insert(id);
584    }
585
586    pub fn coercion_casts(&self) -> &ItemLocalSet {
587        &self.coercion_casts
588    }
589
590    pub fn offset_of_data(&self) -> LocalTableInContext<'_, Vec<(Ty<'tcx>, VariantIdx, FieldIdx)>> {
591        LocalTableInContext { hir_owner: self.hir_owner, data: &self.offset_of_data }
592    }
593
594    pub fn offset_of_data_mut(
595        &mut self,
596    ) -> LocalTableInContextMut<'_, Vec<(Ty<'tcx>, VariantIdx, FieldIdx)>> {
597        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.offset_of_data }
598    }
599}
600
601/// A resolved splatted function call.
602#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for SplattedDef<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            SplattedDef::FnDef {
                def_id: __self_0, arg_index: __self_1, arg_count: __self_2 }
                =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "FnDef",
                    "def_id", __self_0, "arg_index", __self_1, "arg_count",
                    &__self_2),
            SplattedDef::FnPtr {
                fn_ptr_type: __self_0,
                arg_index: __self_1,
                arg_count: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "FnPtr",
                    "fn_ptr_type", __self_0, "arg_index", __self_1, "arg_count",
                    &__self_2),
        }
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for SplattedDef<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for SplattedDef<'tcx> {
    #[inline]
    fn clone(&self) -> SplattedDef<'tcx> {
        let _: ::core::clone::AssertParamIsClone<DefId>;
        let _: ::core::clone::AssertParamIsClone<u16>;
        let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for SplattedDef<'tcx> {
    #[inline]
    fn eq(&self, other: &SplattedDef<'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) {
                (SplattedDef::FnDef {
                    def_id: __self_0, arg_index: __self_1, arg_count: __self_2
                    }, SplattedDef::FnDef {
                    def_id: __arg1_0, arg_index: __arg1_1, arg_count: __arg1_2
                    }) =>
                    __self_1 == __arg1_1 && __self_2 == __arg1_2 &&
                        __self_0 == __arg1_0,
                (SplattedDef::FnPtr {
                    fn_ptr_type: __self_0,
                    arg_index: __self_1,
                    arg_count: __self_2 }, SplattedDef::FnPtr {
                    fn_ptr_type: __arg1_0,
                    arg_index: __arg1_1,
                    arg_count: __arg1_2 }) =>
                    __self_1 == __arg1_1 && __self_2 == __arg1_2 &&
                        __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for SplattedDef<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<DefId>;
        let _: ::core::cmp::AssertParamIsEq<u16>;
        let _: ::core::cmp::AssertParamIsEq<Ty<'tcx>>;
    }
}Eq, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            SplattedDef<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    SplattedDef::FnDef {
                        def_id: ref __binding_0,
                        arg_index: ref __binding_1,
                        arg_count: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    SplattedDef::FnPtr {
                        fn_ptr_type: ref __binding_0,
                        arg_index: ref __binding_1,
                        arg_count: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for SplattedDef<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        SplattedDef::FnDef {
                            def_id: ref __binding_0,
                            arg_index: ref __binding_1,
                            arg_count: ref __binding_2 } => {
                            0usize
                        }
                        SplattedDef::FnPtr {
                            fn_ptr_type: ref __binding_0,
                            arg_index: ref __binding_1,
                            arg_count: ref __binding_2 } => {
                            1usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    SplattedDef::FnDef {
                        def_id: ref __binding_0,
                        arg_index: ref __binding_1,
                        arg_count: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                    SplattedDef::FnPtr {
                        fn_ptr_type: ref __binding_0,
                        arg_index: ref __binding_1,
                        arg_count: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for SplattedDef<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        SplattedDef::FnDef {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                            arg_index: ::rustc_serialize::Decodable::decode(__decoder),
                            arg_count: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    1usize => {
                        SplattedDef::FnPtr {
                            fn_ptr_type: ::rustc_serialize::Decodable::decode(__decoder),
                            arg_index: ::rustc_serialize::Decodable::decode(__decoder),
                            arg_count: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SplattedDef`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable)]
603pub enum SplattedDef<'tcx> {
604    /// A resolved FnDef call.
605    FnDef {
606        /// The DefId of the FnDef (used to look up its type).
607        def_id: DefId,
608
609        /// The index of the first argument in the callee's splatted tuple, and the index of the
610        /// splatted tuple argument in the caller.
611        arg_index: u16,
612
613        /// The number of arguments in the splatted tuple.
614        arg_count: u16,
615    },
616
617    /// A resolved FnPtr Call.
618    FnPtr {
619        /// The resolved type of the FnPtr.
620        fn_ptr_type: Ty<'tcx>,
621
622        /// The index of the first argument in the callee's splatted tuple, and the index of the
623        /// splatted tuple argument in the caller.
624        arg_index: u16,
625
626        /// The number of arguments in the splatted tuple.
627        arg_count: u16,
628    },
629}
630
631impl<'tcx> SplattedDef<'tcx> {
632    pub fn def_id(&self) -> Option<DefId> {
633        match self {
634            SplattedDef::FnDef { def_id, .. } => Some(*def_id),
635            SplattedDef::FnPtr { .. } => None,
636        }
637    }
638
639    pub fn fn_ptr_type(&self) -> Option<Ty<'tcx>> {
640        match self {
641            SplattedDef::FnDef { .. } => None,
642            SplattedDef::FnPtr { fn_ptr_type, .. } => Some(*fn_ptr_type),
643        }
644    }
645
646    pub fn arg_index(&self) -> u16 {
647        match self {
648            SplattedDef::FnDef { arg_index, .. } => *arg_index,
649            SplattedDef::FnPtr { arg_index, .. } => *arg_index,
650        }
651    }
652
653    pub fn arg_count(&self) -> u16 {
654        match self {
655            SplattedDef::FnDef { arg_count, .. } => *arg_count,
656            SplattedDef::FnPtr { arg_count, .. } => *arg_count,
657        }
658    }
659}
660
661/// Validate that the given HirId (respectively its `local_id` part) can be
662/// safely used as a key in the maps of a TypeckResults. For that to be
663/// the case, the HirId must have the same `owner` as all the other IDs in
664/// this table (signified by `hir_owner`). Otherwise the HirId
665/// would be in a different frame of reference and using its `local_id`
666/// would result in lookup errors, or worse, in silently wrong data being
667/// stored/returned.
668#[inline]
669fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) {
670    if hir_id.owner != hir_owner {
671        invalid_hir_id_for_typeck_results(hir_owner, hir_id);
672    }
673}
674
675#[cold]
676#[inline(never)]
677fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) {
678    ty::tls::with(|tcx| {
679        crate::util::bug::bug_fmt(format_args!("node {0} cannot be placed in TypeckResults with hir_owner {1:?}",
        tcx.hir_id_to_string(hir_id), hir_owner))bug!(
680            "node {} cannot be placed in TypeckResults with hir_owner {:?}",
681            tcx.hir_id_to_string(hir_id),
682            hir_owner
683        )
684    });
685}
686
687pub struct LocalTableInContext<'a, V> {
688    hir_owner: OwnerId,
689    data: &'a ItemLocalMap<V>,
690}
691
692impl<'a, V> LocalTableInContext<'a, V> {
693    pub fn contains_key(&self, id: HirId) -> bool {
694        validate_hir_id_for_typeck_results(self.hir_owner, id);
695        self.data.contains_key(&id.local_id)
696    }
697
698    pub fn get(&self, id: HirId) -> Option<&'a V> {
699        validate_hir_id_for_typeck_results(self.hir_owner, id);
700        self.data.get(&id.local_id)
701    }
702
703    pub fn items(
704        &self,
705    ) -> UnordItems<(hir::ItemLocalId, &'a V), impl Iterator<Item = (hir::ItemLocalId, &'a V)>>
706    {
707        self.data.items().map(|(id, value)| (*id, value))
708    }
709
710    pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
711        self.data.items().map(|(&k, v)| (k, v)).into_sorted_stable_ord_by_key(|(k, _)| k)
712    }
713}
714
715impl<'a, V> ::std::ops::Index<HirId> for LocalTableInContext<'a, V> {
716    type Output = V;
717
718    fn index(&self, key: HirId) -> &V {
719        self.get(key).unwrap_or_else(|| {
720            crate::util::bug::bug_fmt(format_args!("LocalTableInContext({0:?}): key {1:?} not found",
        self.hir_owner, key))bug!("LocalTableInContext({:?}): key {:?} not found", self.hir_owner, key)
721        })
722    }
723}
724
725pub struct LocalTableInContextMut<'a, V> {
726    hir_owner: OwnerId,
727    data: &'a mut ItemLocalMap<V>,
728}
729
730impl<'a, V> LocalTableInContextMut<'a, V> {
731    pub fn get_mut(&mut self, id: HirId) -> Option<&mut V> {
732        validate_hir_id_for_typeck_results(self.hir_owner, id);
733        self.data.get_mut(&id.local_id)
734    }
735
736    pub fn get(&mut self, id: HirId) -> Option<&V> {
737        validate_hir_id_for_typeck_results(self.hir_owner, id);
738        self.data.get(&id.local_id)
739    }
740
741    pub fn entry(&mut self, id: HirId) -> Entry<'_, hir::ItemLocalId, V> {
742        validate_hir_id_for_typeck_results(self.hir_owner, id);
743        self.data.entry(id.local_id)
744    }
745
746    pub fn insert(&mut self, id: HirId, val: V) -> Option<V> {
747        validate_hir_id_for_typeck_results(self.hir_owner, id);
748        self.data.insert(id.local_id, val)
749    }
750
751    pub fn remove(&mut self, id: HirId) -> Option<V> {
752        validate_hir_id_for_typeck_results(self.hir_owner, id);
753        self.data.remove(&id.local_id)
754    }
755
756    pub fn extend(&mut self, items: UnordItems<(HirId, V), impl Iterator<Item = (HirId, V)>>) {
757        self.data.extend_unord(items.map(|(id, value)| {
758            validate_hir_id_for_typeck_results(self.hir_owner, id);
759            (id.local_id, value)
760        }))
761    }
762}
763
764#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for LocalSetInContext<'a> {
    #[inline]
    fn clone(&self) -> LocalSetInContext<'a> {
        let _: ::core::clone::AssertParamIsClone<OwnerId>;
        let _: ::core::clone::AssertParamIsClone<&'a ItemLocalSet>;
        *self
    }
}Clone, #[automatically_derived]
impl<'a> ::core::marker::Copy for LocalSetInContext<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::fmt::Debug for LocalSetInContext<'a> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "LocalSetInContext", "hir_owner", &self.hir_owner, "data",
            &&self.data)
    }
}Debug)]
765pub struct LocalSetInContext<'a> {
766    hir_owner: OwnerId,
767    data: &'a ItemLocalSet,
768}
769
770impl<'a> LocalSetInContext<'a> {
771    pub fn is_empty(&self) -> bool {
772        self.data.is_empty()
773    }
774
775    pub fn contains(&self, id: hir::HirId) -> bool {
776        validate_hir_id_for_typeck_results(self.hir_owner, id);
777        self.data.contains(&id.local_id)
778    }
779}
780
781#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for LocalSetInContextMut<'a> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "LocalSetInContextMut", "hir_owner", &self.hir_owner, "data",
            &&self.data)
    }
}Debug)]
782pub struct LocalSetInContextMut<'a> {
783    hir_owner: OwnerId,
784    data: &'a mut ItemLocalSet,
785}
786
787impl<'a> LocalSetInContextMut<'a> {
788    pub fn is_empty(&self) -> bool {
789        self.data.is_empty()
790    }
791
792    pub fn contains(&self, id: hir::HirId) -> bool {
793        validate_hir_id_for_typeck_results(self.hir_owner, id);
794        self.data.contains(&id.local_id)
795    }
796    pub fn insert(&mut self, id: hir::HirId) -> bool {
797        validate_hir_id_for_typeck_results(self.hir_owner, id);
798        self.data.insert(id.local_id)
799    }
800
801    pub fn remove(&mut self, id: hir::HirId) -> bool {
802        validate_hir_id_for_typeck_results(self.hir_owner, id);
803        self.data.remove(&id.local_id)
804    }
805}
806
807impl ::std::fmt::Debug for UserTypeAnnotationIndex {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("UserType({0})", self.as_u32()))
    }
}rustc_index::newtype_index! {
808    #[stable_hash]
809    #[encodable]
810    #[debug_format = "UserType({})"]
811    pub struct UserTypeAnnotationIndex {
812        const START_INDEX = 0;
813    }
814}
815
816/// Mapping of type annotation indices to canonical user type annotations.
817pub type CanonicalUserTypeAnnotations<'tcx> =
818    IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
819
820#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for CanonicalUserTypeAnnotation<'tcx> {
    #[inline]
    fn clone(&self) -> CanonicalUserTypeAnnotation<'tcx> {
        CanonicalUserTypeAnnotation {
            user_ty: ::core::clone::Clone::clone(&self.user_ty),
            span: ::core::clone::Clone::clone(&self.span),
            inferred_ty: ::core::clone::Clone::clone(&self.inferred_ty),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for CanonicalUserTypeAnnotation<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "CanonicalUserTypeAnnotation", "user_ty", &self.user_ty, "span",
            &self.span, "inferred_ty", &&self.inferred_ty)
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for
            CanonicalUserTypeAnnotation<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    CanonicalUserTypeAnnotation {
                        user_ty: ref __binding_0,
                        span: ref __binding_1,
                        inferred_ty: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for
            CanonicalUserTypeAnnotation<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                CanonicalUserTypeAnnotation {
                    user_ty: ::rustc_serialize::Decodable::decode(__decoder),
                    span: ::rustc_serialize::Decodable::decode(__decoder),
                    inferred_ty: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            CanonicalUserTypeAnnotation<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    CanonicalUserTypeAnnotation {
                        user_ty: ref __binding_0,
                        span: ref __binding_1,
                        inferred_ty: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for CanonicalUserTypeAnnotation<'tcx> {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        CanonicalUserTypeAnnotation {
                            user_ty: __binding_0,
                            span: __binding_1,
                            inferred_ty: __binding_2 } => {
                            CanonicalUserTypeAnnotation {
                                user_ty: __binding_0,
                                span: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                inferred_ty: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    CanonicalUserTypeAnnotation {
                        user_ty: __binding_0,
                        span: __binding_1,
                        inferred_ty: __binding_2 } => {
                        CanonicalUserTypeAnnotation {
                            user_ty: __binding_0,
                            span: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            inferred_ty: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for CanonicalUserTypeAnnotation<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    CanonicalUserTypeAnnotation {
                        span: ref __binding_1, inferred_ty: ref __binding_2, .. } =>
                        {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable)]
821pub struct CanonicalUserTypeAnnotation<'tcx> {
822    #[type_foldable(identity)]
823    #[type_visitable(ignore)]
824    pub user_ty: Box<CanonicalUserType<'tcx>>,
825    pub span: Span,
826    pub inferred_ty: Ty<'tcx>,
827}
828
829/// Canonical user type annotation.
830pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
831
832#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for UserType<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for UserType<'tcx> {
    #[inline]
    fn clone(&self) -> UserType<'tcx> {
        let _: ::core::clone::AssertParamIsClone<UserTypeKind<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<ty::Clauses<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for UserType<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "UserType",
            "kind", &self.kind, "bounds", &&self.bounds)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for UserType<'tcx> {
    #[inline]
    fn eq(&self, other: &UserType<'tcx>) -> bool {
        self.kind == other.kind && self.bounds == other.bounds
    }
}PartialEq, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for UserType<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    UserType { kind: ref __binding_0, bounds: ref __binding_1 }
                        => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for UserType<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                UserType {
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                    bounds: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable)]
833#[derive(#[automatically_derived]
impl<'tcx> ::core::cmp::Eq for UserType<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<UserTypeKind<'tcx>>;
        let _: ::core::cmp::AssertParamIsEq<ty::Clauses<'tcx>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for UserType<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.kind, state);
        ::core::hash::Hash::hash(&self.bounds, state)
    }
}Hash, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            UserType<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    UserType { kind: ref __binding_0, bounds: ref __binding_1 }
                        => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserType<'tcx> {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        UserType { kind: __binding_0, bounds: __binding_1 } => {
                            UserType {
                                kind: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                bounds: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    UserType { kind: __binding_0, bounds: __binding_1 } => {
                        UserType {
                            kind: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            bounds: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserType<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    UserType { kind: ref __binding_0, bounds: 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)]
834pub struct UserType<'tcx> {
835    pub kind: UserTypeKind<'tcx>,
836    pub bounds: ty::Clauses<'tcx>,
837}
838
839impl<'tcx> UserType<'tcx> {
840    pub fn new(kind: UserTypeKind<'tcx>) -> UserType<'tcx> {
841        UserType { kind, bounds: ty::ListWithCachedTypeInfo::empty() }
842    }
843
844    /// A user type annotation with additional bounds that need to be enforced.
845    /// These bounds are lowered from `impl Trait` in bindings.
846    pub fn new_with_bounds(kind: UserTypeKind<'tcx>, bounds: ty::Clauses<'tcx>) -> UserType<'tcx> {
847        UserType { kind, bounds }
848    }
849}
850
851/// A user-given type annotation attached to a constant. These arise
852/// from constants that are named via paths, like `Foo::<A>::new` and
853/// so forth.
854#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for UserTypeKind<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for UserTypeKind<'tcx> {
    #[inline]
    fn clone(&self) -> UserTypeKind<'tcx> {
        let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<DefId>;
        let _: ::core::clone::AssertParamIsClone<UserArgs<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for UserTypeKind<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            UserTypeKind::Ty(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Ty",
                    &__self_0),
            UserTypeKind::TypeOf(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "TypeOf",
                    __self_0, &__self_1),
        }
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for UserTypeKind<'tcx> {
    #[inline]
    fn eq(&self, other: &UserTypeKind<'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) {
                (UserTypeKind::Ty(__self_0), UserTypeKind::Ty(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (UserTypeKind::TypeOf(__self_0, __self_1),
                    UserTypeKind::TypeOf(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for UserTypeKind<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        UserTypeKind::Ty(ref __binding_0) => { 0usize }
                        UserTypeKind::TypeOf(ref __binding_0, ref __binding_1) => {
                            1usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    UserTypeKind::Ty(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    UserTypeKind::TypeOf(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for UserTypeKind<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        UserTypeKind::Ty(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        UserTypeKind::TypeOf(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `UserTypeKind`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable)]
855#[derive(#[automatically_derived]
impl<'tcx> ::core::cmp::Eq for UserTypeKind<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Ty<'tcx>>;
        let _: ::core::cmp::AssertParamIsEq<DefId>;
        let _: ::core::cmp::AssertParamIsEq<UserArgs<'tcx>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for UserTypeKind<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            UserTypeKind::Ty(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            UserTypeKind::TypeOf(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
        }
    }
}Hash, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            UserTypeKind<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    UserTypeKind::Ty(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    UserTypeKind::TypeOf(ref __binding_0, ref __binding_1) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserTypeKind<'tcx> {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        UserTypeKind::Ty(__binding_0) => {
                            UserTypeKind::Ty(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        UserTypeKind::TypeOf(__binding_0, __binding_1) => {
                            UserTypeKind::TypeOf(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?)
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    UserTypeKind::Ty(__binding_0) => {
                        UserTypeKind::Ty(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    UserTypeKind::TypeOf(__binding_0, __binding_1) => {
                        UserTypeKind::TypeOf(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserTypeKind<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    UserTypeKind::Ty(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);
                                }
                            }
                        }
                    }
                    UserTypeKind::TypeOf(ref __binding_0, ref __binding_1) => {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable, const _: () =
    {
        impl<'tcx, '__lifted>
            ::rustc_middle::ty::Lift<::rustc_middle::ty::TyCtxt<'__lifted>>
            for UserTypeKind<'tcx> {
            type Lifted = UserTypeKind<'__lifted>;
            fn lift_to_interner(self,
                __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>)
                -> UserTypeKind<'__lifted> {
                match self {
                    UserTypeKind::Ty(__binding_0) => {
                        UserTypeKind::Ty(__tcx.lift(__binding_0))
                    }
                    UserTypeKind::TypeOf(__binding_0, __binding_1) => {
                        UserTypeKind::TypeOf(__tcx.lift(__binding_0),
                            __tcx.lift(__binding_1))
                    }
                }
            }
        }
    };Lift)]
856pub enum UserTypeKind<'tcx> {
857    Ty(Ty<'tcx>),
858
859    /// The canonical type is the result of `type_of(def_id)` with the
860    /// given generic parameters applied.
861    TypeOf(DefId, UserArgs<'tcx>),
862}
863
864pub trait IsIdentity {
865    fn is_identity(&self) -> bool;
866}
867
868impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
869    /// Returns `true` if this represents the generic parameters of the form `[?0, ?1, ?2]`,
870    /// i.e., each thing is mapped to a canonical variable with the same index.
871    fn is_identity(&self) -> bool {
872        if !self.value.bounds.is_empty() {
873            return false;
874        }
875
876        match self.value.kind {
877            UserTypeKind::Ty(_) => false,
878            UserTypeKind::TypeOf(_, user_args) => {
879                if user_args.user_self_ty.is_some() {
880                    return false;
881                }
882
883                iter::zip(user_args.args, BoundVar::ZERO..).all(|(arg, cvar)| {
884                    match arg.kind() {
885                        GenericArgKind::Type(ty) => match ty.kind() {
886                            ty::Bound(debruijn, b) => {
887                                // We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters.
888                                {
    match (&*debruijn, &ty::BoundVarIndexKind::Canonical) {
        (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);
            }
        }
    }
};assert_eq!(*debruijn, ty::BoundVarIndexKind::Canonical);
889                                cvar == b.var
890                            }
891                            _ => false,
892                        },
893
894                        GenericArgKind::Lifetime(r) => match r.kind() {
895                            ty::ReBound(debruijn, b) => {
896                                // We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters.
897                                {
    match (&debruijn, &ty::BoundVarIndexKind::Canonical) {
        (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);
            }
        }
    }
};assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical);
898                                cvar == b.var
899                            }
900                            _ => false,
901                        },
902
903                        GenericArgKind::Const(ct) => match ct.kind() {
904                            ty::ConstKind::Bound(debruijn, b) => {
905                                // We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters.
906                                {
    match (&debruijn, &ty::BoundVarIndexKind::Canonical) {
        (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);
            }
        }
    }
};assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical);
907                                cvar == b.var
908                            }
909                            _ => false,
910                        },
911                    }
912                })
913            }
914        }
915    }
916}
917
918impl<'tcx> std::fmt::Display for UserType<'tcx> {
919    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
920        self.kind.fmt(f)?;
921        for b in self.bounds {
922            f.write_fmt(format_args!(" + "))write!(f, " + ")?;
923            b.fmt(f)?;
924        }
925        Ok(())
926    }
927}
928
929/// Information on a pattern incompatible with Rust 2024, for use by the error/migration diagnostic
930/// emitted during THIR construction.
931#[derive(const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for Rust2024IncompatiblePatInfo
            {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Rust2024IncompatiblePatInfo {
                        primary_labels: ref __binding_0,
                        bad_mut_modifiers: ref __binding_1,
                        bad_ref_modifiers: ref __binding_2,
                        bad_ref_pats: ref __binding_3,
                        suggest_eliding_modes: ref __binding_4 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for Rust2024IncompatiblePatInfo
            {
            fn decode(__decoder: &mut __D) -> Self {
                Rust2024IncompatiblePatInfo {
                    primary_labels: ::rustc_serialize::Decodable::decode(__decoder),
                    bad_mut_modifiers: ::rustc_serialize::Decodable::decode(__decoder),
                    bad_ref_modifiers: ::rustc_serialize::Decodable::decode(__decoder),
                    bad_ref_pats: ::rustc_serialize::Decodable::decode(__decoder),
                    suggest_eliding_modes: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::fmt::Debug for Rust2024IncompatiblePatInfo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "Rust2024IncompatiblePatInfo", "primary_labels",
            &self.primary_labels, "bad_mut_modifiers",
            &self.bad_mut_modifiers, "bad_ref_modifiers",
            &self.bad_ref_modifiers, "bad_ref_pats", &self.bad_ref_pats,
            "suggest_eliding_modes", &&self.suggest_eliding_modes)
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            Rust2024IncompatiblePatInfo {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    Rust2024IncompatiblePatInfo {
                        primary_labels: ref __binding_0,
                        bad_mut_modifiers: ref __binding_1,
                        bad_ref_modifiers: ref __binding_2,
                        bad_ref_pats: ref __binding_3,
                        suggest_eliding_modes: ref __binding_4 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
932pub struct Rust2024IncompatiblePatInfo {
933    /// Labeled spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024.
934    pub primary_labels: Vec<(Span, String)>,
935    /// Whether any `mut` binding modifiers occur under a non-`move` default binding mode.
936    pub bad_mut_modifiers: bool,
937    /// Whether any `ref`/`ref mut` binding modifiers occur under a non-`move` default binding mode.
938    pub bad_ref_modifiers: bool,
939    /// Whether any `&` or `&mut` patterns occur under a non-`move` default binding mode.
940    pub bad_ref_pats: bool,
941    /// If `true`, we can give a simpler suggestion solely by eliding explicit binding modifiers.
942    pub suggest_eliding_modes: bool,
943}