@@ -48,161 +48,173 @@ use rustc_hir::def_id::DefId;
48
48
49
49
use std:: collections:: BTreeMap ;
50
50
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 } ;
76
52
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 } ;
97
55
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
+ }
119
83
}
120
84
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
+ }
123
104
}
124
105
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
+ }
128
124
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
+ }
133
128
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
+ }
143
132
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
+ }
145
136
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
+ }
151
140
}
152
141
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 ;
156
151
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 > ;
160
153
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
+ }
164
160
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
+ }
172
164
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
+ }
180
171
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
+ }
183
182
}
184
183
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
186
187
where
187
- T : TypeFoldable < ' tcx > ,
188
+ F : TypeFolder < ' tcx > ,
188
189
{
189
- Ok ( self . fold_binder ( t) )
190
- }
190
+ type Error = !;
191
191
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
+ }
195
195
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
+ }
199
202
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
+ }
203
214
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
+ }
206
218
}
207
219
}
208
220
0 commit comments