Skip to main content

rustc_type_ir/solve/
mod.rs

1pub mod inspect;
2
3use std::hash::Hash;
4
5use derive_where::derive_where;
6#[cfg(feature = "nightly")]
7use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash, StableHash_NoContext};
8use rustc_type_ir_macros::{
9    GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
10};
11
12use crate::lang_items::SolverTraitLangItem;
13use crate::search_graph::PathKind;
14use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
15
16pub type CanonicalInput<I, T = <I as Interner>::Predicate> =
17    ty::CanonicalQueryInput<I, QueryInput<I, T>>;
18pub type CanonicalResponse<I> = Canonical<I, Response<I>>;
19/// The result of evaluating a canonical query.
20///
21/// FIXME: We use a different type than the existing canonical queries. This is because
22/// we need to add a `Certainty` for `overflow` and may want to restructure this code without
23/// having to worry about changes to currently used code. Once we've made progress on this
24/// solver, merge the two responses again.
25pub type QueryResult<I> = Result<CanonicalResponse<I>, NoSolution>;
26
27#[derive(#[automatically_derived]
impl ::core::marker::Copy for NoSolution { }Copy, #[automatically_derived]
impl ::core::clone::Clone for NoSolution {
    #[inline]
    fn clone(&self) -> NoSolution { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for NoSolution {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "NoSolution")
    }
}Debug, #[automatically_derived]
impl ::core::hash::Hash for NoSolution {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for NoSolution {
    #[inline]
    fn eq(&self, other: &NoSolution) -> bool { true }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NoSolution {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq)]
28#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for NoSolution
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self { NoSolution => {} }
            }
        }
    };StableHash))]
29pub struct NoSolution;
30
31/// A goal is a statement, i.e. `predicate`, we want to prove
32/// given some assumptions, i.e. `param_env`.
33///
34/// Most of the time the `param_env` contains the `where`-bounds of the function
35/// we're currently typechecking while the `predicate` is some trait bound.
36#[automatically_derived]
impl<I: Interner, P> ::core::marker::Copy for Goal<I, P> where I: Interner,
    P: Copy {
}#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, P)]
37#[derive_where(Copy; I: Interner, P: Copy)]
38#[derive(const _: () =
    {
        impl<I: Interner, P> ::rustc_type_ir::TypeVisitable<I> for Goal<I, P>
            where I: Interner, I::ParamEnv: ::rustc_type_ir::TypeVisitable<I>,
            P: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Goal {
                        param_env: ref __binding_0, predicate: ref __binding_1 } =>
                        {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner, P> ::rustc_type_ir::TypeFoldable<I> for Goal<I, P>
            where I: Interner, I::ParamEnv: ::rustc_type_ir::TypeFoldable<I>,
            P: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        Goal { param_env: __binding_0, predicate: __binding_1 } => {
                            Goal {
                                param_env: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                predicate: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    Goal { param_env: __binding_0, predicate: __binding_1 } => {
                        Goal {
                            param_env: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            predicate: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, P, J> ::rustc_type_ir::lift::Lift<J> for Goal<I, P>
            where I: Interner, J: Interner,
            I::ParamEnv: ::rustc_type_ir::lift::Lift<J, Lifted = J::ParamEnv>,
            P: ::rustc_type_ir::lift::Lift<J, Lifted = P> {
            type Lifted = Goal<J, P>;
            fn lift_to_interner(self, interner: J) -> Self::Lifted {
                match self {
                    Goal { param_env: __binding_0, predicate: __binding_1 } => {
                        Goal {
                            param_env: __binding_0.lift_to_interner(interner),
                            predicate: __binding_1.lift_to_interner(interner),
                        }
                    }
                }
            }
        }
    };Lift_Generic)]
39#[cfg_attr(
40    feature = "nightly",
41    derive(const _: () =
    {
        impl<I: Interner, P, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for Goal<I, P> where
            I::ParamEnv: ::rustc_serialize::Decodable<__D>,
            P: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                Goal {
                    param_env: ::rustc_serialize::Decodable::decode(__decoder),
                    predicate: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, P, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for Goal<I, P> where
            I::ParamEnv: ::rustc_serialize::Encodable<__E>,
            P: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Goal {
                        param_env: ref __binding_0, predicate: ref __binding_1 } =>
                        {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, P>
            ::rustc_data_structures::stable_hasher::StableHash for Goal<I, P>
            where
            I::ParamEnv: ::rustc_data_structures::stable_hasher::StableHash,
            P: ::rustc_data_structures::stable_hasher::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Goal {
                        param_env: ref __binding_0, predicate: ref __binding_1 } =>
                        {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
42)]
43pub struct Goal<I: Interner, P> {
44    pub param_env: I::ParamEnv,
45    pub predicate: P,
46}
47
48impl<I: Interner, P: Eq> Eq for Goal<I, P> {}
49
50impl<I: Interner, P> Goal<I, P> {
51    pub fn new(cx: I, param_env: I::ParamEnv, predicate: impl Upcast<I, P>) -> Goal<I, P> {
52        Goal { param_env, predicate: predicate.upcast(cx) }
53    }
54
55    /// Updates the goal to one with a different `predicate` but the same `param_env`.
56    pub fn with<Q>(self, cx: I, predicate: impl Upcast<I, Q>) -> Goal<I, Q> {
57        Goal { param_env: self.param_env, predicate: predicate.upcast(cx) }
58    }
59}
60
61/// Why a specific goal has to be proven.
62///
63/// This is necessary as we treat nested goals different depending on
64/// their source. This is used to decide whether a cycle is coinductive.
65/// See the documentation of `EvalCtxt::step_kind_for_source` for more details
66/// about this.
67///
68/// It is also used by proof tree visitors, e.g. for diagnostics purposes.
69#[derive(#[automatically_derived]
impl ::core::marker::Copy for GoalSource { }Copy, #[automatically_derived]
impl ::core::clone::Clone for GoalSource {
    #[inline]
    fn clone(&self) -> GoalSource {
        let _: ::core::clone::AssertParamIsClone<PathKind>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for GoalSource {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            GoalSource::Misc => ::core::fmt::Formatter::write_str(f, "Misc"),
            GoalSource::TypeRelating =>
                ::core::fmt::Formatter::write_str(f, "TypeRelating"),
            GoalSource::ImplWhereBound =>
                ::core::fmt::Formatter::write_str(f, "ImplWhereBound"),
            GoalSource::AliasBoundConstCondition =>
                ::core::fmt::Formatter::write_str(f,
                    "AliasBoundConstCondition"),
            GoalSource::AliasWellFormed =>
                ::core::fmt::Formatter::write_str(f, "AliasWellFormed"),
            GoalSource::NormalizeGoal(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "NormalizeGoal", &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for GoalSource {
    #[inline]
    fn eq(&self, other: &GoalSource) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (GoalSource::NormalizeGoal(__self_0),
                    GoalSource::NormalizeGoal(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for GoalSource {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<PathKind>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for GoalSource {
    #[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 {
            GoalSource::NormalizeGoal(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash)]
70#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for GoalSource
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    GoalSource::Misc => {}
                    GoalSource::TypeRelating => {}
                    GoalSource::ImplWhereBound => {}
                    GoalSource::AliasBoundConstCondition => {}
                    GoalSource::AliasWellFormed => {}
                    GoalSource::NormalizeGoal(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
71pub enum GoalSource {
72    Misc,
73    /// A nested goal required to prove that types are equal/subtypes.
74    /// This is always an unproductive step.
75    ///
76    /// This is also used for all `NormalizesTo` goals as we they are used
77    /// to relate types in `AliasRelate`.
78    TypeRelating,
79    /// We're proving a where-bound of an impl.
80    ImplWhereBound,
81    /// Const conditions that need to hold for `[const]` alias bounds to hold.
82    AliasBoundConstCondition,
83    /// Predicate required for an alias projection to be well-formed.
84    /// This is used in three places:
85    /// 1. projecting to an opaque whose hidden type is already registered in
86    ///    the opaque type storage,
87    /// 2. for rigid projections's trait goal,
88    /// 3. for GAT where clauses.
89    AliasWellFormed,
90    /// In case normalizing aliases in nested goals cycles, eagerly normalizing these
91    /// aliases in the context of the parent may incorrectly change the cycle kind.
92    /// Normalizing aliases in goals therefore tracks the original path kind for this
93    /// nested goal. See the comment of the `ReplaceAliasWithInfer` visitor for more
94    /// details.
95    NormalizeGoal(PathKind),
96}
97
98#[automatically_derived]
impl<I: Interner, P> ::core::marker::Copy for QueryInput<I, P> where
    I: Interner, Goal<I, P>: Copy {
}#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal<I, P>)]
99#[derive_where(Copy; I: Interner, Goal<I, P>: Copy)]
100#[derive(const _: () =
    {
        impl<I: Interner, P> ::rustc_type_ir::TypeVisitable<I> for
            QueryInput<I, P> where I: Interner,
            Goal<I, P>: ::rustc_type_ir::TypeVisitable<I>,
            I::PredefinedOpaques: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    QueryInput {
                        goal: ref __binding_0,
                        predefined_opaques_in_body: ref __binding_1 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner, P> ::rustc_type_ir::TypeFoldable<I> for
            QueryInput<I, P> where I: Interner,
            Goal<I, P>: ::rustc_type_ir::TypeFoldable<I>,
            I::PredefinedOpaques: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        QueryInput {
                            goal: __binding_0, predefined_opaques_in_body: __binding_1 }
                            => {
                            QueryInput {
                                goal: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                predefined_opaques_in_body: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    QueryInput {
                        goal: __binding_0, predefined_opaques_in_body: __binding_1 }
                        => {
                        QueryInput {
                            goal: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            predefined_opaques_in_body: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic)]
101#[cfg_attr(
102    feature = "nightly",
103    derive(const _: () =
    {
        impl<I: Interner, P, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for QueryInput<I, P> where
            Goal<I, P>: ::rustc_serialize::Decodable<__D>,
            I::PredefinedOpaques: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                QueryInput {
                    goal: ::rustc_serialize::Decodable::decode(__decoder),
                    predefined_opaques_in_body: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, P, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for QueryInput<I, P> where
            Goal<I, P>: ::rustc_serialize::Encodable<__E>,
            I::PredefinedOpaques: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    QueryInput {
                        goal: ref __binding_0,
                        predefined_opaques_in_body: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, P>
            ::rustc_data_structures::stable_hasher::StableHash for
            QueryInput<I, P> where
            Goal<I, P>: ::rustc_data_structures::stable_hasher::StableHash,
            I::PredefinedOpaques: ::rustc_data_structures::stable_hasher::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    QueryInput {
                        goal: ref __binding_0,
                        predefined_opaques_in_body: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
104)]
105pub struct QueryInput<I: Interner, P> {
106    pub goal: Goal<I, P>,
107    pub predefined_opaques_in_body: I::PredefinedOpaques,
108}
109
110impl<I: Interner, P: Eq> Eq for QueryInput<I, P> {}
111
112/// Which trait candidates should be preferred over other candidates? By default, prefer where
113/// bounds over alias bounds. For marker traits, prefer alias bounds over where bounds.
114#[derive(#[automatically_derived]
impl ::core::clone::Clone for CandidatePreferenceMode {
    #[inline]
    fn clone(&self) -> CandidatePreferenceMode { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CandidatePreferenceMode { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for CandidatePreferenceMode {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                CandidatePreferenceMode::Default => "Default",
                CandidatePreferenceMode::Marker => "Marker",
            })
    }
}Debug)]
115pub enum CandidatePreferenceMode {
116    /// Prefers where bounds over alias bounds
117    Default,
118    /// Prefers alias bounds over where bounds
119    Marker,
120}
121
122impl CandidatePreferenceMode {
123    /// Given `trait_def_id`, which candidate preference mode should be used?
124    pub fn compute<I: Interner>(cx: I, trait_id: I::TraitId) -> CandidatePreferenceMode {
125        let is_sizedness_or_auto_or_default_goal = cx.is_sizedness_trait(trait_id)
126            || cx.trait_is_auto(trait_id)
127            || cx.is_default_trait(trait_id);
128        if is_sizedness_or_auto_or_default_goal {
129            CandidatePreferenceMode::Marker
130        } else {
131            CandidatePreferenceMode::Default
132        }
133    }
134}
135
136/// Possible ways the given goal can be proven.
137#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for CandidateSource<I> where I: Interner
    {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            CandidateSource::Impl(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "Impl");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CandidateSource::BuiltinImpl(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "BuiltinImpl");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CandidateSource::ParamEnv(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "ParamEnv");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CandidateSource::AliasBound(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "AliasBound");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CandidateSource::CoherenceUnknowable =>
                ::core::fmt::Formatter::write_str(__f, "CoherenceUnknowable"),
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
138pub enum CandidateSource<I: Interner> {
139    /// A user written impl.
140    ///
141    /// ## Examples
142    ///
143    /// ```rust
144    /// fn main() {
145    ///     let x: Vec<u32> = Vec::new();
146    ///     // This uses the impl from the standard library to prove `Vec<T>: Clone`.
147    ///     let y = x.clone();
148    /// }
149    /// ```
150    Impl(I::ImplId),
151    /// A builtin impl generated by the compiler. When adding a new special
152    /// trait, try to use actual impls whenever possible. Builtin impls should
153    /// only be used in cases where the impl cannot be manually be written.
154    ///
155    /// Notable examples are auto traits, `Sized`, and `DiscriminantKind`.
156    /// For a list of all traits with builtin impls, check out the
157    /// `EvalCtxt::assemble_builtin_impl_candidates` method.
158    BuiltinImpl(BuiltinImplSource),
159    /// An assumption from the environment. Stores a [`ParamEnvSource`], since we
160    /// prefer non-global param-env candidates in candidate assembly.
161    ///
162    /// ## Examples
163    ///
164    /// ```rust
165    /// fn is_clone<T: Clone>(x: T) -> (T, T) {
166    ///     // This uses the assumption `T: Clone` from the `where`-bounds
167    ///     // to prove `T: Clone`.
168    ///     (x.clone(), x)
169    /// }
170    /// ```
171    ParamEnv(ParamEnvSource),
172    /// If the self type is an alias type, e.g. an opaque type or a projection,
173    /// we know the bounds on that alias to hold even without knowing its concrete
174    /// underlying type.
175    ///
176    /// More precisely this candidate is using the `n-th` bound in the `item_bounds` of
177    /// the self type.
178    ///
179    /// ## Examples
180    ///
181    /// ```rust
182    /// trait Trait {
183    ///     type Assoc: Clone;
184    /// }
185    ///
186    /// fn foo<T: Trait>(x: <T as Trait>::Assoc) {
187    ///     // We prove `<T as Trait>::Assoc` by looking at the bounds on `Assoc` in
188    ///     // in the trait definition.
189    ///     let _y = x.clone();
190    /// }
191    /// ```
192    AliasBound(AliasBoundKind),
193    /// A candidate that is registered only during coherence to represent some
194    /// yet-unknown impl that could be produced downstream without violating orphan
195    /// rules.
196    // FIXME: Merge this with the forced ambiguity candidates, so those don't use `Misc`.
197    CoherenceUnknowable,
198}
199
200impl<I: Interner> Eq for CandidateSource<I> {}
201
202#[derive(#[automatically_derived]
impl ::core::clone::Clone for ParamEnvSource {
    #[inline]
    fn clone(&self) -> ParamEnvSource { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ParamEnvSource { }Copy, #[automatically_derived]
impl ::core::hash::Hash for ParamEnvSource {
    #[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)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for ParamEnvSource {
    #[inline]
    fn eq(&self, other: &ParamEnvSource) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ParamEnvSource {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for ParamEnvSource {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                ParamEnvSource::NonGlobal => "NonGlobal",
                ParamEnvSource::Global => "Global",
            })
    }
}Debug)]
203pub enum ParamEnvSource {
204    /// Preferred eagerly.
205    NonGlobal,
206    // Not considered unless there are non-global param-env candidates too.
207    Global,
208}
209
210#[derive(#[automatically_derived]
impl ::core::clone::Clone for AliasBoundKind {
    #[inline]
    fn clone(&self) -> AliasBoundKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AliasBoundKind { }Copy, #[automatically_derived]
impl ::core::hash::Hash for AliasBoundKind {
    #[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)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for AliasBoundKind {
    #[inline]
    fn eq(&self, other: &AliasBoundKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AliasBoundKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for AliasBoundKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AliasBoundKind::SelfBounds => "SelfBounds",
                AliasBoundKind::NonSelfBounds => "NonSelfBounds",
            })
    }
}Debug)]
211#[derive(const _: () =
    {
        impl<I> ::rustc_type_ir::TypeVisitable<I> for AliasBoundKind where
            I: Interner {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    AliasBoundKind::SelfBounds => {}
                    AliasBoundKind::NonSelfBounds => {}
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I> ::rustc_type_ir::TypeFoldable<I> for AliasBoundKind where
            I: Interner {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        AliasBoundKind::SelfBounds => { AliasBoundKind::SelfBounds }
                        AliasBoundKind::NonSelfBounds => {
                            AliasBoundKind::NonSelfBounds
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    AliasBoundKind::SelfBounds => { AliasBoundKind::SelfBounds }
                    AliasBoundKind::NonSelfBounds => {
                        AliasBoundKind::NonSelfBounds
                    }
                }
            }
        }
    };TypeFoldable_Generic)]
212pub enum AliasBoundKind {
213    /// Alias bound from the self type of a projection
214    SelfBounds,
215    // Alias bound having recursed on the self type of a projection
216    NonSelfBounds,
217}
218
219#[derive(#[automatically_derived]
impl ::core::clone::Clone for BuiltinImplSource {
    #[inline]
    fn clone(&self) -> BuiltinImplSource {
        let _: ::core::clone::AssertParamIsClone<usize>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BuiltinImplSource { }Copy, #[automatically_derived]
impl ::core::hash::Hash for BuiltinImplSource {
    #[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 {
            BuiltinImplSource::Object(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            BuiltinImplSource::TraitUpcasting(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for BuiltinImplSource {
    #[inline]
    fn eq(&self, other: &BuiltinImplSource) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (BuiltinImplSource::Object(__self_0),
                    BuiltinImplSource::Object(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (BuiltinImplSource::TraitUpcasting(__self_0),
                    BuiltinImplSource::TraitUpcasting(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for BuiltinImplSource {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<usize>;
    }
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for BuiltinImplSource {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            BuiltinImplSource::Trivial =>
                ::core::fmt::Formatter::write_str(f, "Trivial"),
            BuiltinImplSource::Misc =>
                ::core::fmt::Formatter::write_str(f, "Misc"),
            BuiltinImplSource::Object(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Object",
                    &__self_0),
            BuiltinImplSource::TraitUpcasting(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "TraitUpcasting", &__self_0),
        }
    }
}Debug)]
220#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for
            BuiltinImplSource {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    BuiltinImplSource::Trivial => {}
                    BuiltinImplSource::Misc => {}
                    BuiltinImplSource::Object(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    BuiltinImplSource::TraitUpcasting(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for BuiltinImplSource {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        BuiltinImplSource::Trivial => { 0usize }
                        BuiltinImplSource::Misc => { 1usize }
                        BuiltinImplSource::Object(ref __binding_0) => { 2usize }
                        BuiltinImplSource::TraitUpcasting(ref __binding_0) => {
                            3usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    BuiltinImplSource::Trivial => {}
                    BuiltinImplSource::Misc => {}
                    BuiltinImplSource::Object(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    BuiltinImplSource::TraitUpcasting(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for BuiltinImplSource {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { BuiltinImplSource::Trivial }
                    1usize => { BuiltinImplSource::Misc }
                    2usize => {
                        BuiltinImplSource::Object(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => {
                        BuiltinImplSource::TraitUpcasting(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `BuiltinImplSource`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext))]
221pub enum BuiltinImplSource {
222    /// A built-in impl that is considered trivial, without any nested requirements. They
223    /// are preferred over where-clauses, and we want to track them explicitly.
224    Trivial,
225    /// Some built-in impl we don't need to differentiate. This should be used
226    /// unless more specific information is necessary.
227    Misc,
228    /// A built-in impl for trait objects. The index is only used in winnowing.
229    Object(usize),
230    /// A built-in implementation of `Upcast` for trait objects to other trait objects.
231    ///
232    /// The index is only used for winnowing.
233    TraitUpcasting(usize),
234}
235
236#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for Response<I> where I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            Response {
                certainty: ref __field_certainty,
                var_values: ref __field_var_values,
                external_constraints: ref __field_external_constraints } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "Response");
                ::core::fmt::DebugStruct::field(&mut __builder, "certainty",
                    __field_certainty);
                ::core::fmt::DebugStruct::field(&mut __builder, "var_values",
                    __field_var_values);
                ::core::fmt::DebugStruct::field(&mut __builder,
                    "external_constraints", __field_external_constraints);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
237#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for Response<I>
            where I: Interner,
            CanonicalVarValues<I>: ::rustc_type_ir::TypeVisitable<I>,
            I::ExternalConstraints: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    Response {
                        certainty: ref __binding_0,
                        var_values: ref __binding_1,
                        external_constraints: ref __binding_2 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for Response<I>
            where I: Interner,
            CanonicalVarValues<I>: ::rustc_type_ir::TypeFoldable<I>,
            I::ExternalConstraints: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        Response {
                            certainty: __binding_0,
                            var_values: __binding_1,
                            external_constraints: __binding_2 } => {
                            Response {
                                certainty: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                var_values: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                external_constraints: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    Response {
                        certainty: __binding_0,
                        var_values: __binding_1,
                        external_constraints: __binding_2 } => {
                        Response {
                            certainty: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            var_values: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            external_constraints: ::rustc_type_ir::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic)]
238#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hasher::StableHash
            for Response<I> where
            CanonicalVarValues<I>: ::rustc_data_structures::stable_hasher::StableHash,
            I::ExternalConstraints: ::rustc_data_structures::stable_hasher::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Response {
                        certainty: ref __binding_0,
                        var_values: ref __binding_1,
                        external_constraints: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext))]
239pub struct Response<I: Interner> {
240    pub certainty: Certainty,
241    pub var_values: CanonicalVarValues<I>,
242    /// Additional constraints returned by this query.
243    pub external_constraints: I::ExternalConstraints,
244}
245
246impl<I: Interner> Eq for Response<I> {}
247
248/// Additional constraints returned on success.
249#[automatically_derived]
impl<I: Interner> ::core::default::Default for ExternalConstraintsData<I>
    where I: Interner {
    fn default() -> Self {
        ExternalConstraintsData {
            region_constraints: ::core::default::Default::default(),
            opaque_types: ::core::default::Default::default(),
            normalization_nested_goals: ::core::default::Default::default(),
        }
    }
}#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
250#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            ExternalConstraintsData<I> where I: Interner,
            Vec<(ty::RegionConstraint<I>,
            VisibleForLeakCheck)>: ::rustc_type_ir::TypeVisitable<I>,
            Vec<(ty::OpaqueTypeKey<I>,
            I::Ty)>: ::rustc_type_ir::TypeVisitable<I>,
            NestedNormalizationGoals<I>: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    ExternalConstraintsData {
                        region_constraints: ref __binding_0,
                        opaque_types: ref __binding_1,
                        normalization_nested_goals: ref __binding_2 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            ExternalConstraintsData<I> where I: Interner,
            Vec<(ty::RegionConstraint<I>,
            VisibleForLeakCheck)>: ::rustc_type_ir::TypeFoldable<I>,
            Vec<(ty::OpaqueTypeKey<I>,
            I::Ty)>: ::rustc_type_ir::TypeFoldable<I>,
            NestedNormalizationGoals<I>: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        ExternalConstraintsData {
                            region_constraints: __binding_0,
                            opaque_types: __binding_1,
                            normalization_nested_goals: __binding_2 } => {
                            ExternalConstraintsData {
                                region_constraints: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                opaque_types: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                normalization_nested_goals: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    ExternalConstraintsData {
                        region_constraints: __binding_0,
                        opaque_types: __binding_1,
                        normalization_nested_goals: __binding_2 } => {
                        ExternalConstraintsData {
                            region_constraints: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            opaque_types: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            normalization_nested_goals: ::rustc_type_ir::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic)]
251#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hasher::StableHash
            for ExternalConstraintsData<I> where
            Vec<(ty::RegionConstraint<I>,
            VisibleForLeakCheck)>: ::rustc_data_structures::stable_hasher::StableHash,
            Vec<(ty::OpaqueTypeKey<I>,
            I::Ty)>: ::rustc_data_structures::stable_hasher::StableHash,
            NestedNormalizationGoals<I>: ::rustc_data_structures::stable_hasher::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    ExternalConstraintsData {
                        region_constraints: ref __binding_0,
                        opaque_types: ref __binding_1,
                        normalization_nested_goals: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext))]
252pub struct ExternalConstraintsData<I: Interner> {
253    pub region_constraints: Vec<(ty::RegionConstraint<I>, VisibleForLeakCheck)>,
254    pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
255    pub normalization_nested_goals: NestedNormalizationGoals<I>,
256}
257
258impl<I: Interner> Eq for ExternalConstraintsData<I> {}
259
260impl<I: Interner> ExternalConstraintsData<I> {
261    pub fn is_empty(&self) -> bool {
262        self.region_constraints.is_empty()
263            && self.opaque_types.is_empty()
264            && self.normalization_nested_goals.is_empty()
265    }
266}
267
268/// Whether the given region constraint should be considered/ignored for
269/// leak check. In most part of the compiler, this should be `Yes`, except
270/// for applying constraints from the nested goals in next-solver.
271/// `Unreachable` is used in places in which leak check isn't done, e.g.
272/// borrowck.
273#[derive(#[automatically_derived]
impl ::core::clone::Clone for VisibleForLeakCheck {
    #[inline]
    fn clone(&self) -> VisibleForLeakCheck { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for VisibleForLeakCheck { }Copy, #[automatically_derived]
impl ::core::hash::Hash for VisibleForLeakCheck {
    #[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)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for VisibleForLeakCheck {
    #[inline]
    fn eq(&self, other: &VisibleForLeakCheck) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for VisibleForLeakCheck {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for VisibleForLeakCheck {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                VisibleForLeakCheck::Yes => "Yes",
                VisibleForLeakCheck::No => "No",
                VisibleForLeakCheck::Unreachable => "Unreachable",
            })
    }
}Debug)]
274#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for
            VisibleForLeakCheck {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    VisibleForLeakCheck::Yes => {}
                    VisibleForLeakCheck::No => {}
                    VisibleForLeakCheck::Unreachable => {}
                }
            }
        }
    };StableHash_NoContext))]
275pub enum VisibleForLeakCheck {
276    Yes,
277    No,
278    Unreachable,
279}
280
281impl VisibleForLeakCheck {
282    pub fn and(self, other: VisibleForLeakCheck) -> VisibleForLeakCheck {
283        match (self, other) {
284            // Make sure that we never overwrite that constraints shouldn't
285            // be encountered by the leak checked
286            (VisibleForLeakCheck::Unreachable, _) | (_, VisibleForLeakCheck::Unreachable) => {
287                VisibleForLeakCheck::Unreachable
288            }
289            (VisibleForLeakCheck::No, _) | (_, VisibleForLeakCheck::No) => VisibleForLeakCheck::No,
290            (VisibleForLeakCheck::Yes, VisibleForLeakCheck::Yes) => VisibleForLeakCheck::Yes,
291        }
292    }
293
294    pub fn or(self, other: VisibleForLeakCheck) -> VisibleForLeakCheck {
295        match (self, other) {
296            // Make sure that we never overwrite that constraints shouldn't
297            // be encountered by the leak checked
298            (VisibleForLeakCheck::Unreachable, _) | (_, VisibleForLeakCheck::Unreachable) => {
299                VisibleForLeakCheck::Unreachable
300            }
301            (VisibleForLeakCheck::Yes, _) | (_, VisibleForLeakCheck::Yes) => {
302                VisibleForLeakCheck::Yes
303            }
304            (VisibleForLeakCheck::No, VisibleForLeakCheck::No) => VisibleForLeakCheck::No,
305        }
306    }
307}
308
309#[automatically_derived]
impl<I: Interner> ::core::default::Default for NestedNormalizationGoals<I>
    where I: Interner {
    fn default() -> Self {
        NestedNormalizationGoals(::core::default::Default::default())
    }
}#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
310#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            NestedNormalizationGoals<I> where I: Interner,
            Vec<(GoalSource,
            Goal<I, I::Predicate>)>: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    NestedNormalizationGoals(ref __binding_0) => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            NestedNormalizationGoals<I> where I: Interner,
            Vec<(GoalSource,
            Goal<I, I::Predicate>)>: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        NestedNormalizationGoals(__binding_0) => {
                            NestedNormalizationGoals(::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    NestedNormalizationGoals(__binding_0) => {
                        NestedNormalizationGoals(::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable_Generic)]
311#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hasher::StableHash
            for NestedNormalizationGoals<I> where
            Vec<(GoalSource,
            Goal<I,
            I::Predicate>)>: ::rustc_data_structures::stable_hasher::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    NestedNormalizationGoals(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext))]
312pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
313
314impl<I: Interner> Eq for NestedNormalizationGoals<I> {}
315
316impl<I: Interner> NestedNormalizationGoals<I> {
317    pub fn empty() -> Self {
318        NestedNormalizationGoals(::alloc::vec::Vec::new()vec![])
319    }
320
321    pub fn is_empty(&self) -> bool {
322        self.0.is_empty()
323    }
324}
325
326#[derive(#[automatically_derived]
impl ::core::clone::Clone for Certainty {
    #[inline]
    fn clone(&self) -> Certainty {
        let _: ::core::clone::AssertParamIsClone<MaybeInfo>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Certainty { }Copy, #[automatically_derived]
impl ::core::hash::Hash for Certainty {
    #[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 {
            Certainty::Maybe(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for Certainty {
    #[inline]
    fn eq(&self, other: &Certainty) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Certainty::Maybe(__self_0), Certainty::Maybe(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Certainty {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<MaybeInfo>;
    }
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for Certainty {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Certainty::Yes => ::core::fmt::Formatter::write_str(f, "Yes"),
            Certainty::Maybe(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Maybe",
                    &__self_0),
        }
    }
}Debug)]
327#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for Certainty
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    Certainty::Yes => {}
                    Certainty::Maybe(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
328pub enum Certainty {
329    Yes,
330    Maybe(MaybeInfo),
331}
332
333#[derive(#[automatically_derived]
impl ::core::clone::Clone for MaybeInfo {
    #[inline]
    fn clone(&self) -> MaybeInfo {
        let _: ::core::clone::AssertParamIsClone<MaybeCause>;
        let _: ::core::clone::AssertParamIsClone<OpaqueTypesJank>;
        let _: ::core::clone::AssertParamIsClone<StalledOnCoroutines>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MaybeInfo { }Copy, #[automatically_derived]
impl ::core::hash::Hash for MaybeInfo {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.cause, state);
        ::core::hash::Hash::hash(&self.opaque_types_jank, state);
        ::core::hash::Hash::hash(&self.stalled_on_coroutines, state)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for MaybeInfo {
    #[inline]
    fn eq(&self, other: &MaybeInfo) -> bool {
        self.cause == other.cause &&
                self.opaque_types_jank == other.opaque_types_jank &&
            self.stalled_on_coroutines == other.stalled_on_coroutines
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for MaybeInfo {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<MaybeCause>;
        let _: ::core::cmp::AssertParamIsEq<OpaqueTypesJank>;
        let _: ::core::cmp::AssertParamIsEq<StalledOnCoroutines>;
    }
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for MaybeInfo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "MaybeInfo",
            "cause", &self.cause, "opaque_types_jank",
            &self.opaque_types_jank, "stalled_on_coroutines",
            &&self.stalled_on_coroutines)
    }
}Debug)]
334#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for MaybeInfo
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    MaybeInfo {
                        cause: ref __binding_0,
                        opaque_types_jank: ref __binding_1,
                        stalled_on_coroutines: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext))]
335pub struct MaybeInfo {
336    pub cause: MaybeCause,
337    pub opaque_types_jank: OpaqueTypesJank,
338    pub stalled_on_coroutines: StalledOnCoroutines,
339}
340
341impl MaybeInfo {
342    pub const AMBIGUOUS: MaybeInfo = MaybeInfo {
343        cause: MaybeCause::Ambiguity,
344        opaque_types_jank: OpaqueTypesJank::AllGood,
345        stalled_on_coroutines: StalledOnCoroutines::No,
346    };
347
348    fn and(self, other: MaybeInfo) -> MaybeInfo {
349        MaybeInfo {
350            cause: self.cause.and(other.cause),
351            opaque_types_jank: self.opaque_types_jank.and(other.opaque_types_jank),
352            stalled_on_coroutines: self.stalled_on_coroutines.and(other.stalled_on_coroutines),
353        }
354    }
355
356    pub fn or(self, other: MaybeInfo) -> MaybeInfo {
357        MaybeInfo {
358            cause: self.cause.or(other.cause),
359            opaque_types_jank: self.opaque_types_jank.or(other.opaque_types_jank),
360            stalled_on_coroutines: self.stalled_on_coroutines.or(other.stalled_on_coroutines),
361        }
362    }
363}
364
365/// Supporting not-yet-defined opaque types in HIR typeck is somewhat
366/// challenging. Ideally we'd normalize them to a new inference variable
367/// and just defer type inference which relies on the opaque until we've
368/// constrained the hidden type.
369///
370/// This doesn't work for method and function calls as we need to guide type
371/// inference for the function arguments. We treat not-yet-defined opaque types
372/// as if they were rigid instead in these places.
373///
374/// When we encounter a `?hidden_type_of_opaque: Trait<?var>` goal, we use the
375/// item bounds and blanket impls to guide inference by constraining other type
376/// variables, see `EvalCtxt::try_assemble_bounds_via_registered_opaques`. We
377/// always keep the certainty as `Maybe` so that we properly prove these goals
378/// once the hidden type has been constrained.
379///
380/// If we fail to prove the trait goal via item bounds or blanket impls, the
381/// goal would have errored if the opaque type were rigid. In this case, we
382/// set `OpaqueTypesJank::ErrorIfRigidSelfTy` in the [Certainty].
383///
384/// Places in HIR typeck where we want to treat not-yet-defined opaque types as if
385/// they were kind of rigid then use `fn root_goal_may_hold_opaque_types_jank` which
386/// returns `false` if the goal doesn't hold or if `OpaqueTypesJank::ErrorIfRigidSelfTy`
387/// is set (i.e. proving it required relies on some `?hidden_ty: NotInItemBounds` goal).
388///
389/// This is subtly different from actually treating not-yet-defined opaque types as
390/// rigid, e.g. it allows constraining opaque types if they are not the self-type of
391/// a goal. It is good enough for now and only matters for very rare type inference
392/// edge cases. We can improve this later on if necessary.
393#[derive(#[automatically_derived]
impl ::core::clone::Clone for OpaqueTypesJank {
    #[inline]
    fn clone(&self) -> OpaqueTypesJank { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OpaqueTypesJank { }Copy, #[automatically_derived]
impl ::core::hash::Hash for OpaqueTypesJank {
    #[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)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for OpaqueTypesJank {
    #[inline]
    fn eq(&self, other: &OpaqueTypesJank) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OpaqueTypesJank {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for OpaqueTypesJank {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                OpaqueTypesJank::AllGood => "AllGood",
                OpaqueTypesJank::ErrorIfRigidSelfTy => "ErrorIfRigidSelfTy",
            })
    }
}Debug)]
394#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for
            OpaqueTypesJank {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    OpaqueTypesJank::AllGood => {}
                    OpaqueTypesJank::ErrorIfRigidSelfTy => {}
                }
            }
        }
    };StableHash))]
395pub enum OpaqueTypesJank {
396    AllGood,
397    ErrorIfRigidSelfTy,
398}
399impl OpaqueTypesJank {
400    fn and(self, other: OpaqueTypesJank) -> OpaqueTypesJank {
401        match (self, other) {
402            (OpaqueTypesJank::AllGood, OpaqueTypesJank::AllGood) => OpaqueTypesJank::AllGood,
403            (OpaqueTypesJank::ErrorIfRigidSelfTy, _) | (_, OpaqueTypesJank::ErrorIfRigidSelfTy) => {
404                OpaqueTypesJank::ErrorIfRigidSelfTy
405            }
406        }
407    }
408
409    pub fn or(self, other: OpaqueTypesJank) -> OpaqueTypesJank {
410        match (self, other) {
411            (OpaqueTypesJank::ErrorIfRigidSelfTy, OpaqueTypesJank::ErrorIfRigidSelfTy) => {
412                OpaqueTypesJank::ErrorIfRigidSelfTy
413            }
414            (OpaqueTypesJank::AllGood, _) | (_, OpaqueTypesJank::AllGood) => {
415                OpaqueTypesJank::AllGood
416            }
417        }
418    }
419}
420
421#[derive(#[automatically_derived]
impl ::core::clone::Clone for StalledOnCoroutines {
    #[inline]
    fn clone(&self) -> StalledOnCoroutines { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for StalledOnCoroutines { }Copy, #[automatically_derived]
impl ::core::hash::Hash for StalledOnCoroutines {
    #[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)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for StalledOnCoroutines {
    #[inline]
    fn eq(&self, other: &StalledOnCoroutines) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for StalledOnCoroutines {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for StalledOnCoroutines {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                StalledOnCoroutines::Yes => "Yes",
                StalledOnCoroutines::No => "No",
            })
    }
}Debug)]
422#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for
            StalledOnCoroutines {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    StalledOnCoroutines::Yes => {}
                    StalledOnCoroutines::No => {}
                }
            }
        }
    };StableHash_NoContext))]
423pub enum StalledOnCoroutines {
424    Yes,
425    No,
426}
427
428impl StalledOnCoroutines {
429    fn and(self, other: StalledOnCoroutines) -> StalledOnCoroutines {
430        match (self, other) {
431            (StalledOnCoroutines::No, StalledOnCoroutines::No) => StalledOnCoroutines::No,
432            (StalledOnCoroutines::Yes, _) | (_, StalledOnCoroutines::Yes) => {
433                StalledOnCoroutines::Yes
434            }
435        }
436    }
437
438    pub fn or(self, other: StalledOnCoroutines) -> StalledOnCoroutines {
439        // `StalledOnCoroutines::Yes` is contagious: obtaining `Certainty::Maybe`
440        // while a candidate is stalled on a coroutine might have been
441        // `Certainty::Yes` or `NoSolution` if it were not stalled.
442        StalledOnCoroutines::and(self, other)
443    }
444}
445
446impl Certainty {
447    pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeInfo::AMBIGUOUS);
448
449    /// Use this function to merge the certainty of multiple nested subgoals.
450    ///
451    /// Given an impl like `impl<T: Foo + Bar> Baz for T {}`, we have 2 nested
452    /// subgoals whenever we use the impl as a candidate: `T: Foo` and `T: Bar`.
453    /// If evaluating `T: Foo` results in ambiguity and `T: Bar` results in
454    /// success, we merge these two responses. This results in ambiguity.
455    ///
456    /// If we unify ambiguity with overflow, we return overflow. This doesn't matter
457    /// inside of the solver as we do not distinguish ambiguity from overflow. It does
458    /// however matter for diagnostics. If `T: Foo` resulted in overflow and `T: Bar`
459    /// in ambiguity without changing the inference state, we still want to tell the
460    /// user that `T: Baz` results in overflow.
461    pub fn and(self, other: Certainty) -> Certainty {
462        match (self, other) {
463            (Certainty::Yes, Certainty::Yes) => Certainty::Yes,
464            (Certainty::Yes, Certainty::Maybe { .. }) => other,
465            (Certainty::Maybe { .. }, Certainty::Yes) => self,
466            (Certainty::Maybe(a_maybe), Certainty::Maybe(b_maybe)) => {
467                Certainty::Maybe(a_maybe.and(b_maybe))
468            }
469        }
470    }
471
472    pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
473        Certainty::Maybe(MaybeInfo {
474            cause: MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false },
475            opaque_types_jank: OpaqueTypesJank::AllGood,
476            stalled_on_coroutines: StalledOnCoroutines::No,
477        })
478    }
479}
480
481/// Why we failed to evaluate a goal.
482#[derive(#[automatically_derived]
impl ::core::clone::Clone for MaybeCause {
    #[inline]
    fn clone(&self) -> MaybeCause {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MaybeCause { }Copy, #[automatically_derived]
impl ::core::hash::Hash for MaybeCause {
    #[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 {
            MaybeCause::Overflow {
                suggest_increasing_limit: __self_0, keep_constraints: __self_1
                } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for MaybeCause {
    #[inline]
    fn eq(&self, other: &MaybeCause) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (MaybeCause::Overflow {
                    suggest_increasing_limit: __self_0,
                    keep_constraints: __self_1 }, MaybeCause::Overflow {
                    suggest_increasing_limit: __arg1_0,
                    keep_constraints: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for MaybeCause {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for MaybeCause {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            MaybeCause::Ambiguity =>
                ::core::fmt::Formatter::write_str(f, "Ambiguity"),
            MaybeCause::Overflow {
                suggest_increasing_limit: __self_0, keep_constraints: __self_1
                } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Overflow", "suggest_increasing_limit", __self_0,
                    "keep_constraints", &__self_1),
        }
    }
}Debug)]
483#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for MaybeCause
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    MaybeCause::Ambiguity => {}
                    MaybeCause::Overflow {
                        suggest_increasing_limit: ref __binding_0,
                        keep_constraints: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
484pub enum MaybeCause {
485    /// We failed due to ambiguity. This ambiguity can either
486    /// be a true ambiguity, i.e. there are multiple different answers,
487    /// or we hit a case where we just don't bother, e.g. `?x: Trait` goals.
488    Ambiguity,
489    /// We gave up due to an overflow, most often by hitting the recursion limit.
490    Overflow { suggest_increasing_limit: bool, keep_constraints: bool },
491}
492
493impl MaybeCause {
494    fn and(self, other: MaybeCause) -> MaybeCause {
495        match (self, other) {
496            (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
497            (MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
498            (MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
499            (
500                MaybeCause::Overflow {
501                    suggest_increasing_limit: limit_a,
502                    keep_constraints: keep_a,
503                },
504                MaybeCause::Overflow {
505                    suggest_increasing_limit: limit_b,
506                    keep_constraints: keep_b,
507                },
508            ) => MaybeCause::Overflow {
509                suggest_increasing_limit: limit_a && limit_b,
510                keep_constraints: keep_a && keep_b,
511            },
512        }
513    }
514
515    pub fn or(self, other: MaybeCause) -> MaybeCause {
516        match (self, other) {
517            (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
518
519            // When combining ambiguity + overflow, we can keep constraints.
520            (
521                MaybeCause::Ambiguity,
522                MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
523            ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
524            (
525                MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
526                MaybeCause::Ambiguity,
527            ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
528
529            (
530                MaybeCause::Overflow {
531                    suggest_increasing_limit: limit_a,
532                    keep_constraints: keep_a,
533                },
534                MaybeCause::Overflow {
535                    suggest_increasing_limit: limit_b,
536                    keep_constraints: keep_b,
537                },
538            ) => MaybeCause::Overflow {
539                suggest_increasing_limit: limit_a || limit_b,
540                keep_constraints: keep_a || keep_b,
541            },
542        }
543    }
544}
545
546/// Indicates that a `impl Drop for Adt` is `const` or not.
547#[derive(#[automatically_derived]
impl ::core::fmt::Debug for AdtDestructorKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AdtDestructorKind::NotConst => "NotConst",
                AdtDestructorKind::Const => "Const",
            })
    }
}Debug)]
548pub enum AdtDestructorKind {
549    NotConst,
550    Const,
551}
552
553/// Which sizedness trait - `Sized`, `MetaSized`? `PointeeSized` is omitted as it is removed during
554/// lowering.
555#[derive(#[automatically_derived]
impl ::core::marker::Copy for SizedTraitKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for SizedTraitKind {
    #[inline]
    fn clone(&self) -> SizedTraitKind { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SizedTraitKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                SizedTraitKind::Sized => "Sized",
                SizedTraitKind::MetaSized => "MetaSized",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for SizedTraitKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for SizedTraitKind {
    #[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)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for SizedTraitKind {
    #[inline]
    fn eq(&self, other: &SizedTraitKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq)]
556#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::StableHash for
            SizedTraitKind {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    SizedTraitKind::Sized => {}
                    SizedTraitKind::MetaSized => {}
                }
            }
        }
    };StableHash))]
557pub enum SizedTraitKind {
558    /// `Sized` trait
559    Sized,
560    /// `MetaSized` trait
561    MetaSized,
562}
563
564impl SizedTraitKind {
565    /// Returns `DefId` of corresponding language item.
566    pub fn require_lang_item<I: Interner>(self, cx: I) -> I::TraitId {
567        cx.require_trait_lang_item(match self {
568            SizedTraitKind::Sized => SolverTraitLangItem::Sized,
569            SizedTraitKind::MetaSized => SolverTraitLangItem::MetaSized,
570        })
571    }
572}