From 76b60efbfb8cdc94cf14fef1be50c60f250bc293 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 29 Aug 2021 18:49:16 +0300 Subject: [PATCH 1/2] internal: improve compile times a bit before after for cargo llvm-lines -q --lib --release -p ide_ssr | head -n 24 Lines Copies Function name ----- ------ ------------- 297146 (100%) 12748 (100%) (TOTAL) 5970 (2.0%) 47 (0.4%) core::iter::traits::iterator::Iterator::try_fold 4750 (1.6%) 27 (0.2%) hashbrown::raw::RawTable::resize 4080 (1.4%) 30 (0.2%) alloc::raw_vec::RawVec::grow_amortized 3933 (1.3%) 69 (0.5%) alloc::raw_vec::RawVec::current_memory 3668 (1.2%) 89 (0.7%) as core::ops::try_trait::Try>::branch 3500 (1.2%) 50 (0.4%) hashbrown::raw::RawTable::drop_elements 3436 (1.2%) 33 (0.3%) hashbrown::raw::RawTable::find 3415 (1.1%) 17 (0.1%) hashbrown::raw::RawTable::rehash_in_place 3400 (1.1%) 50 (0.4%) as core::iter::traits::iterator::Iterator>::next 2840 (1.0%) 20 (0.2%) alloc::raw_vec::RawVec::allocate_in 2700 (0.9%) 30 (0.2%) core::alloc::layout::Layout::array 2666 (0.9%) 86 (0.7%) core::ptr::metadata::from_raw_parts_mut 2495 (0.8%) 50 (0.4%) core::option::Option::map 2354 (0.8%) 38 (0.3%) alloc::alloc::box_free 2302 (0.8%) 7 (0.1%) ide_ssr::parsing::RuleBuilder::try_add 2146 (0.7%) 45 (0.4%) core::mem::replace 2070 (0.7%) 69 (0.5%) as core::ops::drop::Drop>::drop 1979 (0.7%) 16 (0.1%) hashbrown::map::HashMap::insert 1926 (0.6%) 18 (0.1%) as core::iter::adapters::zip::ZipImpl>::next 1922 (0.6%) 62 (0.5%) core::fmt::ArgumentV1::new 1885 (0.6%) 13 (0.1%) alloc::raw_vec::RawVec::shrink Lines Copies Function name ----- ------ ------------- 261717 (100%) 11666 (100%) (TOTAL) 5239 (2.0%) 42 (0.4%) core::iter::traits::iterator::Iterator::try_fold 4750 (1.8%) 27 (0.2%) hashbrown::raw::RawTable::resize 3933 (1.5%) 69 (0.6%) alloc::raw_vec::RawVec::current_memory 3536 (1.4%) 26 (0.2%) alloc::raw_vec::RawVec::grow_amortized 3500 (1.3%) 50 (0.4%) hashbrown::raw::RawTable::drop_elements 3400 (1.3%) 50 (0.4%) as core::iter::traits::iterator::Iterator>::next 3124 (1.2%) 30 (0.3%) hashbrown::raw::RawTable::find 2812 (1.1%) 14 (0.1%) hashbrown::raw::RawTable::rehash_in_place 2604 (1.0%) 84 (0.7%) core::ptr::metadata::from_raw_parts_mut 2340 (0.9%) 26 (0.2%) core::alloc::layout::Layout::array 2302 (0.9%) 7 (0.1%) ide_ssr::parsing::RuleBuilder::try_add 2272 (0.9%) 16 (0.1%) alloc::raw_vec::RawVec::allocate_in 2201 (0.8%) 35 (0.3%) alloc::alloc::box_free 2104 (0.8%) 44 (0.4%) core::mem::replace 2079 (0.8%) 42 (0.4%) as core::ops::try_trait::Try>::branch 2070 (0.8%) 69 (0.6%) as core::ops::drop::Drop>::drop 1926 (0.7%) 18 (0.2%) as core::iter::adapters::zip::ZipImpl>::next 1885 (0.7%) 13 (0.1%) alloc::raw_vec::RawVec::shrink 1833 (0.7%) 13 (0.1%) hashbrown::raw::RawTable::shrink_to 1771 (0.7%) 91 (0.8%) core::ptr::read 1701 (0.6%) 35 (0.3%) core::option::Option::map --- crates/hir/src/lib.rs | 87 ++++++++++++++++++++++---- crates/hir_ty/src/method_resolution.rs | 6 +- 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index a968b59bfe..6383a467eb 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2517,18 +2517,35 @@ impl Type { krate: Crate, mut callback: impl FnMut(AssocItem) -> Option, ) -> Option { - for krate in method_resolution::def_crates(db, &self.ty, krate.id)? { + let mut slot = None; + self.iterate_assoc_items_dyn(db, krate, &mut |assoc_item_id| { + slot = callback(assoc_item_id.into()); + slot.is_some() + }); + slot + } + + fn iterate_assoc_items_dyn( + self, + db: &dyn HirDatabase, + krate: Crate, + callback: &mut dyn FnMut(AssocItemId) -> bool, + ) { + let def_crates = match method_resolution::def_crates(db, &self.ty, krate.id) { + Some(it) => it, + None => return, + }; + for krate in def_crates { let impls = db.inherent_impls_in_crate(krate); for impl_def in impls.for_self_ty(&self.ty) { for &item in db.impl_data(*impl_def).items.iter() { - if let Some(result) = callback(item.into()) { - return Some(result); + if callback(item) { + return; } } } } - None } pub fn type_arguments(&self) -> impl Iterator + '_ { @@ -2550,6 +2567,31 @@ impl Type { mut callback: impl FnMut(&Ty, Function) -> Option, ) -> Option { let _p = profile::span("iterate_method_candidates"); + let mut slot = None; + self.iterate_method_candidates_dyn( + db, + krate, + traits_in_scope, + name, + &mut |ty, assoc_item_id| match assoc_item_id { + AssocItemId::FunctionId(it) => { + slot = callback(ty, it.into()); + slot.is_some() + } + AssocItemId::ConstId(_) | AssocItemId::TypeAliasId(_) => false, + }, + ); + slot + } + + fn iterate_method_candidates_dyn( + &self, + db: &dyn HirDatabase, + krate: Crate, + traits_in_scope: &FxHashSet, + name: Option<&Name>, + callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, + ) { // There should be no inference vars in types passed here // FIXME check that? // FIXME replace Unknown by bound vars here @@ -2559,7 +2601,7 @@ impl Type { let env = self.env.clone(); let krate = krate.id; - method_resolution::iterate_method_candidates( + method_resolution::iterate_method_candidates_dyn( &canonical, db, env, @@ -2568,11 +2610,8 @@ impl Type { None, name, method_resolution::LookupMode::MethodCall, - |ty, it| match it { - AssocItemId::FunctionId(f) => callback(ty, f.into()), - _ => None, - }, - ) + callback, + ); } pub fn iterate_path_candidates( @@ -2584,12 +2623,34 @@ impl Type { mut callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { let _p = profile::span("iterate_path_candidates"); + let mut slot = None; + self.iterate_path_candidates_dyn( + db, + krate, + traits_in_scope, + name, + &mut |ty, assoc_item_id| { + slot = callback(ty, assoc_item_id.into()); + slot.is_some() + }, + ); + slot + } + + fn iterate_path_candidates_dyn( + &self, + db: &dyn HirDatabase, + krate: Crate, + traits_in_scope: &FxHashSet, + name: Option<&Name>, + callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, + ) { let canonical = hir_ty::replace_errors_with_variables(&self.ty); let env = self.env.clone(); let krate = krate.id; - method_resolution::iterate_method_candidates( + method_resolution::iterate_method_candidates_dyn( &canonical, db, env, @@ -2598,8 +2659,8 @@ impl Type { None, name, method_resolution::LookupMode::Path, - |ty, it| callback(ty, it.into()), - ) + callback, + ); } pub fn as_adt(&self) -> Option { diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 3d233b1e20..0bd1d30bbf 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -410,7 +410,7 @@ pub enum LookupMode { // This would be nicer if it just returned an iterator, but that runs into // lifetime problems, because we need to borrow temp `CrateImplDefs`. // FIXME add a context type here? -pub fn iterate_method_candidates( +pub fn iterate_method_candidates( ty: &Canonical, db: &dyn HirDatabase, env: Arc, @@ -422,7 +422,7 @@ pub fn iterate_method_candidates( mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { let mut slot = None; - iterate_method_candidates_impl( + iterate_method_candidates_dyn( ty, db, env, @@ -440,7 +440,7 @@ pub fn iterate_method_candidates( slot } -fn iterate_method_candidates_impl( +pub fn iterate_method_candidates_dyn( ty: &Canonical, db: &dyn HirDatabase, env: Arc, From cfa3f679e9f9de0be803b5a86d27da8c9dbe364f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 29 Aug 2021 18:55:25 +0300 Subject: [PATCH 2/2] internal: don't expose impl details out of hir --- crates/hir/src/lib.rs | 8 ++++---- crates/hir_ty/src/method_resolution.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 6383a467eb..544312f6fc 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2564,7 +2564,7 @@ impl Type { krate: Crate, traits_in_scope: &FxHashSet, name: Option<&Name>, - mut callback: impl FnMut(&Ty, Function) -> Option, + mut callback: impl FnMut(Type, Function) -> Option, ) -> Option { let _p = profile::span("iterate_method_candidates"); let mut slot = None; @@ -2575,7 +2575,7 @@ impl Type { name, &mut |ty, assoc_item_id| match assoc_item_id { AssocItemId::FunctionId(it) => { - slot = callback(ty, it.into()); + slot = callback(self.derived(ty.clone()), it.into()); slot.is_some() } AssocItemId::ConstId(_) | AssocItemId::TypeAliasId(_) => false, @@ -2620,7 +2620,7 @@ impl Type { krate: Crate, traits_in_scope: &FxHashSet, name: Option<&Name>, - mut callback: impl FnMut(&Ty, AssocItem) -> Option, + mut callback: impl FnMut(Type, AssocItem) -> Option, ) -> Option { let _p = profile::span("iterate_path_candidates"); let mut slot = None; @@ -2630,7 +2630,7 @@ impl Type { traits_in_scope, name, &mut |ty, assoc_item_id| { - slot = callback(ty, assoc_item_id.into()); + slot = callback(self.derived(ty.clone()), assoc_item_id.into()); slot.is_some() }, ); diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 0bd1d30bbf..9b789b5fa2 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -410,7 +410,7 @@ pub enum LookupMode { // This would be nicer if it just returned an iterator, but that runs into // lifetime problems, because we need to borrow temp `CrateImplDefs`. // FIXME add a context type here? -pub fn iterate_method_candidates( +pub fn iterate_method_candidates( ty: &Canonical, db: &dyn HirDatabase, env: Arc,