hir_ty/next_solver/
opaques.rs

1//! Things related to opaques in the next-trait-solver.
2
3use rustc_ast_ir::try_visit;
4use rustc_type_ir::inherent::SliceLike;
5
6use super::{DbInterner, SolverDefId, Ty, interned_vec_db, interned_vec_nolifetime_salsa};
7
8pub type OpaqueTypeKey<'db> = rustc_type_ir::OpaqueTypeKey<DbInterner<'db>>;
9
10type PredefinedOpaque<'db> = (OpaqueTypeKey<'db>, Ty<'db>);
11interned_vec_db!(PredefinedOpaques, PredefinedOpaque);
12
13pub type ExternalConstraintsData<'db> =
14    rustc_type_ir::solve::ExternalConstraintsData<DbInterner<'db>>;
15
16interned_vec_nolifetime_salsa!(SolverDefIds, SolverDefId);
17
18#[salsa::interned(constructor = new_, debug)]
19pub struct ExternalConstraints<'db> {
20    #[returns(ref)]
21    kind_: rustc_type_ir::solve::ExternalConstraintsData<DbInterner<'db>>,
22}
23
24impl<'db> ExternalConstraints<'db> {
25    pub fn new(interner: DbInterner<'db>, data: ExternalConstraintsData<'db>) -> Self {
26        ExternalConstraints::new_(interner.db(), data)
27    }
28
29    pub fn inner(&self) -> &ExternalConstraintsData<'db> {
30        crate::with_attached_db(|db| {
31            let inner = self.kind_(db);
32            // SAFETY: ¯\_(ツ)_/¯
33            unsafe { std::mem::transmute(inner) }
34        })
35    }
36}
37
38impl<'db> std::ops::Deref for ExternalConstraints<'db> {
39    type Target = ExternalConstraintsData<'db>;
40
41    fn deref(&self) -> &Self::Target {
42        self.inner()
43    }
44}
45
46impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for ExternalConstraints<'db> {
47    fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
48        &self,
49        visitor: &mut V,
50    ) -> V::Result {
51        try_visit!(self.region_constraints.visit_with(visitor));
52        try_visit!(self.opaque_types.visit_with(visitor));
53        self.normalization_nested_goals.visit_with(visitor)
54    }
55}
56
57impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for ExternalConstraints<'db> {
58    fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
59        self,
60        folder: &mut F,
61    ) -> Result<Self, F::Error> {
62        Ok(ExternalConstraints::new(
63            folder.cx(),
64            ExternalConstraintsData {
65                region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
66                opaque_types: self
67                    .opaque_types
68                    .iter()
69                    .cloned()
70                    .map(|opaque| opaque.try_fold_with(folder))
71                    .collect::<Result<_, F::Error>>()?,
72                normalization_nested_goals: self
73                    .normalization_nested_goals
74                    .clone()
75                    .try_fold_with(folder)?,
76            },
77        ))
78    }
79    fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
80        ExternalConstraints::new(
81            folder.cx(),
82            ExternalConstraintsData {
83                region_constraints: self.region_constraints.clone().fold_with(folder),
84                opaque_types: self
85                    .opaque_types
86                    .iter()
87                    .cloned()
88                    .map(|opaque| opaque.fold_with(folder))
89                    .collect(),
90                normalization_nested_goals: self
91                    .normalization_nested_goals
92                    .clone()
93                    .fold_with(folder),
94            },
95        )
96    }
97}