@@ -140,79 +140,21 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
140140 }
141141 }
142142
143+ #[ inline]
143144 fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
144145 if !t. needs_infer ( ) && !t. has_erasable_regions ( ) {
145- return t;
146- }
147-
148- let tcx = self . infcx . tcx ;
149-
150- match * t. kind ( ) {
151- ty:: Infer ( ty:: TyVar ( v) ) => {
152- let opt_ty = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . probe ( v) . known ( ) ;
153- self . freshen_ty ( opt_ty, ty:: TyVar ( v) , ty:: FreshTy )
154- }
146+ t
147+ } else {
148+ match * t. kind ( ) {
149+ ty:: Infer ( v) => self . fold_infer_ty ( v) . unwrap_or ( t) ,
155150
156- ty:: Infer ( ty:: IntVar ( v) ) => self . freshen_ty (
157- self . infcx
158- . inner
159- . borrow_mut ( )
160- . int_unification_table ( )
161- . probe_value ( v)
162- . map ( |v| v. to_type ( tcx) ) ,
163- ty:: IntVar ( v) ,
164- ty:: FreshIntTy ,
165- ) ,
151+ // This code is hot enough that a non-debug assertion here makes a noticeable
152+ // difference on benchmarks like `wg-grammar`.
153+ #[ cfg( debug_assertions) ]
154+ ty:: Placeholder ( ..) | ty:: Bound ( ..) => bug ! ( "unexpected type {:?}" , t) ,
166155
167- ty:: Infer ( ty:: FloatVar ( v) ) => self . freshen_ty (
168- self . infcx
169- . inner
170- . borrow_mut ( )
171- . float_unification_table ( )
172- . probe_value ( v)
173- . map ( |v| v. to_type ( tcx) ) ,
174- ty:: FloatVar ( v) ,
175- ty:: FreshFloatTy ,
176- ) ,
177-
178- ty:: Infer ( ty:: FreshTy ( ct) | ty:: FreshIntTy ( ct) | ty:: FreshFloatTy ( ct) ) => {
179- if ct >= self . ty_freshen_count {
180- bug ! (
181- "Encountered a freshend type with id {} \
182- but our counter is only at {}",
183- ct,
184- self . ty_freshen_count
185- ) ;
186- }
187- t
156+ _ => t. super_fold_with ( self ) ,
188157 }
189-
190- ty:: Generator ( ..)
191- | ty:: Bool
192- | ty:: Char
193- | ty:: Int ( ..)
194- | ty:: Uint ( ..)
195- | ty:: Float ( ..)
196- | ty:: Adt ( ..)
197- | ty:: Str
198- | ty:: Error ( _)
199- | ty:: Array ( ..)
200- | ty:: Slice ( ..)
201- | ty:: RawPtr ( ..)
202- | ty:: Ref ( ..)
203- | ty:: FnDef ( ..)
204- | ty:: FnPtr ( _)
205- | ty:: Dynamic ( ..)
206- | ty:: Never
207- | ty:: Tuple ( ..)
208- | ty:: Alias ( ..)
209- | ty:: Foreign ( ..)
210- | ty:: Param ( ..)
211- | ty:: Closure ( ..)
212- | ty:: GeneratorWitnessMIR ( ..)
213- | ty:: GeneratorWitness ( ..) => t. super_fold_with ( self ) ,
214-
215- ty:: Placeholder ( ..) | ty:: Bound ( ..) => bug ! ( "unexpected type {:?}" , t) ,
216158 }
217159 }
218160
@@ -253,3 +195,54 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
253195 }
254196 }
255197}
198+
199+ impl < ' a , ' tcx > TypeFreshener < ' a , ' tcx > {
200+ // This is separate from `fold_ty` to keep that method small and inlinable.
201+ #[ inline( never) ]
202+ fn fold_infer_ty ( & mut self , v : ty:: InferTy ) -> Option < Ty < ' tcx > > {
203+ match v {
204+ ty:: TyVar ( v) => {
205+ let opt_ty = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . probe ( v) . known ( ) ;
206+ Some ( self . freshen_ty ( opt_ty, ty:: TyVar ( v) , ty:: FreshTy ) )
207+ }
208+
209+ ty:: IntVar ( v) => Some (
210+ self . freshen_ty (
211+ self . infcx
212+ . inner
213+ . borrow_mut ( )
214+ . int_unification_table ( )
215+ . probe_value ( v)
216+ . map ( |v| v. to_type ( self . infcx . tcx ) ) ,
217+ ty:: IntVar ( v) ,
218+ ty:: FreshIntTy ,
219+ ) ,
220+ ) ,
221+
222+ ty:: FloatVar ( v) => Some (
223+ self . freshen_ty (
224+ self . infcx
225+ . inner
226+ . borrow_mut ( )
227+ . float_unification_table ( )
228+ . probe_value ( v)
229+ . map ( |v| v. to_type ( self . infcx . tcx ) ) ,
230+ ty:: FloatVar ( v) ,
231+ ty:: FreshFloatTy ,
232+ ) ,
233+ ) ,
234+
235+ ty:: FreshTy ( ct) | ty:: FreshIntTy ( ct) | ty:: FreshFloatTy ( ct) => {
236+ if ct >= self . ty_freshen_count {
237+ bug ! (
238+ "Encountered a freshend type with id {} \
239+ but our counter is only at {}",
240+ ct,
241+ self . ty_freshen_count
242+ ) ;
243+ }
244+ None
245+ }
246+ }
247+ }
248+ }
0 commit comments