10074: internal: improve compile times a bit r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2021-08-29 15:56:06 +00:00 committed by GitHub
commit d15f646ff1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 17 deletions

View file

@ -2517,18 +2517,35 @@ impl Type {
krate: Crate, krate: Crate,
mut callback: impl FnMut(AssocItem) -> Option<T>, mut callback: impl FnMut(AssocItem) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
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); let impls = db.inherent_impls_in_crate(krate);
for impl_def in impls.for_self_ty(&self.ty) { for impl_def in impls.for_self_ty(&self.ty) {
for &item in db.impl_data(*impl_def).items.iter() { for &item in db.impl_data(*impl_def).items.iter() {
if let Some(result) = callback(item.into()) { if callback(item) {
return Some(result); return;
} }
} }
} }
} }
None
} }
pub fn type_arguments(&self) -> impl Iterator<Item = Type> + '_ { pub fn type_arguments(&self) -> impl Iterator<Item = Type> + '_ {
@ -2547,9 +2564,34 @@ impl Type {
krate: Crate, krate: Crate,
traits_in_scope: &FxHashSet<TraitId>, traits_in_scope: &FxHashSet<TraitId>,
name: Option<&Name>, name: Option<&Name>,
mut callback: impl FnMut(&Ty, Function) -> Option<T>, mut callback: impl FnMut(Type, Function) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
let _p = profile::span("iterate_method_candidates"); 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(self.derived(ty.clone()), 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<TraitId>,
name: Option<&Name>,
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
) {
// There should be no inference vars in types passed here // There should be no inference vars in types passed here
// FIXME check that? // FIXME check that?
// FIXME replace Unknown by bound vars here // FIXME replace Unknown by bound vars here
@ -2559,7 +2601,7 @@ impl Type {
let env = self.env.clone(); let env = self.env.clone();
let krate = krate.id; let krate = krate.id;
method_resolution::iterate_method_candidates( method_resolution::iterate_method_candidates_dyn(
&canonical, &canonical,
db, db,
env, env,
@ -2568,11 +2610,8 @@ impl Type {
None, None,
name, name,
method_resolution::LookupMode::MethodCall, method_resolution::LookupMode::MethodCall,
|ty, it| match it { callback,
AssocItemId::FunctionId(f) => callback(ty, f.into()), );
_ => None,
},
)
} }
pub fn iterate_path_candidates<T>( pub fn iterate_path_candidates<T>(
@ -2581,15 +2620,37 @@ impl Type {
krate: Crate, krate: Crate,
traits_in_scope: &FxHashSet<TraitId>, traits_in_scope: &FxHashSet<TraitId>,
name: Option<&Name>, name: Option<&Name>,
mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, mut callback: impl FnMut(Type, AssocItem) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
let _p = profile::span("iterate_path_candidates"); 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(self.derived(ty.clone()), assoc_item_id.into());
slot.is_some()
},
);
slot
}
fn iterate_path_candidates_dyn(
&self,
db: &dyn HirDatabase,
krate: Crate,
traits_in_scope: &FxHashSet<TraitId>,
name: Option<&Name>,
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
) {
let canonical = hir_ty::replace_errors_with_variables(&self.ty); let canonical = hir_ty::replace_errors_with_variables(&self.ty);
let env = self.env.clone(); let env = self.env.clone();
let krate = krate.id; let krate = krate.id;
method_resolution::iterate_method_candidates( method_resolution::iterate_method_candidates_dyn(
&canonical, &canonical,
db, db,
env, env,
@ -2598,8 +2659,8 @@ impl Type {
None, None,
name, name,
method_resolution::LookupMode::Path, method_resolution::LookupMode::Path,
|ty, it| callback(ty, it.into()), callback,
) );
} }
pub fn as_adt(&self) -> Option<Adt> { pub fn as_adt(&self) -> Option<Adt> {

View file

@ -422,7 +422,7 @@ pub fn iterate_method_candidates<T>(
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>, mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
let mut slot = None; let mut slot = None;
iterate_method_candidates_impl( iterate_method_candidates_dyn(
ty, ty,
db, db,
env, env,
@ -440,7 +440,7 @@ pub fn iterate_method_candidates<T>(
slot slot
} }
fn iterate_method_candidates_impl( pub fn iterate_method_candidates_dyn(
ty: &Canonical<Ty>, ty: &Canonical<Ty>,
db: &dyn HirDatabase, db: &dyn HirDatabase,
env: Arc<TraitEnvironment>, env: Arc<TraitEnvironment>,