use std::ops::ControlFlow; use rustc_data_structures::intern::Interned; use crate::infer::canonical::QueryRegionConstraints; use crate::ty::{ FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>); impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> { type Target = ExternalConstraintsData<'tcx>; fn deref(&self) -> &Self::Target { &*self.0 } } /// Additional constraints returned on success. #[derive(Debug, PartialEq, Eq, Clone, Hash, Default, TypeFoldable, TypeVisitable)] pub struct ExternalConstraintsData<'tcx> { // FIXME: implement this. pub region_constraints: QueryRegionConstraints<'tcx>, pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, } // FIXME: Having to clone `region_constraints` for folding feels bad and // probably isn't great wrt performance. // // Not sure how to fix this, maybe we should also intern `opaque_types` and // `region_constraints` here or something. impl<'tcx> TypeFoldable> for ExternalConstraints<'tcx> { fn try_fold_with>>( self, folder: &mut F, ) -> Result { Ok(FallibleTypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { region_constraints: self.region_constraints.clone().try_fold_with(folder)?, opaque_types: self .opaque_types .iter() .map(|opaque| opaque.try_fold_with(folder)) .collect::>()?, })) } fn fold_with>>(self, folder: &mut F) -> Self { TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { region_constraints: self.region_constraints.clone().fold_with(folder), opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), }) } } impl<'tcx> TypeVisitable> for ExternalConstraints<'tcx> { fn visit_with>>( &self, visitor: &mut V, ) -> std::ops::ControlFlow { self.region_constraints.visit_with(visitor)?; self.opaque_types.visit_with(visitor)?; ControlFlow::Continue(()) } }