diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cc378f1ea47c..ae2ab2b02521 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -265,6 +265,10 @@ impl<'tcx> AssociatedItems<'tcx> { self.items.iter().map(|(_, v)| *v) } + pub fn len(&self) -> usize { + self.items.len() + } + /// Returns an iterator over all associated items with the given name, ignoring hygiene. pub fn filter_by_name_unhygienic( &self, diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs index be77d049cae4..673cddbdb5f2 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs @@ -22,6 +22,14 @@ impl InherentOverlapChecker<'tcx> { let impl_items1 = self.tcx.associated_items(impl1); let impl_items2 = self.tcx.associated_items(impl2); + let mut impl_items1 = &impl_items1; + let mut impl_items2 = &impl_items2; + + // Performance optimization: iterate over the smaller list + if impl_items1.len() > impl_items2.len() { + std::mem::swap(&mut impl_items1, &mut impl_items2); + } + for item1 in impl_items1.in_definition_order() { let collision = impl_items2.filter_by_name_unhygienic(item1.ident.name).any(|item2| { // Symbols and namespace match, compare hygienically.