rustc_middle/traits/
solve.rs

1use rustc_ast_ir::try_visit;
2use rustc_data_structures::intern::Interned;
3use rustc_macros::HashStable;
4use rustc_type_ir as ir;
5pub use rustc_type_ir::solve::*;
6
7use crate::ty::{
8    self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
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        Ok(FallibleTypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
53            region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
54            opaque_types: self
55                .opaque_types
56                .iter()
57                .map(|opaque| opaque.try_fold_with(folder))
58                .collect::<Result<_, F::Error>>()?,
59            normalization_nested_goals: self
60                .normalization_nested_goals
61                .clone()
62                .try_fold_with(folder)?,
63        }))
64    }
65
66    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
67        TypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
68            region_constraints: self.region_constraints.clone().fold_with(folder),
69            opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
70            normalization_nested_goals: self.normalization_nested_goals.clone().fold_with(folder),
71        })
72    }
73}
74
75impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
76    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
77        try_visit!(self.region_constraints.visit_with(visitor));
78        try_visit!(self.opaque_types.visit_with(visitor));
79        self.normalization_nested_goals.visit_with(visitor)
80    }
81}
82
83// FIXME: Having to clone `region_constraints` for folding feels bad and
84// probably isn't great wrt performance.
85//
86// Not sure how to fix this, maybe we should also intern `opaque_types` and
87// `region_constraints` here or something.
88impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
89    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
90        self,
91        folder: &mut F,
92    ) -> Result<Self, F::Error> {
93        Ok(FallibleTypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
94            opaque_types: self
95                .opaque_types
96                .iter()
97                .map(|opaque| opaque.try_fold_with(folder))
98                .collect::<Result<_, F::Error>>()?,
99        }))
100    }
101
102    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
103        TypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
104            opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
105        })
106    }
107}
108
109impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
110    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
111        self.opaque_types.visit_with(visitor)
112    }
113}