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, 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
18#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
19pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>);
20
21impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
22    type Target = PredefinedOpaquesData<TyCtxt<'tcx>>;
23
24    fn deref(&self) -> &Self::Target {
25        &self.0
26    }
27}
28
29#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
30pub struct ExternalConstraints<'tcx>(
31    pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
32);
33
34impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
35    type Target = ExternalConstraintsData<TyCtxt<'tcx>>;
36
37    fn deref(&self) -> &Self::Target {
38        &self.0
39    }
40}
41
42// FIXME: Having to clone `region_constraints` for folding feels bad and
43// probably isn't great wrt performance.
44//
45// Not sure how to fix this, maybe we should also intern `opaque_types` and
46// `region_constraints` here or something.
47impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
48    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
49        self,
50        folder: &mut F,
51    ) -> Result<Self, F::Error> {
52        // Perf testing has found that this check is slightly faster than
53        // folding and re-interning an empty `ExternalConstraintsData`.
54        // See: <https://github.com/rust-lang/rust/pull/142430>.
55        if self.is_empty() {
56            return Ok(self);
57        }
58
59        Ok(FallibleTypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
60            region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
61            opaque_types: self
62                .opaque_types
63                .iter()
64                .map(|opaque| opaque.try_fold_with(folder))
65                .collect::<Result<_, F::Error>>()?,
66            normalization_nested_goals: self
67                .normalization_nested_goals
68                .clone()
69                .try_fold_with(folder)?,
70        }))
71    }
72
73    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
74        // Perf testing has found that this check is slightly faster than
75        // folding and re-interning an empty `ExternalConstraintsData`.
76        // See: <https://github.com/rust-lang/rust/pull/142430>.
77        if self.is_empty() {
78            return self;
79        }
80
81        TypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
82            region_constraints: self.region_constraints.clone().fold_with(folder),
83            opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
84            normalization_nested_goals: self.normalization_nested_goals.clone().fold_with(folder),
85        })
86    }
87}
88
89impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
90    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
91        try_visit!(self.region_constraints.visit_with(visitor));
92        try_visit!(self.opaque_types.visit_with(visitor));
93        self.normalization_nested_goals.visit_with(visitor)
94    }
95}
96
97// FIXME: Having to clone `region_constraints` for folding feels bad and
98// probably isn't great wrt performance.
99//
100// Not sure how to fix this, maybe we should also intern `opaque_types` and
101// `region_constraints` here or something.
102impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
103    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
104        self,
105        folder: &mut F,
106    ) -> Result<Self, F::Error> {
107        Ok(FallibleTypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
108            opaque_types: self
109                .opaque_types
110                .iter()
111                .map(|opaque| opaque.try_fold_with(folder))
112                .collect::<Result<_, F::Error>>()?,
113        }))
114    }
115
116    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
117        TypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
118            opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
119        })
120    }
121}
122
123impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
124    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
125        self.opaque_types.visit_with(visitor)
126    }
127}