Skip to content

Commit e4f4cd7

Browse files
Do not collect all traits
1 parent e008b08 commit e4f4cd7

File tree

1 file changed

+53
-102
lines changed

1 file changed

+53
-102
lines changed

crates/ra_assists/src/handlers/auto_import.rs

Lines changed: 53 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use crate::{
33
insert_use_statement, AssistId,
44
};
55
use hir::{
6-
db::{DefDatabase, HirDatabase},
7-
AsAssocItem, AssocItem, AssocItemContainer, Crate, ModPath, Module, ModuleDef, PathResolution,
6+
db::HirDatabase, AsAssocItem, AssocItemContainer, ModPath, Module, ModuleDef, PathResolution,
87
SourceAnalyzer, Trait, Type,
98
};
109
use ra_ide_db::{imports_locator::ImportsLocator, RootDatabase};
@@ -141,121 +140,73 @@ impl AutoImportAssets {
141140
ImportsLocator::new(db)
142141
.find_imports(&self.get_search_query())
143142
.into_iter()
144-
.map(|module_def| match &self.import_candidate {
143+
.filter_map(|module_def| match &self.import_candidate {
145144
ImportCandidate::TraitAssocItem(assoc_item_type, _) => {
146145
let located_assoc_item = match module_def {
147-
ModuleDef::Function(located_function) => {
148-
Some(AssocItem::Function(located_function))
149-
}
150-
ModuleDef::Const(located_const) => Some(AssocItem::Const(located_const)),
146+
ModuleDef::Function(located_function) => located_function
147+
.as_assoc_item(db)
148+
.map(|assoc| assoc.container(db))
149+
.and_then(Self::assoc_to_trait),
150+
ModuleDef::Const(located_const) => located_const
151+
.as_assoc_item(db)
152+
.map(|assoc| assoc.container(db))
153+
.and_then(Self::assoc_to_trait),
151154
_ => None,
152-
};
153-
154-
let mut applicable_traits = Vec::new();
155-
if let Some(located_assoc_item) = located_assoc_item {
156-
let trait_candidates: FxHashSet<_> =
157-
Self::get_trait_candidates(db, located_assoc_item, current_crate)
158-
.into_iter()
159-
.map(|trait_candidate| trait_candidate.into())
160-
.collect();
161-
if !trait_candidates.is_empty() {
162-
assoc_item_type.iterate_path_candidates(
163-
db,
164-
current_crate,
165-
&trait_candidates,
166-
None,
167-
|_, assoc| {
168-
if let AssocItemContainer::Trait(appropriate_trait) =
169-
assoc.container(db)
170-
{
171-
applicable_traits.push(
172-
self.module_with_name_to_import
173-
.find_use_path(db, appropriate_trait.into()),
174-
);
175-
};
176-
None::<()>
177-
},
178-
);
179-
};
180-
}
181-
applicable_traits
155+
}?;
156+
157+
let mut trait_candidates = FxHashSet::default();
158+
trait_candidates.insert(located_assoc_item.into());
159+
160+
assoc_item_type
161+
.iterate_path_candidates(
162+
db,
163+
current_crate,
164+
&trait_candidates,
165+
None,
166+
|_, assoc| Self::assoc_to_trait(assoc.container(db)),
167+
)
168+
.map(ModuleDef::from)
182169
}
183170
ImportCandidate::TraitMethod(function_callee, _) => {
184-
let mut applicable_traits = Vec::new();
185-
if let ModuleDef::Function(located_function) = module_def {
186-
let trait_candidates: FxHashSet<_> = Self::get_trait_candidates(
171+
let located_assoc_item =
172+
if let ModuleDef::Function(located_function) = module_def {
173+
located_function
174+
.as_assoc_item(db)
175+
.map(|assoc| assoc.container(db))
176+
.and_then(Self::assoc_to_trait)
177+
} else {
178+
None
179+
}?;
180+
181+
let mut trait_candidates = FxHashSet::default();
182+
trait_candidates.insert(located_assoc_item.into());
183+
184+
function_callee
185+
.iterate_method_candidates(
187186
db,
188-
AssocItem::Function(located_function),
189187
current_crate,
188+
&trait_candidates,
189+
None,
190+
|_, function| {
191+
Self::assoc_to_trait(function.as_assoc_item(db)?.container(db))
192+
},
190193
)
191-
.into_iter()
192-
.map(|trait_candidate| trait_candidate.into())
193-
.collect();
194-
if !trait_candidates.is_empty() {
195-
function_callee.iterate_method_candidates(
196-
db,
197-
current_crate,
198-
&trait_candidates,
199-
None,
200-
|_, function| {
201-
if let AssocItemContainer::Trait(appropriate_trait) = function
202-
.as_assoc_item(db)
203-
.expect("Function is an assoc item")
204-
.container(db)
205-
{
206-
applicable_traits.push(
207-
self.module_with_name_to_import
208-
.find_use_path(db, appropriate_trait.into()),
209-
);
210-
};
211-
None::<()>
212-
},
213-
);
214-
}
215-
}
216-
applicable_traits
194+
.map(ModuleDef::from)
217195
}
218-
_ => vec![self.module_with_name_to_import.find_use_path(db, module_def)],
196+
_ => Some(module_def),
219197
})
220-
.flatten()
221-
.filter_map(std::convert::identity)
198+
.filter_map(|module_def| self.module_with_name_to_import.find_use_path(db, module_def))
222199
.filter(|use_path| !use_path.segments.is_empty())
223200
.take(20)
224201
.collect::<BTreeSet<_>>()
225202
}
226203

227-
fn get_trait_candidates(
228-
db: &RootDatabase,
229-
called_assoc_item: AssocItem,
230-
root_crate: Crate,
231-
) -> FxHashSet<Trait> {
232-
let _p = profile("auto_import::get_trait_candidates");
233-
root_crate
234-
.dependencies(db)
235-
.into_iter()
236-
.map(|dependency| db.crate_def_map(dependency.krate.into()))
237-
.chain(std::iter::once(db.crate_def_map(root_crate.into())))
238-
.map(|crate_def_map| {
239-
crate_def_map
240-
.modules
241-
.iter()
242-
.map(|(_, module_data)| module_data.scope.declarations())
243-
.flatten()
244-
.filter_map(|module_def_id| match module_def_id.into() {
245-
ModuleDef::Trait(trait_candidate)
246-
if trait_candidate
247-
.items(db)
248-
.into_iter()
249-
.any(|item| item == called_assoc_item) =>
250-
{
251-
Some(trait_candidate)
252-
}
253-
_ => None,
254-
})
255-
.collect::<FxHashSet<_>>()
256-
})
257-
.flatten()
258-
.collect()
204+
fn assoc_to_trait(assoc: AssocItemContainer) -> Option<Trait> {
205+
if let AssocItemContainer::Trait(extracted_trait) = assoc {
206+
Some(extracted_trait)
207+
} else {
208+
None
209+
}
259210
}
260211
}
261212

0 commit comments

Comments
 (0)