rustc_middle/traits/
solve.rs

1use rustc_data_structures::intern::Interned;
2use rustc_macros::HashStable;
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>>;
17
18pub type PredefinedOpaques<'tcx> = &'tcx ty::List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>;
19
20#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
21pub struct ExternalConstraints<'tcx>(
22    pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
23);
24
25impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
26    type Target = ExternalConstraintsData<TyCtxt<'tcx>>;
27
28    fn deref(&self) -> &Self::Target {
29        &self.0
30    }
31}
32
33// FIXME: Having to clone `region_constraints` for folding feels bad and
34// probably isn't great wrt performance.
35//
36// Not sure how to fix this, maybe we should also intern `opaque_types` and
37// `region_constraints` here or something.
38impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
39    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
40        self,
41        folder: &mut F,
42    ) -> Result<Self, F::Error> {
43        // Perf testing has found that this check is slightly faster than
44        // folding and re-interning an empty `ExternalConstraintsData`.
45        // See: <https://github.com/rust-lang/rust/pull/142430>.
46        if self.is_empty() {
47            return Ok(self);
48        }
49
50        Ok(FallibleTypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
51            region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
52            opaque_types: self
53                .opaque_types
54                .iter()
55                .map(|opaque| opaque.try_fold_with(folder))
56                .collect::<Result<_, F::Error>>()?,
57            normalization_nested_goals: self
58                .normalization_nested_goals
59                .clone()
60                .try_fold_with(folder)?,
61        }))
62    }
63
64    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
65        // Perf testing has found that this check is slightly faster than
66        // folding and re-interning an empty `ExternalConstraintsData`.
67        // See: <https://github.com/rust-lang/rust/pull/142430>.
68        if self.is_empty() {
69            return self;
70        }
71
72        TypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
73            region_constraints: self.region_constraints.clone().fold_with(folder),
74            opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
75            normalization_nested_goals: self.normalization_nested_goals.clone().fold_with(folder),
76        })
77    }
78}
79
80impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
81    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
82        try_visit!(self.region_constraints.visit_with(visitor));
83        try_visit!(self.opaque_types.visit_with(visitor));
84        self.normalization_nested_goals.visit_with(visitor)
85    }
86}