@@ -220,6 +220,15 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
220
220
// and small enough to prevent hangs.
221
221
const STARTING_DEPTH : usize = 8 ;
222
222
223
+ #[ inline( always) ]
224
+ pub fn inlined_args_may_unify (
225
+ self ,
226
+ obligation_args : I :: GenericArgs ,
227
+ impl_args : I :: GenericArgs ,
228
+ ) -> bool {
229
+ self . inlined_args_may_unify_inner ( obligation_args, impl_args, Self :: STARTING_DEPTH )
230
+ }
231
+
223
232
pub fn args_may_unify (
224
233
self ,
225
234
obligation_args : I :: GenericArgs ,
@@ -228,32 +237,59 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
228
237
self . args_may_unify_inner ( obligation_args, impl_args, Self :: STARTING_DEPTH )
229
238
}
230
239
231
- pub fn types_may_unify ( self , lhs : I :: Ty , rhs : I :: Ty ) -> bool {
232
- self . types_may_unify_inner ( lhs, rhs, Self :: STARTING_DEPTH )
240
+ #[ inline( always) ]
241
+ fn inlined_arg_may_unify ( self , obl : I :: GenericArg , imp : I :: GenericArg , depth : usize ) -> bool {
242
+ match ( obl. kind ( ) , imp. kind ( ) ) {
243
+ // We don't fast reject based on regions.
244
+ ( ty:: GenericArgKind :: Lifetime ( _) , ty:: GenericArgKind :: Lifetime ( _) ) => true ,
245
+ ( ty:: GenericArgKind :: Type ( obl) , ty:: GenericArgKind :: Type ( imp) ) => {
246
+ self . types_may_unify_inner ( obl, imp, depth)
247
+ }
248
+ ( ty:: GenericArgKind :: Const ( obl) , ty:: GenericArgKind :: Const ( imp) ) => {
249
+ self . consts_may_unify_inner ( obl, imp)
250
+ }
251
+ _ => panic ! ( "kind mismatch: {obl:?} {imp:?}" ) ,
252
+ }
253
+ }
254
+
255
+ fn arg_may_unify ( self , obl : I :: GenericArg , imp : I :: GenericArg , depth : usize ) -> bool {
256
+ self . inlined_arg_may_unify ( obl, imp, depth)
233
257
}
234
258
235
259
fn args_may_unify_inner (
236
260
self ,
237
261
obligation_args : I :: GenericArgs ,
238
262
impl_args : I :: GenericArgs ,
239
263
depth : usize ,
264
+ ) -> bool {
265
+ iter:: zip ( obligation_args. iter ( ) , impl_args. iter ( ) )
266
+ . all ( |( obl, imp) | self . arg_may_unify ( obl, imp, depth) )
267
+ }
268
+
269
+ #[ inline( always) ]
270
+ fn inlined_args_may_unify_inner (
271
+ self ,
272
+ obligation_args : I :: GenericArgs ,
273
+ impl_args : I :: GenericArgs ,
274
+ depth : usize ,
240
275
) -> bool {
241
276
// No need to decrement the depth here as this function is only
242
277
// recursively reachable via `types_may_unify_inner` which already
243
278
// increments the depth for us.
244
- iter:: zip ( obligation_args. iter ( ) , impl_args. iter ( ) ) . all ( |( obl, imp) | {
245
- match ( obl. kind ( ) , imp. kind ( ) ) {
246
- // We don't fast reject based on regions.
247
- ( ty:: GenericArgKind :: Lifetime ( _) , ty:: GenericArgKind :: Lifetime ( _) ) => true ,
248
- ( ty:: GenericArgKind :: Type ( obl) , ty:: GenericArgKind :: Type ( imp) ) => {
249
- self . types_may_unify_inner ( obl, imp, depth)
250
- }
251
- ( ty:: GenericArgKind :: Const ( obl) , ty:: GenericArgKind :: Const ( imp) ) => {
252
- self . consts_may_unify_inner ( obl, imp)
253
- }
254
- _ => panic ! ( "kind mismatch: {obl:?} {imp:?}" ) ,
255
- }
256
- } )
279
+
280
+ // The len==1 case accounts for 99.9% of occurrences in the benchmarks
281
+ // where this code is hot, e.g. `bitmaps-3.1.0` and `typenum-1.17.0`.
282
+ if obligation_args. len ( ) == 1 {
283
+ let obl = obligation_args. as_slice ( ) [ 0 ] ;
284
+ let imp = impl_args. as_slice ( ) [ 0 ] ;
285
+ self . inlined_arg_may_unify ( obl, imp, depth)
286
+ } else {
287
+ self . args_may_unify_inner ( obligation_args, impl_args, depth)
288
+ }
289
+ }
290
+
291
+ pub fn types_may_unify ( self , lhs : I :: Ty , rhs : I :: Ty ) -> bool {
292
+ self . types_may_unify_inner ( lhs, rhs, Self :: STARTING_DEPTH )
257
293
}
258
294
259
295
fn types_may_unify_inner ( self , lhs : I :: Ty , rhs : I :: Ty , depth : usize ) -> bool {
@@ -320,7 +356,9 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
320
356
321
357
ty:: Adt ( lhs_def, lhs_args) => match rhs. kind ( ) {
322
358
ty:: Adt ( rhs_def, rhs_args) => {
323
- lhs_def == rhs_def && self . args_may_unify_inner ( lhs_args, rhs_args, depth)
359
+ // This call site can be hot.
360
+ lhs_def == rhs_def
361
+ && self . inlined_args_may_unify_inner ( lhs_args, rhs_args, depth)
324
362
}
325
363
_ => false ,
326
364
} ,
0 commit comments