| use rustc_data_structures::intern::Interned; | |
| use rustc_macros::HashStable; | |
| use rustc_type_ir as ir; | |
| pub use rustc_type_ir::solve::*; | |
| use crate::ty::{ | |
| self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, | |
| try_visit, | |
| }; | |
| pub type Goal<'tcx, P> = ir::solve::Goal<TyCtxt<'tcx>, P>; | |
| pub type QueryInput<'tcx, P> = ir::solve::QueryInput<TyCtxt<'tcx>, P>; | |
| pub type QueryResult<'tcx> = ir::solve::QueryResult<TyCtxt<'tcx>>; | |
| pub type CandidateSource<'tcx> = ir::solve::CandidateSource<TyCtxt<'tcx>>; | |
| pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir::solve::CanonicalInput<TyCtxt<'tcx>, P>; | |
| pub type CanonicalResponse<'tcx> = ir::solve::CanonicalResponse<TyCtxt<'tcx>>; | |
| pub type PredefinedOpaques<'tcx> = &'tcx ty::List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>; | |
| #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)] | |
| pub struct ExternalConstraints<'tcx>( | |
| pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>, | |
| ); | |
| impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> { | |
| type Target = ExternalConstraintsData<TyCtxt<'tcx>>; | |
| fn deref(&self) -> &Self::Target { | |
| &self.0 | |
| } | |
| } | |
| // 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<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { | |
| fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( | |
| self, | |
| folder: &mut F, | |
| ) -> Result<Self, F::Error> { | |
| // Perf testing has found that this check is slightly faster than | |
| // folding and re-interning an empty `ExternalConstraintsData`. | |
| // See: <https://github.com/rust-lang/rust/pull/142430>. | |
| if self.is_empty() { | |
| return Ok(self); | |
| } | |
| Ok(FallibleTypeFolder::cx(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::<Result<_, F::Error>>()?, | |
| normalization_nested_goals: self | |
| .normalization_nested_goals | |
| .clone() | |
| .try_fold_with(folder)?, | |
| })) | |
| } | |
| fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self { | |
| // Perf testing has found that this check is slightly faster than | |
| // folding and re-interning an empty `ExternalConstraintsData`. | |
| // See: <https://github.com/rust-lang/rust/pull/142430>. | |
| if self.is_empty() { | |
| return self; | |
| } | |
| TypeFolder::cx(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(), | |
| normalization_nested_goals: self.normalization_nested_goals.clone().fold_with(folder), | |
| }) | |
| } | |
| } | |
| impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { | |
| fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&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) | |
| } | |
| } |