blob: 43589ab2ef139318618c85705fe907abcf9af262 [file] [log] [blame]
//! Things related to opaques in the next-trait-solver.
use intern::Interned;
use rustc_ast_ir::try_visit;
use crate::next_solver::SolverDefId;
use super::{CanonicalVarKind, DbInterner, interned_vec_nolifetime_salsa};
pub type OpaqueTypeKey<'db> = rustc_type_ir::OpaqueTypeKey<DbInterner<'db>>;
pub type PredefinedOpaquesData<'db> = rustc_type_ir::solve::PredefinedOpaquesData<DbInterner<'db>>;
pub type ExternalConstraintsData<'db> =
rustc_type_ir::solve::ExternalConstraintsData<DbInterner<'db>>;
#[salsa::interned(constructor = new_, debug)]
pub struct PredefinedOpaques<'db> {
#[returns(ref)]
kind_: rustc_type_ir::solve::PredefinedOpaquesData<DbInterner<'db>>,
}
impl<'db> PredefinedOpaques<'db> {
pub fn new(interner: DbInterner<'db>, data: PredefinedOpaquesData<'db>) -> Self {
PredefinedOpaques::new_(interner.db(), data)
}
pub fn inner(&self) -> &PredefinedOpaquesData<'db> {
salsa::with_attached_database(|db| {
let inner = self.kind_(db);
// SAFETY: ¯\_(ツ)_/¯
unsafe { std::mem::transmute(inner) }
})
.unwrap()
}
}
impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for PredefinedOpaques<'db> {
fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
&self,
visitor: &mut V,
) -> V::Result {
self.opaque_types.visit_with(visitor)
}
}
impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for PredefinedOpaques<'db> {
fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(PredefinedOpaques::new(
folder.cx(),
PredefinedOpaquesData {
opaque_types: self
.opaque_types
.iter()
.cloned()
.map(|opaque| opaque.try_fold_with(folder))
.collect::<Result<_, F::Error>>()?,
},
))
}
fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
PredefinedOpaques::new(
folder.cx(),
PredefinedOpaquesData {
opaque_types: self
.opaque_types
.iter()
.cloned()
.map(|opaque| opaque.fold_with(folder))
.collect(),
},
)
}
}
impl<'db> std::ops::Deref for PredefinedOpaques<'db> {
type Target = PredefinedOpaquesData<'db>;
fn deref(&self) -> &Self::Target {
self.inner()
}
}
interned_vec_nolifetime_salsa!(SolverDefIds, SolverDefId);
#[salsa::interned(constructor = new_, debug)]
pub struct ExternalConstraints<'db> {
#[returns(ref)]
kind_: rustc_type_ir::solve::ExternalConstraintsData<DbInterner<'db>>,
}
impl<'db> ExternalConstraints<'db> {
pub fn new(interner: DbInterner<'db>, data: ExternalConstraintsData<'db>) -> Self {
ExternalConstraints::new_(interner.db(), data)
}
pub fn inner(&self) -> &ExternalConstraintsData<'db> {
salsa::with_attached_database(|db| {
let inner = self.kind_(db);
// SAFETY: ¯\_(ツ)_/¯
unsafe { std::mem::transmute(inner) }
})
.unwrap()
}
}
impl<'db> std::ops::Deref for ExternalConstraints<'db> {
type Target = ExternalConstraintsData<'db>;
fn deref(&self) -> &Self::Target {
self.inner()
}
}
impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for ExternalConstraints<'db> {
fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
&self,
visitor: &mut V,
) -> V::Result {
try_visit!(self.region_constraints.visit_with(visitor));
try_visit!(self.opaque_types.visit_with(visitor));
self.normalization_nested_goals.visit_with(visitor)
}
}
impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for ExternalConstraints<'db> {
fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(ExternalConstraints::new(
folder.cx(),
ExternalConstraintsData {
region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
opaque_types: self
.opaque_types
.iter()
.cloned()
.map(|opaque| opaque.try_fold_with(folder))
.collect::<Result<_, F::Error>>()?,
normalization_nested_goals: self
.normalization_nested_goals
.clone()
.try_fold_with(folder)?,
},
))
}
fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
ExternalConstraints::new(
folder.cx(),
ExternalConstraintsData {
region_constraints: self.region_constraints.clone().fold_with(folder),
opaque_types: self
.opaque_types
.iter()
.cloned()
.map(|opaque| opaque.fold_with(folder))
.collect(),
normalization_nested_goals: self
.normalization_nested_goals
.clone()
.fold_with(folder),
},
)
}
}