Skip to main content

hir_ty/next_solver/
opaques.rs

1//! Things related to opaques in the next-trait-solver.
2
3use intern::{Interned, InternedRef, impl_internable};
4use macros::GenericTypeVisitable;
5use rustc_ast_ir::try_visit;
6use rustc_type_ir::inherent::SliceLike;
7
8use crate::next_solver::{impl_foldable_for_interned_slice, interned_slice};
9
10use super::{DbInterner, SolverDefId, Ty};
11
12pub type OpaqueTypeKey<'db> = rustc_type_ir::OpaqueTypeKey<DbInterner<'db>>;
13
14type PredefinedOpaque<'db> = (OpaqueTypeKey<'db>, Ty<'db>);
15interned_slice!(
16    PredefinedOpaquesStorage,
17    PredefinedOpaques,
18    StoredPredefinedOpaques,
19    predefined_opaques,
20    PredefinedOpaque<'db>,
21    PredefinedOpaque<'static>,
22);
23impl_foldable_for_interned_slice!(PredefinedOpaques);
24
25pub type ExternalConstraintsData<'db> =
26    rustc_type_ir::solve::ExternalConstraintsData<DbInterner<'db>>;
27
28interned_slice!(
29    SolverDefIdsStorage,
30    SolverDefIds,
31    StoredSolverDefIds,
32    def_ids,
33    SolverDefId<'db>,
34    SolverDefId<'static>,
35);
36impl_foldable_for_interned_slice!(SolverDefIds);
37
38#[derive(Clone, Copy, PartialEq, Eq, Hash)]
39pub struct ExternalConstraints<'db> {
40    interned: InternedRef<'db, ExternalConstraintsInterned>,
41}
42
43#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)]
44pub(super) struct ExternalConstraintsInterned(ExternalConstraintsData<'static>);
45
46impl_internable!(gc; ExternalConstraintsInterned);
47
48const _: () = {
49    const fn is_copy<T: Copy>() {}
50    is_copy::<ExternalConstraints<'static>>();
51};
52
53impl<'db> ExternalConstraints<'db> {
54    #[inline]
55    pub fn new(_interner: DbInterner<'db>, data: ExternalConstraintsData<'db>) -> Self {
56        let data = unsafe {
57            std::mem::transmute::<ExternalConstraintsData<'db>, ExternalConstraintsData<'static>>(
58                data,
59            )
60        };
61        Self { interned: Interned::new_gc(ExternalConstraintsInterned(data)) }
62    }
63
64    #[inline]
65    pub fn inner(&self) -> &ExternalConstraintsData<'db> {
66        let inner = &self.interned.0;
67        unsafe {
68            std::mem::transmute::<&ExternalConstraintsData<'static>, &ExternalConstraintsData<'db>>(
69                inner,
70            )
71        }
72    }
73}
74
75impl<'db> std::ops::Deref for ExternalConstraints<'db> {
76    type Target = ExternalConstraintsData<'db>;
77
78    fn deref(&self) -> &Self::Target {
79        self.inner()
80    }
81}
82
83impl std::fmt::Debug for ExternalConstraints<'_> {
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        self.inner().fmt(f)
86    }
87}
88
89impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for ExternalConstraints<'db> {
90    fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
91        &self,
92        visitor: &mut V,
93    ) -> V::Result {
94        try_visit!(self.region_constraints.visit_with(visitor));
95        try_visit!(self.opaque_types.visit_with(visitor));
96        self.normalization_nested_goals.visit_with(visitor)
97    }
98}
99
100impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for ExternalConstraints<'db> {
101    fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
102        self,
103        folder: &mut F,
104    ) -> Result<Self, F::Error> {
105        Ok(ExternalConstraints::new(
106            folder.cx(),
107            ExternalConstraintsData {
108                region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
109                opaque_types: self
110                    .opaque_types
111                    .iter()
112                    .cloned()
113                    .map(|opaque| opaque.try_fold_with(folder))
114                    .collect::<Result<_, F::Error>>()?,
115                normalization_nested_goals: self
116                    .normalization_nested_goals
117                    .clone()
118                    .try_fold_with(folder)?,
119            },
120        ))
121    }
122    fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
123        ExternalConstraints::new(
124            folder.cx(),
125            ExternalConstraintsData {
126                region_constraints: self.region_constraints.clone().fold_with(folder),
127                opaque_types: self
128                    .opaque_types
129                    .iter()
130                    .cloned()
131                    .map(|opaque| opaque.fold_with(folder))
132                    .collect(),
133                normalization_nested_goals: self
134                    .normalization_nested_goals
135                    .clone()
136                    .fold_with(folder),
137            },
138        )
139    }
140}