Skip to content

Commit 63760ac

Browse files
committed
Auto merge of #33064 - jseyfried:improve_resolve_performance, r=eddyb
resolve: Improve performance This fixes #33061 by speeding up searchs through all traits in scope, a bottleneck in `resolve`. According to my measurements, this PR improves resolution performance by a factor of 3.4x on `librustc`, which almost completely reverses the 3.75x performance regression reported in #33061. r? @eddyb
2 parents ed7c567 + 6ae8027 commit 63760ac

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

src/librustc_resolve/lib.rs

+25-11
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,9 @@ pub struct ModuleS<'a> {
848848
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
849849
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
850850

851+
// Used to memoize the traits in this module for faster searches through all traits in scope.
852+
traits: RefCell<Option<Box<[&'a NameBinding<'a>]>>>,
853+
851854
// Whether this module is populated. If not populated, any attempt to
852855
// access the children must be preceded with a
853856
// `populate_module_if_necessary` call.
@@ -875,6 +878,7 @@ impl<'a> ModuleS<'a> {
875878
prelude: RefCell::new(None),
876879
glob_importers: RefCell::new(Vec::new()),
877880
globs: RefCell::new((Vec::new())),
881+
traits: RefCell::new(None),
878882
populated: Cell::new(!external),
879883
arenas: arenas
880884
}
@@ -3225,18 +3229,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
32253229
let mut search_module = self.current_module;
32263230
loop {
32273231
// Look for trait children.
3228-
let mut search_in_module = |module: Module<'a>| module.for_each_child(|_, ns, binding| {
3229-
if ns != TypeNS { return }
3230-
let trait_def_id = match binding.def() {
3231-
Some(Def::Trait(trait_def_id)) => trait_def_id,
3232-
Some(..) | None => return,
3233-
};
3234-
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3235-
add_trait_info(&mut found_traits, trait_def_id, name);
3236-
let trait_name = self.get_trait_name(trait_def_id);
3237-
self.record_use(trait_name, TypeNS, binding);
3232+
let mut search_in_module = |module: Module<'a>| {
3233+
let mut traits = module.traits.borrow_mut();
3234+
if traits.is_none() {
3235+
let mut collected_traits = Vec::new();
3236+
module.for_each_child(|_, ns, binding| {
3237+
if ns != TypeNS { return }
3238+
if let Some(Def::Trait(_)) = binding.def() {
3239+
collected_traits.push(binding);
3240+
}
3241+
});
3242+
*traits = Some(collected_traits.into_boxed_slice());
32383243
}
3239-
});
3244+
3245+
for binding in traits.as_ref().unwrap().iter() {
3246+
let trait_def_id = binding.def().unwrap().def_id();
3247+
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3248+
add_trait_info(&mut found_traits, trait_def_id, name);
3249+
let trait_name = self.get_trait_name(trait_def_id);
3250+
self.record_use(trait_name, TypeNS, binding);
3251+
}
3252+
}
3253+
};
32403254
search_in_module(search_module);
32413255

32423256
match search_module.parent_link {

0 commit comments

Comments
 (0)