Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
}

impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
#[inline]
fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
Expand Down Expand Up @@ -419,6 +420,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
Ok(if *self.kind() == kind { self } else { folder.cx().mk_ty_from_kind(kind) })
}

#[inline]
fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
let kind = match *self.kind() {
ty::RawPtr(ty, mutbl) => ty::RawPtr(ty.fold_with(folder), mutbl),
Expand Down Expand Up @@ -460,6 +462,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
}

impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
#[inline]
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
match self.kind() {
ty::RawPtr(ty, _mutbl) => ty.visit_with(visitor),
Expand Down Expand Up @@ -582,6 +585,7 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
}

impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
#[inline]
fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
Expand All @@ -590,13 +594,15 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
Ok(folder.cx().reuse_or_mk_predicate(self, new))
}

#[inline]
fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
let new = self.kind().fold_with(folder);
folder.cx().reuse_or_mk_predicate(self, new)
}
}

impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
#[inline]
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
self.kind().visit_with(visitor)
}
Expand All @@ -609,19 +615,22 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
}

impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
#[inline]
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
self.as_slice().visit_with(visitor)
}
}

impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
#[inline]
fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
ty::util::try_fold_list(self, folder, |tcx, v| tcx.mk_clauses(v))
}

#[inline]
fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
ty::util::fold_list(self, folder, |tcx, v| tcx.mk_clauses(v))
}
Expand All @@ -647,6 +656,7 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
}

impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
#[inline]
fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
Expand All @@ -665,6 +675,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
if kind != self.kind() { Ok(folder.cx().mk_ct_from_kind(kind)) } else { Ok(self) }
}

#[inline]
fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
let kind = match self.kind() {
ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.fold_with(folder)),
Expand All @@ -682,6 +693,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
}

impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
#[inline]
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
match self.kind() {
ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_type_ir/src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,22 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Binder<I, T> {
}

impl<I: Interner, T: TypeFoldable<I>> TypeSuperFoldable<I> for Binder<I, T> {
#[inline]
fn try_super_fold_with<F: FallibleTypeFolder<I>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_bound(|t| t.try_fold_with(folder))
}

#[inline]
fn super_fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
self.map_bound(|t| t.fold_with(folder))
}
}

impl<I: Interner, T: TypeVisitable<I>> TypeSuperVisitable<I> for Binder<I, T> {
#[inline]
fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
self.as_ref().skip_binder().visit_with(visitor)
}
Expand Down
11 changes: 1 addition & 10 deletions compiler/rustc_type_ir/src/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> {
) -> Result<Self, F::Error>;

/// A convenient alternative to `try_super_fold_with` for use with
/// infallible folders. Do not override this method, to ensure coherence
/// with `try_super_fold_with`.
/// infallible folders.
fn super_fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self;
}

Expand All @@ -121,10 +120,6 @@ pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> {
/// default that does an "identity" fold. Implementations of these methods
/// often fall back to a `super_fold_with` method if the primary argument
/// doesn't satisfy a particular condition.
///
/// A blanket implementation of [`FallibleTypeFolder`] will defer to
/// the infallible methods of this trait to ensure that the two APIs
/// are coherent.
pub trait TypeFolder<I: Interner>: Sized {
fn cx(&self) -> I;

Expand Down Expand Up @@ -161,10 +156,6 @@ pub trait TypeFolder<I: Interner>: Sized {
/// This trait is implemented for every folding traversal. There is a fold
/// method defined for every type of interest. Each such method has a default
/// that does an "identity" fold.
///
/// A blanket implementation of this trait (that defers to the relevant
/// method of [`TypeFolder`]) is provided for all infallible folders in
/// order to ensure the two APIs are coherent.
pub trait FallibleTypeFolder<I: Interner>: Sized {
type Error;

Expand Down
Loading