@@ -48,161 +48,173 @@ use rustc_hir::def_id::DefId;
4848
4949use 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
0 commit comments