Skip to content

Commit 66311e1

Browse files
Add TreeId to identify ItemTrees
With per-block `ItemTree`s, the file ID is not enough to identify an `ItemTree`.
1 parent 64bf67c commit 66311e1

File tree

3 files changed

+87
-51
lines changed

3 files changed

+87
-51
lines changed

crates/hir_def/src/data.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
body::Expander,
1111
db::DefDatabase,
1212
intern::Interned,
13-
item_tree::{AssocItem, FnFlags, ItemTreeId, ModItem, Param},
13+
item_tree::{self, AssocItem, FnFlags, ItemTreeId, ModItem, Param},
1414
type_ref::{TraitRef, TypeBound, TypeRef},
1515
visibility::RawVisibility,
1616
AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
@@ -171,7 +171,7 @@ impl TraitData {
171171
module_id,
172172
&mut expander,
173173
tr_def.items.iter().copied(),
174-
tr_loc.id.file_id(),
174+
tr_loc.id.tree_id(),
175175
container,
176176
100,
177177
);
@@ -228,7 +228,7 @@ impl ImplData {
228228
module_id,
229229
&mut expander,
230230
impl_def.items.iter().copied(),
231-
impl_loc.id.file_id(),
231+
impl_loc.id.tree_id(),
232232
container,
233233
100,
234234
);
@@ -290,15 +290,15 @@ fn collect_items(
290290
module: ModuleId,
291291
expander: &mut Expander,
292292
assoc_items: impl Iterator<Item = AssocItem>,
293-
file_id: crate::HirFileId,
293+
tree_id: item_tree::TreeId,
294294
container: AssocContainerId,
295295
limit: usize,
296296
) -> Vec<(Name, AssocItemId)> {
297297
if limit == 0 {
298298
return Vec::new();
299299
}
300300

301-
let item_tree = db.file_item_tree(file_id);
301+
let item_tree = tree_id.item_tree(db);
302302
let crate_graph = db.crate_graph();
303303
let cfg_options = &crate_graph[module.krate].cfg_options;
304304

@@ -312,7 +312,7 @@ fn collect_items(
312312
match item {
313313
AssocItem::Function(id) => {
314314
let item = &item_tree[id];
315-
let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db);
315+
let def = FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(db);
316316
items.push((item.name.clone(), def.into()));
317317
}
318318
AssocItem::Const(id) => {
@@ -321,33 +321,34 @@ fn collect_items(
321321
Some(name) => name,
322322
None => continue,
323323
};
324-
let def = ConstLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db);
324+
let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(db);
325325
items.push((name, def.into()));
326326
}
327327
AssocItem::TypeAlias(id) => {
328328
let item = &item_tree[id];
329-
let def = TypeAliasLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db);
329+
let def = TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(db);
330330
items.push((item.name.clone(), def.into()));
331331
}
332332
AssocItem::MacroCall(call) => {
333333
let call = &item_tree[call];
334-
let ast_id_map = db.ast_id_map(file_id);
335-
let root = db.parse_or_expand(file_id).unwrap();
334+
let ast_id_map = db.ast_id_map(tree_id.file_id());
335+
let root = db.parse_or_expand(tree_id.file_id()).unwrap();
336336
let call = ast_id_map.get(call.ast_id).to_node(&root);
337337
let res = expander.enter_expand(db, call);
338338

339339
if let Ok(res) = res {
340340
if let Some((mark, mac)) = res.value {
341341
let src: InFile<ast::MacroItems> = expander.to_source(mac);
342-
let item_tree = db.file_item_tree(src.file_id);
342+
let tree_id = item_tree::TreeId::new(src.file_id, None);
343+
let item_tree = tree_id.item_tree(db);
343344
let iter =
344345
item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item);
345346
items.extend(collect_items(
346347
db,
347348
module,
348349
expander,
349350
iter,
350-
src.file_id,
351+
tree_id,
351352
container,
352353
limit - 1,
353354
));

crates/hir_def/src/item_tree.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ use crate::{
6767
path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
6868
type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
6969
visibility::RawVisibility,
70+
BlockId,
7071
};
7172

7273
#[derive(Copy, Clone, Eq, PartialEq)]
@@ -374,23 +375,51 @@ impl<N: ItemTreeNode> fmt::Debug for FileItemTreeId<N> {
374375
}
375376
}
376377

378+
/// Identifies a particular [`ItemTree`].
379+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
380+
pub struct TreeId {
381+
file: HirFileId,
382+
block: Option<BlockId>,
383+
}
384+
385+
impl TreeId {
386+
pub(crate) fn new(file: HirFileId, block: Option<BlockId>) -> Self {
387+
Self { file, block }
388+
}
389+
390+
pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
391+
match self.block {
392+
Some(_) => unreachable!("per-block ItemTrees are not yet implemented"),
393+
None => db.file_item_tree(self.file),
394+
}
395+
}
396+
397+
pub(crate) fn file_id(self) -> HirFileId {
398+
self.file
399+
}
400+
}
401+
377402
#[derive(Debug)]
378403
pub struct ItemTreeId<N: ItemTreeNode> {
379-
file: HirFileId,
404+
tree: TreeId,
380405
pub value: FileItemTreeId<N>,
381406
}
382407

383408
impl<N: ItemTreeNode> ItemTreeId<N> {
384-
pub fn new(file: HirFileId, idx: FileItemTreeId<N>) -> Self {
385-
Self { file, value: idx }
409+
pub fn new(tree: TreeId, idx: FileItemTreeId<N>) -> Self {
410+
Self { tree, value: idx }
386411
}
387412

388413
pub fn file_id(self) -> HirFileId {
389-
self.file
414+
self.tree.file
415+
}
416+
417+
pub fn tree_id(self) -> TreeId {
418+
self.tree
390419
}
391420

392421
pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
393-
db.file_item_tree(self.file)
422+
self.tree.item_tree(db)
394423
}
395424
}
396425

@@ -403,15 +432,15 @@ impl<N: ItemTreeNode> Clone for ItemTreeId<N> {
403432

404433
impl<N: ItemTreeNode> PartialEq for ItemTreeId<N> {
405434
fn eq(&self, other: &Self) -> bool {
406-
self.file == other.file && self.value == other.value
435+
self.tree == other.tree && self.value == other.value
407436
}
408437
}
409438

410439
impl<N: ItemTreeNode> Eq for ItemTreeId<N> {}
411440

412441
impl<N: ItemTreeNode> Hash for ItemTreeId<N> {
413442
fn hash<H: Hasher>(&self, state: &mut H) {
414-
self.file.hash(state);
443+
self.tree.hash(state);
415444
self.value.hash(state);
416445
}
417446
}

0 commit comments

Comments
 (0)