Skip to content

Commit 62846d7

Browse files
committed
Move folding & visiting traits to ir submodules
1 parent 2008188 commit 62846d7

File tree

3 files changed

+322
-292
lines changed

3 files changed

+322
-292
lines changed

compiler/rustc_middle/src/ty/fold.rs

Lines changed: 142 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -48,161 +48,173 @@ use rustc_hir::def_id::DefId;
4848

4949
use std::collections::BTreeMap;
5050

51-
/// This trait is implemented for every type that can be folded,
52-
/// providing the skeleton of the traversal.
53-
///
54-
/// To implement this conveniently, use the derive macro located in
55-
/// `rustc_macros`.
56-
pub trait TypeFoldable<'tcx>: TypeVisitable<'tcx> {
57-
/// The entry point for folding. To fold a value `t` with a folder `f`
58-
/// call: `t.try_fold_with(f)`.
59-
///
60-
/// For most types, this just traverses the value, calling `try_fold_with`
61-
/// on each field/element.
62-
///
63-
/// For types of interest (such as `Ty`), the implementation of method
64-
/// calls a folder method specifically for that type (such as
65-
/// `F::try_fold_ty`). This is where control transfers from `TypeFoldable`
66-
/// to `TypeFolder`.
67-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error>;
68-
69-
/// A convenient alternative to `try_fold_with` for use with infallible
70-
/// folders. Do not override this method, to ensure coherence with
71-
/// `try_fold_with`.
72-
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
73-
self.try_fold_with(folder).into_ok()
74-
}
75-
}
51+
pub use ir::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
7652

77-
// This trait is implemented for types of interest.
78-
pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> {
79-
/// Provides a default fold for a type of interest. This should only be
80-
/// called within `TypeFolder` methods, when a non-custom traversal is
81-
/// desired for the value of the type of interest passed to that method.
82-
/// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call
83-
/// `ty.try_super_fold_with(self)`, but any other folding should be done
84-
/// with `xyz.try_fold_with(self)`.
85-
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
86-
self,
87-
folder: &mut F,
88-
) -> Result<Self, F::Error>;
89-
90-
/// A convenient alternative to `try_super_fold_with` for use with
91-
/// infallible folders. Do not override this method, to ensure coherence
92-
/// with `try_super_fold_with`.
93-
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
94-
self.try_super_fold_with(folder).into_ok()
95-
}
96-
}
53+
pub mod ir {
54+
use crate::ty::{self, ir::TypeVisitable, Binder, Ty, TyCtxt};
9755

98-
/// This trait is implemented for every infallible folding traversal. There is
99-
/// a fold method defined for every type of interest. Each such method has a
100-
/// default that does an "identity" fold. Implementations of these methods
101-
/// often fall back to a `super_fold_with` method if the primary argument
102-
/// doesn't satisfy a particular condition.
103-
///
104-
/// A blanket implementation of [`FallibleTypeFolder`] will defer to
105-
/// the infallible methods of this trait to ensure that the two APIs
106-
/// are coherent.
107-
pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> {
108-
fn tcx(&self) -> TyCtxt<'tcx>;
109-
110-
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T>
111-
where
112-
T: TypeFoldable<'tcx>,
113-
{
114-
t.super_fold_with(self)
115-
}
116-
117-
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
118-
t.super_fold_with(self)
56+
/// This trait is implemented for every type that can be folded,
57+
/// providing the skeleton of the traversal.
58+
///
59+
/// To implement this conveniently, use the derive macro located in
60+
/// `rustc_macros`.
61+
pub trait TypeFoldable<'tcx>: TypeVisitable<'tcx> {
62+
/// The entry point for folding. To fold a value `t` with a folder `f`
63+
/// call: `t.try_fold_with(f)`.
64+
///
65+
/// For most types, this just traverses the value, calling `try_fold_with`
66+
/// on each field/element.
67+
///
68+
/// For types of interest (such as `Ty`), the implementation of method
69+
/// calls a folder method specifically for that type (such as
70+
/// `F::try_fold_ty`). This is where control transfers from `TypeFoldable`
71+
/// to `TypeFolder`.
72+
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
73+
self,
74+
folder: &mut F,
75+
) -> Result<Self, F::Error>;
76+
77+
/// A convenient alternative to `try_fold_with` for use with infallible
78+
/// folders. Do not override this method, to ensure coherence with
79+
/// `try_fold_with`.
80+
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
81+
self.try_fold_with(folder).into_ok()
82+
}
11983
}
12084

121-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
122-
r.super_fold_with(self)
85+
// This trait is implemented for types of interest.
86+
pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> {
87+
/// Provides a default fold for a type of interest. This should only be
88+
/// called within `TypeFolder` methods, when a non-custom traversal is
89+
/// desired for the value of the type of interest passed to that method.
90+
/// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call
91+
/// `ty.try_super_fold_with(self)`, but any other folding should be done
92+
/// with `xyz.try_fold_with(self)`.
93+
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
94+
self,
95+
folder: &mut F,
96+
) -> Result<Self, F::Error>;
97+
98+
/// A convenient alternative to `try_super_fold_with` for use with
99+
/// infallible folders. Do not override this method, to ensure coherence
100+
/// with `try_super_fold_with`.
101+
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
102+
self.try_super_fold_with(folder).into_ok()
103+
}
123104
}
124105

125-
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
126-
c.super_fold_with(self)
127-
}
106+
/// This trait is implemented for every infallible folding traversal. There is
107+
/// a fold method defined for every type of interest. Each such method has a
108+
/// default that does an "identity" fold. Implementations of these methods
109+
/// often fall back to a `super_fold_with` method if the primary argument
110+
/// doesn't satisfy a particular condition.
111+
///
112+
/// A blanket implementation of [`FallibleTypeFolder`] will defer to
113+
/// the infallible methods of this trait to ensure that the two APIs
114+
/// are coherent.
115+
pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> {
116+
fn tcx(&self) -> TyCtxt<'tcx>;
117+
118+
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T>
119+
where
120+
T: TypeFoldable<'tcx>,
121+
{
122+
t.super_fold_with(self)
123+
}
128124

129-
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
130-
p.super_fold_with(self)
131-
}
132-
}
125+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
126+
t.super_fold_with(self)
127+
}
133128

134-
/// This trait is implemented for every folding traversal. There is a fold
135-
/// method defined for every type of interest. Each such method has a default
136-
/// that does an "identity" fold.
137-
///
138-
/// A blanket implementation of this trait (that defers to the relevant
139-
/// method of [`TypeFolder`]) is provided for all infallible folders in
140-
/// order to ensure the two APIs are coherent.
141-
pub trait FallibleTypeFolder<'tcx>: Sized {
142-
type Error;
129+
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
130+
r.super_fold_with(self)
131+
}
143132

144-
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
133+
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
134+
c.super_fold_with(self)
135+
}
145136

146-
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
147-
where
148-
T: TypeFoldable<'tcx>,
149-
{
150-
t.try_super_fold_with(self)
137+
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
138+
p.super_fold_with(self)
139+
}
151140
}
152141

153-
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
154-
t.try_super_fold_with(self)
155-
}
142+
/// This trait is implemented for every folding traversal. There is a fold
143+
/// method defined for every type of interest. Each such method has a default
144+
/// that does an "identity" fold.
145+
///
146+
/// A blanket implementation of this trait (that defers to the relevant
147+
/// method of [`TypeFolder`]) is provided for all infallible folders in
148+
/// order to ensure the two APIs are coherent.
149+
pub trait FallibleTypeFolder<'tcx>: Sized {
150+
type Error;
156151

157-
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
158-
r.try_super_fold_with(self)
159-
}
152+
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
160153

161-
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
162-
c.try_super_fold_with(self)
163-
}
154+
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
155+
where
156+
T: TypeFoldable<'tcx>,
157+
{
158+
t.try_super_fold_with(self)
159+
}
164160

165-
fn try_fold_predicate(
166-
&mut self,
167-
p: ty::Predicate<'tcx>,
168-
) -> Result<ty::Predicate<'tcx>, Self::Error> {
169-
p.try_super_fold_with(self)
170-
}
171-
}
161+
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
162+
t.try_super_fold_with(self)
163+
}
172164

173-
// This blanket implementation of the fallible trait for infallible folders
174-
// delegates to infallible methods to ensure coherence.
175-
impl<'tcx, F> FallibleTypeFolder<'tcx> for F
176-
where
177-
F: TypeFolder<'tcx>,
178-
{
179-
type Error = !;
165+
fn try_fold_region(
166+
&mut self,
167+
r: ty::Region<'tcx>,
168+
) -> Result<ty::Region<'tcx>, Self::Error> {
169+
r.try_super_fold_with(self)
170+
}
180171

181-
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
182-
TypeFolder::tcx(self)
172+
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
173+
c.try_super_fold_with(self)
174+
}
175+
176+
fn try_fold_predicate(
177+
&mut self,
178+
p: ty::Predicate<'tcx>,
179+
) -> Result<ty::Predicate<'tcx>, Self::Error> {
180+
p.try_super_fold_with(self)
181+
}
183182
}
184183

185-
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, !>
184+
// This blanket implementation of the fallible trait for infallible folders
185+
// delegates to infallible methods to ensure coherence.
186+
impl<'tcx, F> FallibleTypeFolder<'tcx> for F
186187
where
187-
T: TypeFoldable<'tcx>,
188+
F: TypeFolder<'tcx>,
188189
{
189-
Ok(self.fold_binder(t))
190-
}
190+
type Error = !;
191191

192-
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
193-
Ok(self.fold_ty(t))
194-
}
192+
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
193+
TypeFolder::tcx(self)
194+
}
195195

196-
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
197-
Ok(self.fold_region(r))
198-
}
196+
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, !>
197+
where
198+
T: TypeFoldable<'tcx>,
199+
{
200+
Ok(self.fold_binder(t))
201+
}
199202

200-
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, !> {
201-
Ok(self.fold_const(c))
202-
}
203+
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
204+
Ok(self.fold_ty(t))
205+
}
206+
207+
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
208+
Ok(self.fold_region(r))
209+
}
210+
211+
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, !> {
212+
Ok(self.fold_const(c))
213+
}
203214

204-
fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result<ty::Predicate<'tcx>, !> {
205-
Ok(self.fold_predicate(p))
215+
fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result<ty::Predicate<'tcx>, !> {
216+
Ok(self.fold_predicate(p))
217+
}
206218
}
207219
}
208220

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ mod structural_impls;
146146
mod sty;
147147
mod typeck_results;
148148

149+
pub mod ir {
150+
pub use super::{fold::ir::*, visit::ir::*};
151+
}
152+
149153
// Data types
150154

151155
pub type RegisteredTools = FxHashSet<Ident>;

0 commit comments

Comments
 (0)