Skip to main content

rustc_middle/traits/
solve.rs

1use rustc_data_structures::intern::Interned;
2use rustc_macros::StableHash;
3use rustc_type_ir as ir;
4pub use rustc_type_ir::solve::*;
5
6use crate::ty::{
7    self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
8    try_visit,
9};
10
11pub type Goal<'tcx, P> = ir::solve::Goal<TyCtxt<'tcx>, P>;
12pub type QueryInput<'tcx, P> = ir::solve::QueryInput<TyCtxt<'tcx>, P>;
13pub type QueryResult<'tcx> = ir::solve::QueryResult<TyCtxt<'tcx>>;
14pub type CandidateSource<'tcx> = ir::solve::CandidateSource<TyCtxt<'tcx>>;
15pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir::solve::CanonicalInput<TyCtxt<'tcx>, P>;
16pub type CanonicalResponse<'tcx> = ir::solve::CanonicalResponse<TyCtxt<'tcx>>;
17pub type FetchEligibleAssocItemResponse<'tcx> =
18    ir::solve::FetchEligibleAssocItemResponse<TyCtxt<'tcx>>;
19pub type ComputeGoalFastPathOutcome<'tcx> = ir::solve::ComputeGoalFastPathOutcome<TyCtxt<'tcx>>;
20pub type GoalStalledOn<'tcx> = ir::solve::GoalStalledOn<TyCtxt<'tcx>>;
21pub type GoalStalledOnOpaques<'tcx> = ir::solve::GoalStalledOnOpaques<TyCtxt<'tcx>>;
22pub type SucceededInErased<'tcx> = ir::solve::SucceededInErased<TyCtxt<'tcx>>;
23
24pub type PredefinedOpaques<'tcx> = &'tcx ty::List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>;
25
26#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ExternalConstraints<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "ExternalConstraints", &&self.0)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for ExternalConstraints<'tcx> {
    #[inline]
    fn eq(&self, other: &ExternalConstraints<'tcx>) -> bool {
        self.0 == other.0
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for ExternalConstraints<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _:
                ::core::cmp::AssertParamIsEq<Interned<'tcx,
                ExternalConstraintsData<TyCtxt<'tcx>>>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for ExternalConstraints<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ExternalConstraints<'tcx> {
    #[inline]
    fn clone(&self) -> ExternalConstraints<'tcx> {
        let _:
                ::core::clone::AssertParamIsClone<Interned<'tcx,
                ExternalConstraintsData<TyCtxt<'tcx>>>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for ExternalConstraints<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            ExternalConstraints<'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 {
                    ExternalConstraints(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
27pub struct ExternalConstraints<'tcx>(
28    pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
29);
30
31impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
32    type Target = ExternalConstraintsData<TyCtxt<'tcx>>;
33
34    fn deref(&self) -> &Self::Target {
35        &self.0
36    }
37}
38
39// FIXME: Having to clone `region_constraints` for folding feels bad and
40// probably isn't great wrt performance.
41//
42// Not sure how to fix this, maybe we should also intern `opaque_types` and
43// `region_constraints` here or something.
44impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
45    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
46        self,
47        folder: &mut F,
48    ) -> Result<Self, F::Error> {
49        // Perf testing has found that this check is slightly faster than
50        // folding and re-interning an empty `ExternalConstraintsData`.
51        // See: <https://github.com/rust-lang/rust/pull/142430>.
52        if self.is_empty() {
53            return Ok(self);
54        }
55
56        Ok(FallibleTypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
57            region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
58            opaque_types: self
59                .opaque_types
60                .iter()
61                .map(|opaque| opaque.try_fold_with(folder))
62                .collect::<Result<_, F::Error>>()?,
63            normalization_nested_goals: self
64                .normalization_nested_goals
65                .clone()
66                .try_fold_with(folder)?,
67        }))
68    }
69
70    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
71        // Perf testing has found that this check is slightly faster than
72        // folding and re-interning an empty `ExternalConstraintsData`.
73        // See: <https://github.com/rust-lang/rust/pull/142430>.
74        if self.is_empty() {
75            return self;
76        }
77
78        TypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
79            region_constraints: self.region_constraints.clone().fold_with(folder),
80            opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
81            normalization_nested_goals: self.normalization_nested_goals.clone().fold_with(folder),
82        })
83    }
84}
85
86impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
87    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
88        let ExternalConstraintsData {
89            region_constraints,
90            opaque_types,
91            normalization_nested_goals,
92        } = &**self;
93
94        match ::rustc_ast_ir::visit::VisitorResult::branch(region_constraints.visit_with(visitor))
    {
    core::ops::ControlFlow::Continue(()) =>
        (),
        #[allow(unreachable_code)]
        core::ops::ControlFlow::Break(r) => {
        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
    }
};try_visit!(region_constraints.visit_with(visitor));
95        match ::rustc_ast_ir::visit::VisitorResult::branch(opaque_types.visit_with(visitor))
    {
    core::ops::ControlFlow::Continue(()) =>
        (),
        #[allow(unreachable_code)]
        core::ops::ControlFlow::Break(r) => {
        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
    }
};try_visit!(opaque_types.visit_with(visitor));
96        normalization_nested_goals.visit_with(visitor)
97    }
98}