mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 22:53:28 +00:00
Add TreeId
to identify ItemTree
s
With per-block `ItemTree`s, the file ID is not enough to identify an `ItemTree`.
This commit is contained in:
parent
64bf67c5aa
commit
66311e1262
@ -10,7 +10,7 @@ use crate::{
|
||||
body::Expander,
|
||||
db::DefDatabase,
|
||||
intern::Interned,
|
||||
item_tree::{AssocItem, FnFlags, ItemTreeId, ModItem, Param},
|
||||
item_tree::{self, AssocItem, FnFlags, ItemTreeId, ModItem, Param},
|
||||
type_ref::{TraitRef, TypeBound, TypeRef},
|
||||
visibility::RawVisibility,
|
||||
AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
|
||||
@ -171,7 +171,7 @@ impl TraitData {
|
||||
module_id,
|
||||
&mut expander,
|
||||
tr_def.items.iter().copied(),
|
||||
tr_loc.id.file_id(),
|
||||
tr_loc.id.tree_id(),
|
||||
container,
|
||||
100,
|
||||
);
|
||||
@ -228,7 +228,7 @@ impl ImplData {
|
||||
module_id,
|
||||
&mut expander,
|
||||
impl_def.items.iter().copied(),
|
||||
impl_loc.id.file_id(),
|
||||
impl_loc.id.tree_id(),
|
||||
container,
|
||||
100,
|
||||
);
|
||||
@ -290,7 +290,7 @@ fn collect_items(
|
||||
module: ModuleId,
|
||||
expander: &mut Expander,
|
||||
assoc_items: impl Iterator<Item = AssocItem>,
|
||||
file_id: crate::HirFileId,
|
||||
tree_id: item_tree::TreeId,
|
||||
container: AssocContainerId,
|
||||
limit: usize,
|
||||
) -> Vec<(Name, AssocItemId)> {
|
||||
@ -298,7 +298,7 @@ fn collect_items(
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let item_tree = db.file_item_tree(file_id);
|
||||
let item_tree = tree_id.item_tree(db);
|
||||
let crate_graph = db.crate_graph();
|
||||
let cfg_options = &crate_graph[module.krate].cfg_options;
|
||||
|
||||
@ -312,7 +312,7 @@ fn collect_items(
|
||||
match item {
|
||||
AssocItem::Function(id) => {
|
||||
let item = &item_tree[id];
|
||||
let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db);
|
||||
let def = FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(db);
|
||||
items.push((item.name.clone(), def.into()));
|
||||
}
|
||||
AssocItem::Const(id) => {
|
||||
@ -321,25 +321,26 @@ fn collect_items(
|
||||
Some(name) => name,
|
||||
None => continue,
|
||||
};
|
||||
let def = ConstLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db);
|
||||
let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(db);
|
||||
items.push((name, def.into()));
|
||||
}
|
||||
AssocItem::TypeAlias(id) => {
|
||||
let item = &item_tree[id];
|
||||
let def = TypeAliasLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db);
|
||||
let def = TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(db);
|
||||
items.push((item.name.clone(), def.into()));
|
||||
}
|
||||
AssocItem::MacroCall(call) => {
|
||||
let call = &item_tree[call];
|
||||
let ast_id_map = db.ast_id_map(file_id);
|
||||
let root = db.parse_or_expand(file_id).unwrap();
|
||||
let ast_id_map = db.ast_id_map(tree_id.file_id());
|
||||
let root = db.parse_or_expand(tree_id.file_id()).unwrap();
|
||||
let call = ast_id_map.get(call.ast_id).to_node(&root);
|
||||
let res = expander.enter_expand(db, call);
|
||||
|
||||
if let Ok(res) = res {
|
||||
if let Some((mark, mac)) = res.value {
|
||||
let src: InFile<ast::MacroItems> = expander.to_source(mac);
|
||||
let item_tree = db.file_item_tree(src.file_id);
|
||||
let tree_id = item_tree::TreeId::new(src.file_id, None);
|
||||
let item_tree = tree_id.item_tree(db);
|
||||
let iter =
|
||||
item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item);
|
||||
items.extend(collect_items(
|
||||
@ -347,7 +348,7 @@ fn collect_items(
|
||||
module,
|
||||
expander,
|
||||
iter,
|
||||
src.file_id,
|
||||
tree_id,
|
||||
container,
|
||||
limit - 1,
|
||||
));
|
||||
|
@ -67,6 +67,7 @@ use crate::{
|
||||
path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
|
||||
type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
|
||||
visibility::RawVisibility,
|
||||
BlockId,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
@ -374,23 +375,51 @@ impl<N: ItemTreeNode> fmt::Debug for FileItemTreeId<N> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifies a particular [`ItemTree`].
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
pub struct TreeId {
|
||||
file: HirFileId,
|
||||
block: Option<BlockId>,
|
||||
}
|
||||
|
||||
impl TreeId {
|
||||
pub(crate) fn new(file: HirFileId, block: Option<BlockId>) -> Self {
|
||||
Self { file, block }
|
||||
}
|
||||
|
||||
pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
|
||||
match self.block {
|
||||
Some(_) => unreachable!("per-block ItemTrees are not yet implemented"),
|
||||
None => db.file_item_tree(self.file),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn file_id(self) -> HirFileId {
|
||||
self.file
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ItemTreeId<N: ItemTreeNode> {
|
||||
file: HirFileId,
|
||||
tree: TreeId,
|
||||
pub value: FileItemTreeId<N>,
|
||||
}
|
||||
|
||||
impl<N: ItemTreeNode> ItemTreeId<N> {
|
||||
pub fn new(file: HirFileId, idx: FileItemTreeId<N>) -> Self {
|
||||
Self { file, value: idx }
|
||||
pub fn new(tree: TreeId, idx: FileItemTreeId<N>) -> Self {
|
||||
Self { tree, value: idx }
|
||||
}
|
||||
|
||||
pub fn file_id(self) -> HirFileId {
|
||||
self.file
|
||||
self.tree.file
|
||||
}
|
||||
|
||||
pub fn tree_id(self) -> TreeId {
|
||||
self.tree
|
||||
}
|
||||
|
||||
pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
|
||||
db.file_item_tree(self.file)
|
||||
self.tree.item_tree(db)
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,7 +432,7 @@ impl<N: ItemTreeNode> Clone for ItemTreeId<N> {
|
||||
|
||||
impl<N: ItemTreeNode> PartialEq for ItemTreeId<N> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.file == other.file && self.value == other.value
|
||||
self.tree == other.tree && self.value == other.value
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,7 +440,7 @@ impl<N: ItemTreeNode> Eq for ItemTreeId<N> {}
|
||||
|
||||
impl<N: ItemTreeNode> Hash for ItemTreeId<N> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.file.hash(state);
|
||||
self.tree.hash(state);
|
||||
self.value.hash(state);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use crate::{
|
||||
item_scope::{ImportType, PerNsGlobImports},
|
||||
item_tree::{
|
||||
self, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, MacroCall, MacroDef,
|
||||
MacroRules, Mod, ModItem, ModKind,
|
||||
MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||
},
|
||||
macro_call_as_call_id,
|
||||
nameres::{
|
||||
@ -311,7 +311,7 @@ impl DefCollector<'_> {
|
||||
def_collector: &mut *self,
|
||||
macro_depth: 0,
|
||||
module_id,
|
||||
file_id: file_id.into(),
|
||||
tree_id: TreeId::new(file_id.into(), None),
|
||||
item_tree: &item_tree,
|
||||
mod_dir: ModDir::root(),
|
||||
}
|
||||
@ -331,7 +331,8 @@ impl DefCollector<'_> {
|
||||
def_collector: &mut *self,
|
||||
macro_depth: 0,
|
||||
module_id,
|
||||
file_id: block.file_id,
|
||||
// FIXME: populate block once we have per-block ItemTrees
|
||||
tree_id: TreeId::new(block.file_id, None),
|
||||
item_tree: &item_tree,
|
||||
mod_dir: ModDir::root(),
|
||||
}
|
||||
@ -427,7 +428,7 @@ impl DefCollector<'_> {
|
||||
def_collector: &mut *self,
|
||||
macro_depth: directive.depth,
|
||||
module_id: directive.module_id,
|
||||
file_id,
|
||||
tree_id: TreeId::new(file_id, None),
|
||||
item_tree: &item_tree,
|
||||
mod_dir,
|
||||
}
|
||||
@ -1066,7 +1067,7 @@ impl DefCollector<'_> {
|
||||
def_collector: &mut *self,
|
||||
macro_depth: directive.depth,
|
||||
module_id: directive.module_id,
|
||||
file_id,
|
||||
tree_id: TreeId::new(file_id, None),
|
||||
item_tree: &item_tree,
|
||||
mod_dir,
|
||||
}
|
||||
@ -1113,7 +1114,7 @@ impl DefCollector<'_> {
|
||||
def_collector: &mut *self,
|
||||
macro_depth: directive.depth,
|
||||
module_id: directive.module_id,
|
||||
file_id,
|
||||
tree_id: TreeId::new(file_id, None),
|
||||
item_tree: &item_tree,
|
||||
mod_dir,
|
||||
}
|
||||
@ -1200,7 +1201,7 @@ impl DefCollector<'_> {
|
||||
ModCollector {
|
||||
def_collector: &mut *self,
|
||||
macro_depth: depth,
|
||||
file_id,
|
||||
tree_id: TreeId::new(file_id, None),
|
||||
module_id,
|
||||
item_tree: &item_tree,
|
||||
mod_dir,
|
||||
@ -1295,7 +1296,7 @@ struct ModCollector<'a, 'b> {
|
||||
def_collector: &'a mut DefCollector<'b>,
|
||||
macro_depth: usize,
|
||||
module_id: LocalModuleId,
|
||||
file_id: HirFileId,
|
||||
tree_id: TreeId,
|
||||
item_tree: &'a ItemTree,
|
||||
mod_dir: ModDir,
|
||||
}
|
||||
@ -1362,7 +1363,7 @@ impl ModCollector<'_, '_> {
|
||||
self.def_collector.db,
|
||||
krate,
|
||||
self.item_tree,
|
||||
ItemTreeId::new(self.file_id, import_id),
|
||||
ItemTreeId::new(self.tree_id, import_id),
|
||||
);
|
||||
self.def_collector.unresolved_imports.extend(imports.into_iter().map(
|
||||
|import| ImportDirective {
|
||||
@ -1379,7 +1380,7 @@ impl ModCollector<'_, '_> {
|
||||
self.def_collector.db,
|
||||
krate,
|
||||
self.item_tree,
|
||||
ItemTreeId::new(self.file_id, import_id),
|
||||
ItemTreeId::new(self.tree_id, import_id),
|
||||
),
|
||||
status: PartialResolvedImport::Unresolved,
|
||||
})
|
||||
@ -1391,20 +1392,20 @@ impl ModCollector<'_, '_> {
|
||||
ModItem::Impl(imp) => {
|
||||
let module = self.def_collector.def_map.module_id(self.module_id);
|
||||
let impl_id =
|
||||
ImplLoc { container: module, id: ItemTreeId::new(self.file_id, imp) }
|
||||
ImplLoc { container: module, id: ItemTreeId::new(self.tree_id, imp) }
|
||||
.intern(self.def_collector.db);
|
||||
self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
|
||||
}
|
||||
ModItem::Function(id) => {
|
||||
let func = &self.item_tree[id];
|
||||
|
||||
let ast_id = InFile::new(self.file_id, func.ast_id);
|
||||
let ast_id = InFile::new(self.file_id(), func.ast_id);
|
||||
self.collect_proc_macro_def(&func.name, ast_id, &attrs);
|
||||
|
||||
def = Some(DefData {
|
||||
id: FunctionLoc {
|
||||
container: module.into(),
|
||||
id: ItemTreeId::new(self.file_id, id),
|
||||
id: ItemTreeId::new(self.tree_id, id),
|
||||
}
|
||||
.intern(self.def_collector.db)
|
||||
.into(),
|
||||
@ -1417,7 +1418,7 @@ impl ModCollector<'_, '_> {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
def = Some(DefData {
|
||||
id: StructLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
|
||||
id: StructLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
.intern(self.def_collector.db)
|
||||
.into(),
|
||||
name: &it.name,
|
||||
@ -1429,7 +1430,7 @@ impl ModCollector<'_, '_> {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
def = Some(DefData {
|
||||
id: UnionLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
|
||||
id: UnionLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
.intern(self.def_collector.db)
|
||||
.into(),
|
||||
name: &it.name,
|
||||
@ -1441,7 +1442,7 @@ impl ModCollector<'_, '_> {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
def = Some(DefData {
|
||||
id: EnumLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
|
||||
id: EnumLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
.intern(self.def_collector.db)
|
||||
.into(),
|
||||
name: &it.name,
|
||||
@ -1453,7 +1454,7 @@ impl ModCollector<'_, '_> {
|
||||
let it = &self.item_tree[id];
|
||||
let const_id = ConstLoc {
|
||||
container: module.into(),
|
||||
id: ItemTreeId::new(self.file_id, id),
|
||||
id: ItemTreeId::new(self.tree_id, id),
|
||||
}
|
||||
.intern(self.def_collector.db);
|
||||
|
||||
@ -1478,7 +1479,7 @@ impl ModCollector<'_, '_> {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
def = Some(DefData {
|
||||
id: StaticLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
|
||||
id: StaticLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
.intern(self.def_collector.db)
|
||||
.into(),
|
||||
name: &it.name,
|
||||
@ -1490,7 +1491,7 @@ impl ModCollector<'_, '_> {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
def = Some(DefData {
|
||||
id: TraitLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
|
||||
id: TraitLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
.intern(self.def_collector.db)
|
||||
.into(),
|
||||
name: &it.name,
|
||||
@ -1504,7 +1505,7 @@ impl ModCollector<'_, '_> {
|
||||
def = Some(DefData {
|
||||
id: TypeAliasLoc {
|
||||
container: module.into(),
|
||||
id: ItemTreeId::new(self.file_id, id),
|
||||
id: ItemTreeId::new(self.tree_id, id),
|
||||
}
|
||||
.intern(self.def_collector.db)
|
||||
.into(),
|
||||
@ -1540,7 +1541,7 @@ impl ModCollector<'_, '_> {
|
||||
ModKind::Inline { items } => {
|
||||
let module_id = self.push_child_module(
|
||||
module.name.clone(),
|
||||
AstId::new(self.file_id, module.ast_id),
|
||||
AstId::new(self.file_id(), module.ast_id),
|
||||
None,
|
||||
&self.item_tree[module.visibility],
|
||||
);
|
||||
@ -1551,7 +1552,7 @@ impl ModCollector<'_, '_> {
|
||||
def_collector: &mut *self.def_collector,
|
||||
macro_depth: self.macro_depth,
|
||||
module_id,
|
||||
file_id: self.file_id,
|
||||
tree_id: self.tree_id,
|
||||
item_tree: self.item_tree,
|
||||
mod_dir,
|
||||
}
|
||||
@ -1563,9 +1564,10 @@ impl ModCollector<'_, '_> {
|
||||
}
|
||||
// out of line module, resolve, parse and recurse
|
||||
ModKind::Outline {} => {
|
||||
let ast_id = AstId::new(self.file_id, module.ast_id);
|
||||
let ast_id = AstId::new(self.tree_id.file_id(), module.ast_id);
|
||||
let db = self.def_collector.db;
|
||||
match self.mod_dir.resolve_declaration(db, self.file_id, &module.name, path_attr) {
|
||||
match self.mod_dir.resolve_declaration(db, self.file_id(), &module.name, path_attr)
|
||||
{
|
||||
Ok((file_id, is_mod_rs, mod_dir)) => {
|
||||
let item_tree = db.file_item_tree(file_id.into());
|
||||
if item_tree
|
||||
@ -1585,7 +1587,7 @@ impl ModCollector<'_, '_> {
|
||||
def_collector: &mut *self.def_collector,
|
||||
macro_depth: self.macro_depth,
|
||||
module_id,
|
||||
file_id: file_id.into(),
|
||||
tree_id: TreeId::new(file_id.into(), None),
|
||||
item_tree: &item_tree,
|
||||
mod_dir,
|
||||
}
|
||||
@ -1656,7 +1658,7 @@ impl ModCollector<'_, '_> {
|
||||
/// assumed to be resolved already.
|
||||
fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> {
|
||||
let mut ignore_up_to =
|
||||
self.def_collector.skip_attrs.get(&InFile::new(self.file_id, mod_item)).copied();
|
||||
self.def_collector.skip_attrs.get(&InFile::new(self.file_id(), mod_item)).copied();
|
||||
let iter = attrs
|
||||
.iter()
|
||||
.dedup_by(|a, b| {
|
||||
@ -1686,7 +1688,7 @@ impl ModCollector<'_, '_> {
|
||||
log::debug!("non-builtin attribute {}", attr.path);
|
||||
|
||||
let ast_id = AstIdWithPath::new(
|
||||
self.file_id,
|
||||
self.file_id(),
|
||||
mod_item.ast_id(self.item_tree),
|
||||
attr.path.as_ref().clone(),
|
||||
);
|
||||
@ -1749,7 +1751,7 @@ impl ModCollector<'_, '_> {
|
||||
match attr.parse_derive() {
|
||||
Some(derive_macros) => {
|
||||
for path in derive_macros {
|
||||
let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
|
||||
let ast_id = AstIdWithPath::new(self.file_id(), ast_id, path);
|
||||
self.def_collector.unresolved_macros.push(MacroDirective {
|
||||
module_id: self.module_id,
|
||||
depth: self.macro_depth + 1,
|
||||
@ -1776,7 +1778,7 @@ impl ModCollector<'_, '_> {
|
||||
let krate = self.def_collector.def_map.krate;
|
||||
let mac = &self.item_tree[id];
|
||||
let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
|
||||
let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
|
||||
let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
|
||||
|
||||
let export_attr = attrs.by_key("macro_export");
|
||||
|
||||
@ -1841,7 +1843,7 @@ impl ModCollector<'_, '_> {
|
||||
fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) {
|
||||
let krate = self.def_collector.def_map.krate;
|
||||
let mac = &self.item_tree[id];
|
||||
let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
|
||||
let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
|
||||
|
||||
// Case 1: bulitin macros
|
||||
let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
|
||||
@ -1885,7 +1887,7 @@ impl ModCollector<'_, '_> {
|
||||
}
|
||||
|
||||
fn collect_macro_call(&mut self, mac: &MacroCall) {
|
||||
let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, (*mac.path).clone());
|
||||
let mut ast_id = AstIdWithPath::new(self.file_id(), mac.ast_id, (*mac.path).clone());
|
||||
|
||||
// Case 1: try to resolve in legacy scope and expand macro_rules
|
||||
let mut error = None;
|
||||
@ -1962,7 +1964,7 @@ impl ModCollector<'_, '_> {
|
||||
fn emit_unconfigured_diagnostic(&mut self, item: ModItem, cfg: &CfgExpr) {
|
||||
let ast_id = item.ast_id(self.item_tree);
|
||||
|
||||
let ast_id = InFile::new(self.file_id, ast_id);
|
||||
let ast_id = InFile::new(self.file_id(), ast_id);
|
||||
self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
|
||||
self.module_id,
|
||||
ast_id,
|
||||
@ -1970,6 +1972,10 @@ impl ModCollector<'_, '_> {
|
||||
self.def_collector.cfg_options.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
fn file_id(&self) -> HirFileId {
|
||||
self.tree_id.file_id()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
Loading…
Reference in New Issue
Block a user