Auto merge of #14715 - Veykril:symbol-index, r=Veykril

Refactor symbol index

Closes https://github.com/rust-lang/rust-analyzer/issues/14677

instead of eagerly fetching the source data in symbol index we do it lazily now, this shouldn't make it much more expensive as we had to parse the source most of the time anyways even after fetching.
This commit is contained in:
bors 2023-05-02 10:34:53 +00:00
commit 94ac1cdbf5
13 changed files with 422 additions and 684 deletions

View File

@ -51,7 +51,7 @@ use hir_def::{
per_ns::PerNs, per_ns::PerNs,
resolver::{HasResolver, Resolver}, resolver::{HasResolver, Resolver},
src::HasSource as _, src::HasSource as _,
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
@ -119,11 +119,9 @@ pub use {
path::{ModPath, PathKind}, path::{ModPath, PathKind},
type_ref::{Mutability, TypeRef}, type_ref::{Mutability, TypeRef},
visibility::Visibility, visibility::Visibility,
// FIXME: This is here since it is input of a method in `HirWrite` // FIXME: This is here since some queries take it as input that are used
// and things outside of hir need to implement that trait. We probably // outside of hir.
// should move whole `hir_ty::display` to this crate so we will become {AdtId, ModuleDefId},
// able to use `ModuleDef` or `Definition` instead of `ModuleDefId`.
ModuleDefId,
}, },
hir_expand::{ hir_expand::{
attrs::Attr, attrs::Attr,
@ -4429,3 +4427,90 @@ impl HasCrate for Module {
Module::krate(*self) Module::krate(*self)
} }
} }
pub trait HasContainer {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer;
}
impl HasContainer for Module {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
// FIXME: handle block expressions as modules (their parent is in a different DefMap)
let def_map = self.id.def_map(db.upcast());
match def_map[self.id.local_id].parent {
Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }),
None => ItemContainer::Crate(def_map.krate()),
}
}
}
impl HasContainer for Function {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
container_id_to_hir(self.id.lookup(db.upcast()).container)
}
}
impl HasContainer for Struct {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
}
}
impl HasContainer for Union {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
}
}
impl HasContainer for Enum {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
}
}
impl HasContainer for TypeAlias {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
container_id_to_hir(self.id.lookup(db.upcast()).container)
}
}
impl HasContainer for Const {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
container_id_to_hir(self.id.lookup(db.upcast()).container)
}
}
impl HasContainer for Static {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
container_id_to_hir(self.id.lookup(db.upcast()).container)
}
}
impl HasContainer for Trait {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
}
}
impl HasContainer for TraitAlias {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
}
}
fn container_id_to_hir(c: ItemContainerId) -> ItemContainer {
match c {
ItemContainerId::ExternBlockId(_id) => ItemContainer::ExternBlock(),
ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }),
ItemContainerId::ImplId(id) => ItemContainer::Impl(Impl { id }),
ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }),
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ItemContainer {
Trait(Trait),
Impl(Impl),
Module(Module),
ExternBlock(),
Crate(CrateId),
}

View File

@ -1,89 +1,20 @@
//! File symbol extraction. //! File symbol extraction.
use base_db::FileRange;
use hir_def::{ use hir_def::{
item_tree::ItemTreeNode, src::HasSource, AdtId, AssocItemId, AssocItemLoc, DefWithBodyId, AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, MacroId, ModuleDefId, ModuleId, TraitId,
HasModule, ImplId, ItemContainerId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId,
}; };
use hir_expand::{HirFileId, InFile};
use hir_ty::db::HirDatabase; use hir_ty::db::HirDatabase;
use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr}; use syntax::SmolStr;
use crate::{Module, Semantics}; use crate::{Module, ModuleDef};
/// The actual data that is stored in the index. It should be as compact as /// The actual data that is stored in the index. It should be as compact as
/// possible. /// possible.
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FileSymbol { pub struct FileSymbol {
// even though name can be derived from the def, we store it for efficiency
pub name: SmolStr, pub name: SmolStr,
pub loc: DeclarationLocation, pub def: ModuleDef,
pub kind: FileSymbolKind,
pub container_name: Option<SmolStr>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DeclarationLocation {
/// The file id for both the `ptr` and `name_ptr`.
pub hir_file_id: HirFileId,
/// This points to the whole syntax node of the declaration.
pub ptr: SyntaxNodePtr,
/// This points to the [`syntax::ast::Name`] identifier of the declaration.
pub name_ptr: SyntaxNodePtr,
}
impl DeclarationLocation {
pub fn syntax<DB: HirDatabase>(&self, sema: &Semantics<'_, DB>) -> SyntaxNode {
let root = sema.parse_or_expand(self.hir_file_id);
self.ptr.to_node(&root)
}
pub fn original_range(&self, db: &dyn HirDatabase) -> FileRange {
let node = resolve_node(db, self.hir_file_id, &self.ptr);
node.as_ref().original_file_range(db.upcast())
}
pub fn original_name_range(&self, db: &dyn HirDatabase) -> Option<FileRange> {
let node = resolve_node(db, self.hir_file_id, &self.name_ptr);
node.as_ref().original_file_range_opt(db.upcast())
}
}
fn resolve_node(
db: &dyn HirDatabase,
file_id: HirFileId,
ptr: &SyntaxNodePtr,
) -> InFile<SyntaxNode> {
let root = db.parse_or_expand(file_id);
let node = ptr.to_node(&root);
InFile::new(file_id, node)
}
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub enum FileSymbolKind {
Const,
Enum,
Function,
Macro,
Module,
Static,
Struct,
Trait,
TraitAlias,
TypeAlias,
Union,
}
impl FileSymbolKind {
pub fn is_type(self: FileSymbolKind) -> bool {
matches!(
self,
FileSymbolKind::Struct
| FileSymbolKind::Enum
| FileSymbolKind::Trait
| FileSymbolKind::TypeAlias
| FileSymbolKind::Union
)
}
} }
/// Represents an outstanding module that the symbol collector must collect symbols from. /// Represents an outstanding module that the symbol collector must collect symbols from.
@ -146,36 +77,34 @@ impl<'a> SymbolCollector<'a> {
match module_def_id { match module_def_id {
ModuleDefId::ModuleId(id) => self.push_module(id), ModuleDefId::ModuleId(id) => self.push_module(id),
ModuleDefId::FunctionId(id) => { ModuleDefId::FunctionId(id) => {
self.push_decl_assoc(id, FileSymbolKind::Function); self.push_decl(id);
self.collect_from_body(id); self.collect_from_body(id);
} }
ModuleDefId::AdtId(AdtId::StructId(id)) => { ModuleDefId::AdtId(AdtId::StructId(id)) => self.push_decl(id),
self.push_decl(id, FileSymbolKind::Struct) ModuleDefId::AdtId(AdtId::EnumId(id)) => self.push_decl(id),
} ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id),
ModuleDefId::AdtId(AdtId::EnumId(id)) => self.push_decl(id, FileSymbolKind::Enum),
ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id, FileSymbolKind::Union),
ModuleDefId::ConstId(id) => { ModuleDefId::ConstId(id) => {
self.push_decl_assoc(id, FileSymbolKind::Const); self.push_decl(id);
self.collect_from_body(id); self.collect_from_body(id);
} }
ModuleDefId::StaticId(id) => { ModuleDefId::StaticId(id) => {
self.push_decl_assoc(id, FileSymbolKind::Static); self.push_decl(id);
self.collect_from_body(id); self.collect_from_body(id);
} }
ModuleDefId::TraitId(id) => { ModuleDefId::TraitId(id) => {
self.push_decl(id, FileSymbolKind::Trait); self.push_decl(id);
self.collect_from_trait(id); self.collect_from_trait(id);
} }
ModuleDefId::TraitAliasId(id) => { ModuleDefId::TraitAliasId(id) => {
self.push_decl(id, FileSymbolKind::TraitAlias); self.push_decl(id);
} }
ModuleDefId::TypeAliasId(id) => { ModuleDefId::TypeAliasId(id) => {
self.push_decl_assoc(id, FileSymbolKind::TypeAlias); self.push_decl(id);
} }
ModuleDefId::MacroId(id) => match id { ModuleDefId::MacroId(id) => match id {
MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro), MacroId::Macro2Id(id) => self.push_decl(id),
MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro), MacroId::MacroRulesId(id) => self.push_decl(id),
MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro), MacroId::ProcMacroId(id) => self.push_decl(id),
}, },
// Don't index these. // Don't index these.
ModuleDefId::BuiltinType(_) => {} ModuleDefId::BuiltinType(_) => {}
@ -195,9 +124,9 @@ impl<'a> SymbolCollector<'a> {
for &id in id { for &id in id {
if id.module(self.db.upcast()) == module_id { if id.module(self.db.upcast()) == module_id {
match id { match id {
MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro), MacroId::Macro2Id(id) => self.push_decl(id),
MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro), MacroId::MacroRulesId(id) => self.push_decl(id),
MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro), MacroId::ProcMacroId(id) => self.push_decl(id),
} }
} }
} }
@ -245,124 +174,36 @@ impl<'a> SymbolCollector<'a> {
} }
} }
fn current_container_name(&self) -> Option<SmolStr> {
self.current_container_name.clone()
}
fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option<SmolStr> { fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option<SmolStr> {
match body_id { match body_id {
DefWithBodyId::FunctionId(id) => Some( DefWithBodyId::FunctionId(id) => Some(self.db.function_data(id).name.to_smol_str()),
id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), DefWithBodyId::StaticId(id) => Some(self.db.static_data(id).name.to_smol_str()),
), DefWithBodyId::ConstId(id) => Some(self.db.const_data(id).name.as_ref()?.to_smol_str()),
DefWithBodyId::StaticId(id) => Some( DefWithBodyId::VariantId(id) => {
id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), Some(self.db.enum_data(id.parent).variants[id.local_id].name.to_smol_str())
), }
DefWithBodyId::ConstId(id) => Some(
id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(),
),
DefWithBodyId::VariantId(id) => Some({
let db = self.db.upcast();
id.parent.lookup(db).source(db).value.name()?.text().into()
}),
} }
} }
fn push_assoc_item(&mut self, assoc_item_id: AssocItemId) { fn push_assoc_item(&mut self, assoc_item_id: AssocItemId) {
match assoc_item_id { match assoc_item_id {
AssocItemId::FunctionId(id) => self.push_decl_assoc(id, FileSymbolKind::Function), AssocItemId::FunctionId(id) => self.push_decl(id),
AssocItemId::ConstId(id) => self.push_decl_assoc(id, FileSymbolKind::Const), AssocItemId::ConstId(id) => self.push_decl(id),
AssocItemId::TypeAliasId(id) => self.push_decl_assoc(id, FileSymbolKind::TypeAlias), AssocItemId::TypeAliasId(id) => self.push_decl(id),
} }
} }
fn push_decl_assoc<L, T>(&mut self, id: L, kind: FileSymbolKind) fn push_decl(&mut self, id: impl Into<ModuleDefId>) {
where let def = ModuleDef::from(id.into());
L: Lookup<Data = AssocItemLoc<T>>, if let Some(name) = def.name(self.db) {
T: ItemTreeNode, self.symbols.push(FileSymbol { name: name.to_smol_str(), def });
<T as ItemTreeNode>::Source: HasName,
{
fn container_name(db: &dyn HirDatabase, container: ItemContainerId) -> Option<SmolStr> {
match container {
ItemContainerId::ModuleId(module_id) => {
let module = Module::from(module_id);
module.name(db).and_then(|name| name.as_text())
} }
ItemContainerId::TraitId(trait_id) => {
let trait_data = db.trait_data(trait_id);
trait_data.name.as_text()
}
ItemContainerId::ImplId(_) | ItemContainerId::ExternBlockId(_) => None,
}
}
self.push_file_symbol(|s| {
let loc = id.lookup(s.db.upcast());
let source = loc.source(s.db.upcast());
let name_node = source.value.name()?;
let container_name =
container_name(s.db, loc.container).or_else(|| s.current_container_name());
Some(FileSymbol {
name: name_node.text().into(),
kind,
container_name,
loc: DeclarationLocation {
hir_file_id: source.file_id,
ptr: SyntaxNodePtr::new(source.value.syntax()),
name_ptr: SyntaxNodePtr::new(name_node.syntax()),
},
})
})
}
fn push_decl<L>(&mut self, id: L, kind: FileSymbolKind)
where
L: Lookup,
<L as Lookup>::Data: HasSource,
<<L as Lookup>::Data as HasSource>::Value: HasName,
{
self.push_file_symbol(|s| {
let loc = id.lookup(s.db.upcast());
let source = loc.source(s.db.upcast());
let name_node = source.value.name()?;
Some(FileSymbol {
name: name_node.text().into(),
kind,
container_name: s.current_container_name(),
loc: DeclarationLocation {
hir_file_id: source.file_id,
ptr: SyntaxNodePtr::new(source.value.syntax()),
name_ptr: SyntaxNodePtr::new(name_node.syntax()),
},
})
})
} }
fn push_module(&mut self, module_id: ModuleId) { fn push_module(&mut self, module_id: ModuleId) {
self.push_file_symbol(|s| { let def = Module::from(module_id);
let def_map = module_id.def_map(s.db.upcast()); if let Some(name) = def.name(self.db) {
let module_data = &def_map[module_id.local_id]; self.symbols.push(FileSymbol { name: name.to_smol_str(), def: ModuleDef::Module(def) });
let declaration = module_data.origin.declaration()?;
let module = declaration.to_node(s.db.upcast());
let name_node = module.name()?;
Some(FileSymbol {
name: name_node.text().into(),
kind: FileSymbolKind::Module,
container_name: s.current_container_name(),
loc: DeclarationLocation {
hir_file_id: declaration.file_id,
ptr: SyntaxNodePtr::new(module.syntax()),
name_ptr: SyntaxNodePtr::new(name_node.syntax()),
},
})
})
}
fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option<FileSymbol>) {
if let Some(file_symbol) = f(self) {
self.symbols.push(file_symbol);
} }
} }
} }

View File

@ -8,8 +8,8 @@
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use hir::{ use hir::{
Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, Field, Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, Field,
Function, GenericParam, HasVisibility, Impl, ItemInNs, Label, Local, Macro, Module, ModuleDef, Function, GenericParam, HasVisibility, Impl, Label, Local, Macro, Module, ModuleDef, Name,
Name, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias, TypeAlias, Variant, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias, TypeAlias, Variant,
Visibility, Visibility,
}; };
use stdx::impl_from; use stdx::impl_from;
@ -622,22 +622,3 @@ impl From<ModuleDef> for Definition {
} }
} }
} }
impl From<Definition> for Option<ItemInNs> {
fn from(def: Definition) -> Self {
let item = match def {
Definition::Module(it) => ModuleDef::Module(it),
Definition::Function(it) => ModuleDef::Function(it),
Definition::Adt(it) => ModuleDef::Adt(it),
Definition::Variant(it) => ModuleDef::Variant(it),
Definition::Const(it) => ModuleDef::Const(it),
Definition::Static(it) => ModuleDef::Static(it),
Definition::Trait(it) => ModuleDef::Trait(it),
Definition::TraitAlias(it) => ModuleDef::TraitAlias(it),
Definition::TypeAlias(it) => ModuleDef::TypeAlias(it),
Definition::BuiltinType(it) => ModuleDef::BuiltinType(it),
_ => return None,
};
Some(ItemInNs::from(item))
}
}

View File

@ -5,17 +5,11 @@
use either::Either; use either::Either;
use hir::{ use hir::{
import_map::{self, ImportKind}, import_map::{self, ImportKind},
symbols::FileSymbol,
AsAssocItem, Crate, ItemInNs, Semantics, AsAssocItem, Crate, ItemInNs, Semantics,
}; };
use limit::Limit; use limit::Limit;
use syntax::{ast, AstNode, SyntaxKind::NAME};
use crate::{ use crate::{imports::import_assets::NameToImport, symbol_index, RootDatabase};
defs::{Definition, NameClass},
imports::import_assets::NameToImport,
symbol_index, RootDatabase,
};
/// A value to use, when uncertain which limit to pick. /// A value to use, when uncertain which limit to pick.
pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(40); pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(40);
@ -118,10 +112,9 @@ fn find_items<'a>(
let local_results = local_query let local_results = local_query
.search(&symbol_index::crate_symbols(db, krate)) .search(&symbol_index::crate_symbols(db, krate))
.into_iter() .into_iter()
.filter_map(move |local_candidate| get_name_definition(sema, &local_candidate)) .filter_map(|local_candidate| match local_candidate.def {
.filter_map(|name_definition_to_import| match name_definition_to_import { hir::ModuleDef::Macro(macro_def) => Some(ItemInNs::Macros(macro_def)),
Definition::Macro(macro_def) => Some(ItemInNs::from(macro_def)), def => Some(ItemInNs::from(def)),
def => <Option<_>>::from(def),
}); });
external_importables.chain(local_results).filter(move |&item| match assoc_item_search { external_importables.chain(local_results).filter(move |&item| match assoc_item_search {
@ -131,22 +124,6 @@ fn find_items<'a>(
}) })
} }
fn get_name_definition(
sema: &Semantics<'_, RootDatabase>,
import_candidate: &FileSymbol,
) -> Option<Definition> {
let _p = profile::span("get_name_definition");
let candidate_node = import_candidate.loc.syntax(sema);
let candidate_name_node = if candidate_node.kind() != NAME {
candidate_node.children().find(|it| it.kind() == NAME)?
} else {
candidate_node
};
let name = ast::Name::cast(candidate_name_node)?;
NameClass::classify(sema, &name)?.defined()
}
fn is_assoc_item(item: ItemInNs, db: &RootDatabase) -> bool { fn is_assoc_item(item: ItemInNs, db: &RootDatabase) -> bool {
item.as_module_def().and_then(|module_def| module_def.as_assoc_item(db)).is_some() item.as_module_def().and_then(|module_def| module_def.as_assoc_item(db)).is_some()
} }

View File

@ -49,10 +49,7 @@ use base_db::{
salsa::{self, Durability}, salsa::{self, Durability},
AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast,
}; };
use hir::{ use hir::db::{DefDatabase, ExpandDatabase, HirDatabase};
db::{DefDatabase, ExpandDatabase, HirDatabase},
symbols::FileSymbolKind,
};
use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase}; use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
@ -378,20 +375,22 @@ impl From<hir::MacroKind> for SymbolKind {
} }
} }
impl From<FileSymbolKind> for SymbolKind { impl From<hir::ModuleDefId> for SymbolKind {
fn from(it: FileSymbolKind) -> Self { fn from(it: hir::ModuleDefId) -> Self {
match it { match it {
FileSymbolKind::Const => SymbolKind::Const, hir::ModuleDefId::ConstId(..) => SymbolKind::Const,
FileSymbolKind::Enum => SymbolKind::Enum, hir::ModuleDefId::EnumVariantId(..) => SymbolKind::Variant,
FileSymbolKind::Function => SymbolKind::Function, hir::ModuleDefId::FunctionId(..) => SymbolKind::Function,
FileSymbolKind::Macro => SymbolKind::Macro, hir::ModuleDefId::MacroId(..) => SymbolKind::Macro,
FileSymbolKind::Module => SymbolKind::Module, hir::ModuleDefId::ModuleId(..) => SymbolKind::Module,
FileSymbolKind::Static => SymbolKind::Static, hir::ModuleDefId::StaticId(..) => SymbolKind::Static,
FileSymbolKind::Struct => SymbolKind::Struct, hir::ModuleDefId::AdtId(hir::AdtId::StructId(..)) => SymbolKind::Struct,
FileSymbolKind::Trait => SymbolKind::Trait, hir::ModuleDefId::AdtId(hir::AdtId::EnumId(..)) => SymbolKind::Enum,
FileSymbolKind::TraitAlias => SymbolKind::TraitAlias, hir::ModuleDefId::AdtId(hir::AdtId::UnionId(..)) => SymbolKind::Union,
FileSymbolKind::TypeAlias => SymbolKind::TypeAlias, hir::ModuleDefId::TraitId(..) => SymbolKind::Trait,
FileSymbolKind::Union => SymbolKind::Union, hir::ModuleDefId::TraitAliasId(..) => SymbolKind::TraitAlias,
hir::ModuleDefId::TypeAliasId(..) => SymbolKind::TypeAlias,
hir::ModuleDefId::BuiltinType(..) => SymbolKind::TypeAlias,
} }
} }
} }

View File

@ -317,7 +317,14 @@ impl Query {
let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value); let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value);
for symbol in &symbol_index.symbols[start..end] { for symbol in &symbol_index.symbols[start..end] {
if self.only_types && !symbol.kind.is_type() { if self.only_types
&& !matches!(
symbol.def,
hir::ModuleDef::Adt(..)
| hir::ModuleDef::TypeAlias(..)
| hir::ModuleDef::BuiltinType(..)
)
{
continue; continue;
} }
if self.exact { if self.exact {

View File

@ -10,368 +10,226 @@
[ [
FileSymbol { FileSymbol {
name: "Alias", name: "Alias",
loc: DeclarationLocation { def: TypeAlias(
hir_file_id: HirFileId( TypeAlias {
id: TypeAliasId(
0, 0,
), ),
ptr: SyntaxNodePtr {
kind: TYPE_ALIAS,
range: 397..417,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 402..407,
},
},
kind: TypeAlias,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "CONST", name: "CONST",
loc: DeclarationLocation { def: Const(
hir_file_id: HirFileId( Const {
id: ConstId(
0, 0,
), ),
ptr: SyntaxNodePtr {
kind: CONST,
range: 340..361,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 346..351,
},
},
kind: Const,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "CONST_WITH_INNER", name: "CONST_WITH_INNER",
loc: DeclarationLocation { def: Const(
hir_file_id: HirFileId( Const {
0, id: ConstId(
2,
), ),
ptr: SyntaxNodePtr {
kind: CONST,
range: 520..592,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 526..542,
},
},
kind: Const,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "Enum", name: "Enum",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Enum(
Enum {
id: EnumId(
0, 0,
), ),
ptr: SyntaxNodePtr {
kind: ENUM,
range: 185..207,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME, ),
range: 190..194,
},
},
kind: Enum,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "Macro", name: "Macro",
loc: DeclarationLocation { def: Macro(
hir_file_id: HirFileId( Macro {
id: Macro2Id(
Macro2Id(
0, 0,
), ),
ptr: SyntaxNodePtr { ),
kind: MACRO_DEF,
range: 153..168,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 159..164,
},
},
kind: Macro,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "STATIC", name: "STATIC",
loc: DeclarationLocation { def: Static(
hir_file_id: HirFileId( Static {
id: StaticId(
0, 0,
), ),
ptr: SyntaxNodePtr {
kind: STATIC,
range: 362..396,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 369..375,
},
},
kind: Static,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "Struct", name: "Struct",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Struct(
0, Struct {
id: StructId(
1,
), ),
ptr: SyntaxNodePtr {
kind: STRUCT,
range: 170..184,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME, ),
range: 177..183,
},
},
kind: Struct,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "StructFromMacro", name: "StructFromMacro",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Struct(
2147483648, Struct {
id: StructId(
0,
), ),
ptr: SyntaxNodePtr {
kind: STRUCT,
range: 0..22,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME, ),
range: 6..21,
},
},
kind: Struct,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "StructInFn", name: "StructInFn",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Struct(
0, Struct {
id: StructId(
4,
), ),
ptr: SyntaxNodePtr {
kind: STRUCT,
range: 318..336,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 325..335,
},
},
kind: Struct,
container_name: Some(
"main",
), ),
}, },
FileSymbol { FileSymbol {
name: "StructInNamedConst", name: "StructInNamedConst",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Struct(
0, Struct {
id: StructId(
5,
), ),
ptr: SyntaxNodePtr {
kind: STRUCT,
range: 555..581,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 562..580,
},
},
kind: Struct,
container_name: Some(
"CONST_WITH_INNER",
), ),
}, },
FileSymbol { FileSymbol {
name: "StructInUnnamedConst", name: "StructInUnnamedConst",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Struct(
0, Struct {
id: StructId(
6,
), ),
ptr: SyntaxNodePtr {
kind: STRUCT,
range: 479..507,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME, ),
range: 486..506,
},
},
kind: Struct,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "Trait", name: "Trait",
loc: DeclarationLocation { def: Trait(
hir_file_id: HirFileId( Trait {
id: TraitId(
0, 0,
), ),
ptr: SyntaxNodePtr {
kind: TRAIT,
range: 261..300,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 267..272,
},
},
kind: Trait,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "Union", name: "Union",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Union(
Union {
id: UnionId(
0, 0,
), ),
ptr: SyntaxNodePtr {
kind: UNION,
range: 208..222,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME, ),
range: 214..219,
},
},
kind: Union,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "a_mod", name: "a_mod",
loc: DeclarationLocation { def: Module(
hir_file_id: HirFileId( Module {
0, id: ModuleId {
krate: Idx::<CrateData>(0),
block: None,
local_id: Idx::<ModuleData>(1),
},
},
), ),
ptr: SyntaxNodePtr {
kind: MODULE,
range: 419..457,
},
name_ptr: SyntaxNodePtr {
kind: NAME,
range: 423..428,
},
},
kind: Module,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "b_mod", name: "b_mod",
loc: DeclarationLocation { def: Module(
hir_file_id: HirFileId( Module {
0, id: ModuleId {
krate: Idx::<CrateData>(0),
block: None,
local_id: Idx::<ModuleData>(2),
},
},
), ),
ptr: SyntaxNodePtr {
kind: MODULE,
range: 594..604,
},
name_ptr: SyntaxNodePtr {
kind: NAME,
range: 598..603,
},
},
kind: Module,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "define_struct", name: "define_struct",
loc: DeclarationLocation { def: Macro(
hir_file_id: HirFileId( Macro {
0, id: MacroRulesId(
MacroRulesId(
1,
),
), ),
ptr: SyntaxNodePtr {
kind: MACRO_RULES,
range: 51..131,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 64..77,
},
},
kind: Macro,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "impl_fn", name: "impl_fn",
loc: DeclarationLocation { def: Function(
hir_file_id: HirFileId( Function {
0, id: FunctionId(
2,
), ),
ptr: SyntaxNodePtr {
kind: FN,
range: 242..257,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 245..252,
},
},
kind: Function,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "macro_rules_macro", name: "macro_rules_macro",
loc: DeclarationLocation { def: Macro(
hir_file_id: HirFileId( Macro {
id: MacroRulesId(
MacroRulesId(
0, 0,
), ),
ptr: SyntaxNodePtr { ),
kind: MACRO_RULES,
range: 1..48,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 14..31,
},
},
kind: Macro,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "main", name: "main",
loc: DeclarationLocation { def: Function(
hir_file_id: HirFileId( Function {
id: FunctionId(
0, 0,
), ),
ptr: SyntaxNodePtr {
kind: FN,
range: 302..338,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME,
range: 305..309,
},
},
kind: Function,
container_name: None,
}, },
FileSymbol { FileSymbol {
name: "trait_fn", name: "trait_fn",
loc: DeclarationLocation { def: Function(
hir_file_id: HirFileId( Function {
0, id: FunctionId(
1,
), ),
ptr: SyntaxNodePtr {
kind: FN,
range: 279..298,
}, },
name_ptr: SyntaxNodePtr {
kind: NAME,
range: 282..290,
},
},
kind: Function,
container_name: Some(
"Trait",
), ),
}, },
], ],
@ -387,21 +245,15 @@
[ [
FileSymbol { FileSymbol {
name: "StructInModA", name: "StructInModA",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Struct(
0, Struct {
id: StructId(
2,
), ),
ptr: SyntaxNodePtr {
kind: STRUCT,
range: 435..455,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME, ),
range: 442..454,
},
},
kind: Struct,
container_name: None,
}, },
], ],
), ),
@ -416,21 +268,15 @@
[ [
FileSymbol { FileSymbol {
name: "StructInModB", name: "StructInModB",
loc: DeclarationLocation { def: Adt(
hir_file_id: HirFileId( Struct(
1, Struct {
id: StructId(
3,
), ),
ptr: SyntaxNodePtr {
kind: STRUCT,
range: 0..20,
}, },
name_ptr: SyntaxNodePtr { ),
kind: NAME, ),
range: 7..19,
},
},
kind: Struct,
container_name: None,
}, },
], ],
), ),

View File

@ -263,7 +263,7 @@ mod tests {
expect![["callee Function FileId(0) 0..14 3..9"]], expect![["callee Function FileId(0) 0..14 3..9"]],
expect![[r#" expect![[r#"
caller1 Function FileId(0) 15..45 18..25 : [34..40] caller1 Function FileId(0) 15..45 18..25 : [34..40]
test_caller Function FileId(0) 95..149 110..121 : [134..140]"#]], test_caller Function FileId(0) 95..149 110..121 tests : [134..140]"#]],
expect![[]], expect![[]],
); );
} }
@ -283,7 +283,7 @@ fn caller() {
//- /foo/mod.rs //- /foo/mod.rs
pub fn callee() {} pub fn callee() {}
"#, "#,
expect![["callee Function FileId(1) 0..18 7..13"]], expect!["callee Function FileId(1) 0..18 7..13 foo"],
expect![["caller Function FileId(0) 27..56 30..36 : [45..51]"]], expect![["caller Function FileId(0) 27..56 30..36 : [45..51]"]],
expect![[]], expect![[]],
); );
@ -323,7 +323,7 @@ pub fn callee() {}
"#, "#,
expect![["caller Function FileId(0) 27..56 30..36"]], expect![["caller Function FileId(0) 27..56 30..36"]],
expect![[]], expect![[]],
expect![["callee Function FileId(1) 0..18 7..13 : [45..51]"]], expect!["callee Function FileId(1) 0..18 7..13 foo : [45..51]"],
); );
} }
@ -477,7 +477,7 @@ fn caller() {
S1::callee(); S1::callee();
} }
"#, "#,
expect![["callee Function FileId(0) 15..27 18..24"]], expect!["callee Function FileId(0) 15..27 18..24 T1"],
expect![["caller Function FileId(0) 82..115 85..91 : [104..110]"]], expect![["caller Function FileId(0) 82..115 85..91 : [104..110]"]],
expect![[]], expect![[]],
); );

View File

@ -2209,6 +2209,7 @@ fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
focus_range: 53..54, focus_range: 53..54,
name: "C", name: "C",
kind: Struct, kind: Struct,
container_name: "M",
description: "pub struct C", description: "pub struct C",
}, },
}, },
@ -2544,6 +2545,7 @@ pub mod future {
focus_range: 60..66, focus_range: 60..66,
name: "Future", name: "Future",
kind: Trait, kind: Trait,
container_name: "future",
description: "pub trait Future", description: "pub trait Future",
}, },
}, },

View File

@ -398,7 +398,7 @@ impl Analysis {
self.with_db(|db| { self.with_db(|db| {
symbol_index::world_symbols(db, query) symbol_index::world_symbols(db, query)
.into_iter() // xx: should we make this a par iter? .into_iter() // xx: should we make this a par iter?
.filter_map(|s| s.try_to_nav(db)) .filter_map(|s| s.def.try_to_nav(db))
.collect::<Vec<_>>() .collect::<Vec<_>>()
}) })
} }

View File

@ -4,8 +4,8 @@ use std::fmt;
use either::Either; use either::Either;
use hir::{ use hir::{
symbols::FileSymbol, AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay, AssocItem, Documentation, FieldSource, HasAttrs, HasContainer, HasSource, HirDisplay, InFile,
InFile, LocalSource, ModuleSource, Semantics, LocalSource, ModuleSource,
}; };
use ide_db::{ use ide_db::{
base_db::{FileId, FileRange}, base_db::{FileId, FileRange},
@ -15,7 +15,7 @@ use ide_db::{defs::Definition, RootDatabase};
use stdx::never; use stdx::never;
use syntax::{ use syntax::{
ast::{self, HasName}, ast::{self, HasName},
match_ast, AstNode, SmolStr, SyntaxNode, TextRange, AstNode, SmolStr, SyntaxNode, TextRange,
}; };
/// `NavigationTarget` represents an element in the editor's UI which you can /// `NavigationTarget` represents an element in the editor's UI which you can
@ -158,24 +158,6 @@ impl NavigationTarget {
} }
} }
impl TryToNav for FileSymbol {
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
let full_range = self.loc.original_range(db);
let name_range = self.loc.original_name_range(db)?;
Some(NavigationTarget {
file_id: full_range.file_id,
name: self.name.clone(),
kind: Some(self.kind.into()),
full_range: full_range.range,
focus_range: Some(name_range.range),
container_name: self.container_name.clone(),
description: description_from_symbol(db, self),
docs: None,
})
}
}
impl TryToNav for Definition { impl TryToNav for Definition {
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
match self { match self {
@ -221,38 +203,80 @@ impl TryToNav for hir::ModuleDef {
} }
} }
pub(crate) trait ToNavFromAst { pub(crate) trait ToNavFromAst: Sized {
const KIND: SymbolKind; const KIND: SymbolKind;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
_ = db;
None
} }
}
fn container_name(db: &RootDatabase, t: impl HasContainer) -> Option<SmolStr> {
match t.container(db) {
hir::ItemContainer::Trait(it) => Some(it.name(db).to_smol_str()),
// FIXME: Handle owners of blocks correctly here
hir::ItemContainer::Module(it) => it.name(db).map(|name| name.to_smol_str()),
_ => None,
}
}
impl ToNavFromAst for hir::Function { impl ToNavFromAst for hir::Function {
const KIND: SymbolKind = SymbolKind::Function; const KIND: SymbolKind = SymbolKind::Function;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
} }
}
impl ToNavFromAst for hir::Const { impl ToNavFromAst for hir::Const {
const KIND: SymbolKind = SymbolKind::Const; const KIND: SymbolKind = SymbolKind::Const;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl ToNavFromAst for hir::Static { impl ToNavFromAst for hir::Static {
const KIND: SymbolKind = SymbolKind::Static; const KIND: SymbolKind = SymbolKind::Static;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl ToNavFromAst for hir::Struct { impl ToNavFromAst for hir::Struct {
const KIND: SymbolKind = SymbolKind::Struct; const KIND: SymbolKind = SymbolKind::Struct;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl ToNavFromAst for hir::Enum { impl ToNavFromAst for hir::Enum {
const KIND: SymbolKind = SymbolKind::Enum; const KIND: SymbolKind = SymbolKind::Enum;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl ToNavFromAst for hir::Variant { impl ToNavFromAst for hir::Variant {
const KIND: SymbolKind = SymbolKind::Variant; const KIND: SymbolKind = SymbolKind::Variant;
} }
impl ToNavFromAst for hir::Union { impl ToNavFromAst for hir::Union {
const KIND: SymbolKind = SymbolKind::Union; const KIND: SymbolKind = SymbolKind::Union;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl ToNavFromAst for hir::TypeAlias { impl ToNavFromAst for hir::TypeAlias {
const KIND: SymbolKind = SymbolKind::TypeAlias; const KIND: SymbolKind = SymbolKind::TypeAlias;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl ToNavFromAst for hir::Trait { impl ToNavFromAst for hir::Trait {
const KIND: SymbolKind = SymbolKind::Trait; const KIND: SymbolKind = SymbolKind::Trait;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl ToNavFromAst for hir::TraitAlias { impl ToNavFromAst for hir::TraitAlias {
const KIND: SymbolKind = SymbolKind::TraitAlias; const KIND: SymbolKind = SymbolKind::TraitAlias;
fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
container_name(db, self)
}
} }
impl<D> TryToNav for D impl<D> TryToNav for D
@ -269,6 +293,7 @@ where
); );
res.docs = self.docs(db); res.docs = self.docs(db);
res.description = Some(self.display(db).to_string()); res.description = Some(self.display(db).to_string());
res.container_name = self.container_name(db);
Some(res) Some(res)
} }
} }
@ -544,32 +569,6 @@ impl TryToNav for hir::ConstParam {
} }
} }
/// Get a description of a symbol.
///
/// e.g. `struct Name`, `enum Name`, `fn Name`
pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
let sema = Semantics::new(db);
let node = symbol.loc.syntax(&sema);
match_ast! {
match node {
ast::Fn(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Struct(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Enum(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Trait(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::TraitAlias(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Module(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::TypeAlias(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Const(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Static(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::RecordField(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Variant(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
ast::Union(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
_ => None,
}
}
}
fn orig_focus_range( fn orig_focus_range(
db: &RootDatabase, db: &RootDatabase,
file_id: hir::HirFileId, file_id: hir::HirFileId,
@ -614,7 +613,6 @@ fn foo() { enum FooInner { } }
focus_range: 34..42, focus_range: 34..42,
name: "FooInner", name: "FooInner",
kind: Enum, kind: Enum,
container_name: "foo",
description: "enum FooInner", description: "enum FooInner",
}, },
] ]

View File

@ -715,7 +715,7 @@ fn f() {
} }
"#, "#,
expect![[r#" expect![[r#"
Foo Struct FileId(1) 17..51 28..31 Foo Struct FileId(1) 17..51 28..31 foo
FileId(0) 53..56 FileId(0) 53..56
FileId(2) 79..82 FileId(2) 79..82
@ -803,7 +803,7 @@ pub(super) struct Foo$0 {
} }
"#, "#,
expect![[r#" expect![[r#"
Foo Struct FileId(2) 0..41 18..21 Foo Struct FileId(2) 0..41 18..21 some
FileId(1) 20..23 Import FileId(1) 20..23 Import
FileId(1) 47..50 FileId(1) 47..50
@ -1542,7 +1542,7 @@ fn f() {
FileId(0) 161..165 FileId(0) 161..165
func Function FileId(0) 137..146 140..144 func Function FileId(0) 137..146 140..144 module
FileId(0) 181..185 FileId(0) 181..185
"#]], "#]],
@ -1581,7 +1581,7 @@ trait Trait {
} }
"#, "#,
expect![[r#" expect![[r#"
func Function FileId(0) 48..87 51..55 func Function FileId(0) 48..87 51..55 Trait
FileId(0) 74..78 FileId(0) 74..78
"#]], "#]],
@ -1692,7 +1692,7 @@ fn f<T: Trait>() {
} }
"#, "#,
expect![[r#" expect![[r#"
CONST Const FileId(0) 18..37 24..29 CONST Const FileId(0) 18..37 24..29 Trait
FileId(0) 71..76 FileId(0) 71..76
FileId(0) 125..130 FileId(0) 125..130
@ -1721,7 +1721,7 @@ fn f<T: Trait>() {
} }
"#, "#,
expect![[r#" expect![[r#"
TypeAlias TypeAlias FileId(0) 18..33 23..32 TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait
FileId(0) 66..75 FileId(0) 66..75
FileId(0) 117..126 FileId(0) 117..126
@ -1750,7 +1750,7 @@ fn f<T: Trait>() {
} }
"#, "#,
expect![[r#" expect![[r#"
function Function FileId(0) 18..34 21..29 function Function FileId(0) 18..34 21..29 Trait
FileId(0) 65..73 FileId(0) 65..73
FileId(0) 112..120 FileId(0) 112..120
@ -1894,7 +1894,7 @@ fn f<T: Trait>() {
} }
"#, "#,
expect![[r#" expect![[r#"
TypeAlias TypeAlias FileId(0) 18..33 23..32 TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait
FileId(0) 66..75 FileId(0) 66..75
FileId(0) 117..126 FileId(0) 117..126
@ -1950,7 +1950,7 @@ impl Foo for Bar {
fn method() {} fn method() {}
"#, "#,
expect![[r#" expect![[r#"
method Function FileId(0) 16..39 19..25 method Function FileId(0) 16..39 19..25 Foo
FileId(0) 101..107 FileId(0) 101..107
"#]], "#]],

View File

@ -2579,6 +2579,7 @@ mod r#mod {
), ),
full_range: 47..84, full_range: 47..84,
name: "r#for", name: "r#for",
container_name: "r#mod",
}, },
kind: DocTest { kind: DocTest {
test_id: Path( test_id: Path(
@ -2595,6 +2596,7 @@ mod r#mod {
), ),
full_range: 90..146, full_range: 90..146,
name: "r#struct", name: "r#struct",
container_name: "r#mod",
}, },
kind: DocTest { kind: DocTest {
test_id: Path( test_id: Path(