@@ -220,6 +220,15 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
220220 // and small enough to prevent hangs.
221221 const STARTING_DEPTH : usize = 8 ;
222222
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+
223232 pub fn args_may_unify (
224233 self ,
225234 obligation_args : I :: GenericArgs ,
@@ -228,32 +237,59 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
228237 self . args_may_unify_inner ( obligation_args, impl_args, Self :: STARTING_DEPTH )
229238 }
230239
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)
233257 }
234258
235259 fn args_may_unify_inner (
236260 self ,
237261 obligation_args : I :: GenericArgs ,
238262 impl_args : I :: GenericArgs ,
239263 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 ,
240275 ) -> bool {
241276 // No need to decrement the depth here as this function is only
242277 // recursively reachable via `types_may_unify_inner` which already
243278 // 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 )
257293 }
258294
259295 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_
320356
321357 ty:: Adt ( lhs_def, lhs_args) => match rhs. kind ( ) {
322358 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)
324362 }
325363 _ => false ,
326364 } ,
0 commit comments