mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 14:03:35 +00:00
Merge #2327
2327: Move constants to new ID r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
c51dcb1c4b
17 changed files with 287 additions and 175 deletions
|
@ -12,7 +12,7 @@ use hir_def::{
|
||||||
builtin_type::BuiltinType,
|
builtin_type::BuiltinType,
|
||||||
traits::TraitData,
|
traits::TraitData,
|
||||||
type_ref::{Mutability, TypeRef},
|
type_ref::{Mutability, TypeRef},
|
||||||
AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId,
|
AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId,
|
||||||
LocalStructFieldId, Lookup, ModuleId, UnionId,
|
LocalStructFieldId, Lookup, ModuleId, UnionId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
|
@ -697,9 +697,9 @@ impl Function {
|
||||||
|
|
||||||
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
||||||
match self.id.lookup(db).container {
|
match self.id.lookup(db).container {
|
||||||
FunctionContainerId::TraitId(it) => Some(Container::Trait(it.into())),
|
ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
|
||||||
FunctionContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
|
ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
|
||||||
FunctionContainerId::ModuleId(_) => None,
|
ContainerId::ModuleId(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +729,7 @@ pub struct Const {
|
||||||
|
|
||||||
impl Const {
|
impl Const {
|
||||||
pub fn module(self, db: &impl DefDatabase) -> Module {
|
pub fn module(self, db: &impl DefDatabase) -> Module {
|
||||||
Module { id: self.id.module(db) }
|
Module { id: self.id.lookup(db).module(db) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
|
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
|
||||||
|
@ -748,22 +748,27 @@ impl Const {
|
||||||
db.infer(self.into())
|
db.infer(self.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The containing impl block, if this is a method.
|
/// The containing impl block, if this is a type alias.
|
||||||
pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
|
pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
|
||||||
ImplBlock::containing(db, self.into())
|
match self.container(db) {
|
||||||
|
Some(Container::ImplBlock(it)) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The containing trait, if this is a trait type alias definition.
|
||||||
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
||||||
db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from)
|
match self.container(db) {
|
||||||
|
Some(Container::Trait(it)) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
||||||
if let Some(impl_block) = self.impl_block(db) {
|
match self.id.lookup(db).container {
|
||||||
Some(impl_block.into())
|
ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
|
||||||
} else if let Some(trait_) = self.parent_trait(db) {
|
ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
|
||||||
Some(trait_.into())
|
ContainerId::ModuleId(_) => None,
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,30 +959,34 @@ pub struct TypeAlias {
|
||||||
|
|
||||||
impl TypeAlias {
|
impl TypeAlias {
|
||||||
pub fn module(self, db: &impl DefDatabase) -> Module {
|
pub fn module(self, db: &impl DefDatabase) -> Module {
|
||||||
Module { id: self.id.module(db) }
|
Module { id: self.id.lookup(db).module(db) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
|
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
|
||||||
Some(self.module(db).krate())
|
Some(self.module(db).krate())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The containing impl block, if this is a method.
|
/// The containing impl block, if this is a type alias.
|
||||||
pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
|
pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
|
||||||
ImplBlock::containing(db, self.into())
|
match self.container(db) {
|
||||||
|
Some(Container::ImplBlock(it)) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The containing trait, if this is a trait method definition.
|
/// The containing trait, if this is a trait type alias definition.
|
||||||
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
||||||
db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from)
|
match self.container(db) {
|
||||||
|
Some(Container::Trait(it)) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
||||||
if let Some(impl_block) = self.impl_block(db) {
|
match self.id.lookup(db).container {
|
||||||
Some(impl_block.into())
|
ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
|
||||||
} else if let Some(trait_) = self.parent_trait(db) {
|
ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
|
||||||
Some(trait_.into())
|
ContainerId::ModuleId(_) => None,
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ impl HasSource for Function {
|
||||||
impl HasSource for Const {
|
impl HasSource for Const {
|
||||||
type Ast = ast::ConstDef;
|
type Ast = ast::ConstDef;
|
||||||
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> {
|
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> {
|
||||||
self.id.source(db)
|
self.id.lookup(db).source(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl HasSource for Static {
|
impl HasSource for Static {
|
||||||
|
@ -138,7 +138,7 @@ impl HasSource for Trait {
|
||||||
impl HasSource for TypeAlias {
|
impl HasSource for TypeAlias {
|
||||||
type Ast = ast::TypeAliasDef;
|
type Ast = ast::TypeAliasDef;
|
||||||
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> {
|
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> {
|
||||||
self.id.source(db)
|
self.id.lookup(db).source(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl HasSource for MacroDef {
|
impl HasSource for MacroDef {
|
||||||
|
|
|
@ -26,7 +26,6 @@ pub use hir_def::db::{
|
||||||
BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
|
BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
|
||||||
EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
|
EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
|
||||||
RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery,
|
RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery,
|
||||||
TraitItemsIndexQuery,
|
|
||||||
};
|
};
|
||||||
pub use hir_expand::db::{
|
pub use hir_expand::db::{
|
||||||
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId};
|
||||||
use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
|
use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode, NameOwner},
|
ast::{self, AstNode, NameOwner},
|
||||||
match_ast, AstPtr,
|
match_ast, AstPtr, SyntaxNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -52,56 +52,54 @@ impl FromSource for Trait {
|
||||||
impl FromSource for Function {
|
impl FromSource for Function {
|
||||||
type Ast = ast::FnDef;
|
type Ast = ast::FnDef;
|
||||||
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
|
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
|
||||||
// FIXME: this doesn't try to handle nested declarations
|
let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
|
||||||
for container in src.value.syntax().ancestors() {
|
Container::Trait(it) => it.items(db),
|
||||||
let res = match_ast! {
|
Container::ImplBlock(it) => it.items(db),
|
||||||
match container {
|
Container::Module(m) => {
|
||||||
ast::TraitDef(it) => {
|
return m
|
||||||
let c = Trait::from_source(db, src.with_value(it))?;
|
.declarations(db)
|
||||||
c.items(db)
|
.into_iter()
|
||||||
.into_iter()
|
.filter_map(|it| match it {
|
||||||
.filter_map(|it| match it {
|
ModuleDef::Function(it) => Some(it),
|
||||||
AssocItem::Function(it) => Some(it),
|
_ => None,
|
||||||
_ => None
|
})
|
||||||
})
|
.find(|it| same_source(&it.source(db), &src))
|
||||||
.find(|it| same_source(&it.source(db), &src))?
|
}
|
||||||
},
|
};
|
||||||
ast::ImplBlock(it) => {
|
items
|
||||||
let c = ImplBlock::from_source(db, src.with_value(it))?;
|
|
||||||
c.items(db)
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|it| match it {
|
|
||||||
AssocItem::Function(it) => Some(it),
|
|
||||||
_ => None
|
|
||||||
})
|
|
||||||
.find(|it| same_source(&it.source(db), &src))?
|
|
||||||
|
|
||||||
},
|
|
||||||
_ => { continue },
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return Some(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
let module_source = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
|
|
||||||
let c = Module::from_definition(db, src.with_value(module_source))?;
|
|
||||||
let res = c
|
|
||||||
.declarations(db)
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|it| match it {
|
.filter_map(|it| match it {
|
||||||
ModuleDef::Function(it) => Some(it),
|
AssocItem::Function(it) => Some(it),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.find(|it| same_source(&it.source(db), &src));
|
.find(|it| same_source(&it.source(db), &src))
|
||||||
res
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSource for Const {
|
impl FromSource for Const {
|
||||||
type Ast = ast::ConstDef;
|
type Ast = ast::ConstDef;
|
||||||
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
|
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
|
||||||
let id = from_source(db, src)?;
|
let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
|
||||||
Some(Const { id })
|
Container::Trait(it) => it.items(db),
|
||||||
|
Container::ImplBlock(it) => it.items(db),
|
||||||
|
Container::Module(m) => {
|
||||||
|
return m
|
||||||
|
.declarations(db)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|it| match it {
|
||||||
|
ModuleDef::Const(it) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.find(|it| same_source(&it.source(db), &src))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
items
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|it| match it {
|
||||||
|
AssocItem::Const(it) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.find(|it| same_source(&it.source(db), &src))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl FromSource for Static {
|
impl FromSource for Static {
|
||||||
|
@ -114,8 +112,27 @@ impl FromSource for Static {
|
||||||
impl FromSource for TypeAlias {
|
impl FromSource for TypeAlias {
|
||||||
type Ast = ast::TypeAliasDef;
|
type Ast = ast::TypeAliasDef;
|
||||||
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
|
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
|
||||||
let id = from_source(db, src)?;
|
let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
|
||||||
Some(TypeAlias { id })
|
Container::Trait(it) => it.items(db),
|
||||||
|
Container::ImplBlock(it) => it.items(db),
|
||||||
|
Container::Module(m) => {
|
||||||
|
return m
|
||||||
|
.declarations(db)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|it| match it {
|
||||||
|
ModuleDef::TypeAlias(it) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.find(|it| same_source(&it.source(db), &src))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
items
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|it| match it {
|
||||||
|
AssocItem::TypeAlias(it) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.find(|it| same_source(&it.source(db), &src))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,11 +275,43 @@ where
|
||||||
Some(DEF::from_ast(ctx, &src.value))
|
Some(DEF::from_ast(ctx, &src.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Container {
|
||||||
|
Trait(Trait),
|
||||||
|
ImplBlock(ImplBlock),
|
||||||
|
Module(Module),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Container {
|
||||||
|
fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option<Container> {
|
||||||
|
// FIXME: this doesn't try to handle nested declarations
|
||||||
|
for container in src.value.ancestors() {
|
||||||
|
let res = match_ast! {
|
||||||
|
match container {
|
||||||
|
ast::TraitDef(it) => {
|
||||||
|
let c = Trait::from_source(db, src.with_value(it))?;
|
||||||
|
Container::Trait(c)
|
||||||
|
},
|
||||||
|
ast::ImplBlock(it) => {
|
||||||
|
let c = ImplBlock::from_source(db, src.with_value(it))?;
|
||||||
|
Container::ImplBlock(c)
|
||||||
|
},
|
||||||
|
_ => { continue },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Some(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
let module_source = ModuleSource::from_child_node(db, src);
|
||||||
|
let c = Module::from_definition(db, src.with_value(module_source))?;
|
||||||
|
Some(Container::Module(c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
|
/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
|
||||||
/// equal if they point to exactly the same object.
|
/// equal if they point to exactly the same object.
|
||||||
///
|
///
|
||||||
/// In general, we do not guarantee that we have exactly one instance of a
|
/// In general, we do not guarantee that we have exactly one instance of a
|
||||||
/// syntax tree for each file. We probably should add such guanratree, but, for
|
/// syntax tree for each file. We probably should add such guarantee, but, for
|
||||||
/// the time being, we will use identity-less AstPtr comparison.
|
/// the time being, we will use identity-less AstPtr comparison.
|
||||||
fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool {
|
fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool {
|
||||||
s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new)
|
s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new)
|
||||||
|
|
|
@ -19,14 +19,6 @@ impl HasSource for ImplBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImplBlock {
|
impl ImplBlock {
|
||||||
pub(crate) fn containing(db: &impl DefDatabase, item: AssocItem) -> Option<ImplBlock> {
|
|
||||||
let module = item.module(db);
|
|
||||||
let crate_def_map = db.crate_def_map(module.id.krate);
|
|
||||||
crate_def_map[module.id.module_id].impls.iter().copied().map(ImplBlock::from).find(|it| {
|
|
||||||
db.impl_data(it.id).items().iter().copied().map(AssocItem::from).any(|it| it == item)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
|
pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
|
||||||
db.impl_data(self.id).target_trait().cloned()
|
db.impl_data(self.id).target_trait().cloned()
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ fn def_with_body_from_child_node(
|
||||||
match_ast! {
|
match_ast! {
|
||||||
match node {
|
match node {
|
||||||
ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); },
|
ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); },
|
||||||
ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) },
|
ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); },
|
||||||
ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) },
|
ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) },
|
||||||
_ => { None },
|
_ => { None },
|
||||||
}
|
}
|
||||||
|
@ -428,6 +428,11 @@ impl SourceAnalyzer {
|
||||||
pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> {
|
pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> {
|
||||||
self.infer.clone().unwrap()
|
self.infer.clone().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn analyzed_declaration(&self) -> Option<DefWithBody> {
|
||||||
|
self.body_owner
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scope_for(
|
fn scope_for(
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
mod autoderef;
|
mod autoderef;
|
||||||
pub(crate) mod primitive;
|
pub(crate) mod primitive;
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
pub(crate) mod traits;
|
pub(crate) mod traits;
|
||||||
pub(crate) mod method_resolution;
|
pub(crate) mod method_resolution;
|
||||||
mod op;
|
mod op;
|
||||||
|
@ -12,6 +10,9 @@ mod lower;
|
||||||
mod infer;
|
mod infer;
|
||||||
pub(crate) mod display;
|
pub(crate) mod display;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{fmt, iter, mem};
|
use std::{fmt, iter, mem};
|
||||||
|
|
|
@ -11,6 +11,7 @@ use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
};
|
};
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
use test_utils::covers;
|
use test_utils::covers;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -2518,7 +2519,6 @@ fn test() {
|
||||||
[167; 179) 'GLOBAL_CONST': u32
|
[167; 179) 'GLOBAL_CONST': u32
|
||||||
[189; 191) 'id': u32
|
[189; 191) 'id': u32
|
||||||
[194; 210) 'Foo::A..._CONST': u32
|
[194; 210) 'Foo::A..._CONST': u32
|
||||||
[126; 128) '99': u32
|
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4742,10 +4742,13 @@ fn infer(content: &str) -> String {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut analyzed = FxHashSet::default();
|
||||||
for node in source_file.syntax().descendants() {
|
for node in source_file.syntax().descendants() {
|
||||||
if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF {
|
if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF {
|
||||||
let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None);
|
let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None);
|
||||||
infer_def(analyzer.inference_result(), analyzer.body_source_map());
|
if analyzed.insert(analyzer.analyzed_declaration()) {
|
||||||
|
infer_def(analyzer.inference_result(), analyzer.body_source_map());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ impl Body {
|
||||||
(src.file_id, f.module(db), src.value.body().map(ast::Expr::from))
|
(src.file_id, f.module(db), src.value.body().map(ast::Expr::from))
|
||||||
}
|
}
|
||||||
DefWithBodyId::ConstId(c) => {
|
DefWithBodyId::ConstId(c) => {
|
||||||
|
let c = c.lookup(db);
|
||||||
let src = c.source(db);
|
let src = c.source(db);
|
||||||
(src.file_id, c.module(db), src.value.body())
|
(src.file_id, c.module(db), src.value.body())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,26 +13,26 @@ use crate::{
|
||||||
raw::{ImportSourceMap, RawItems},
|
raw::{ImportSourceMap, RawItems},
|
||||||
CrateDefMap,
|
CrateDefMap,
|
||||||
},
|
},
|
||||||
traits::{TraitData, TraitItemsIndex},
|
traits::TraitData,
|
||||||
DefWithBodyId, EnumId, FunctionLoc, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId,
|
DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, TraitId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[salsa::query_group(InternDatabaseStorage)]
|
#[salsa::query_group(InternDatabaseStorage)]
|
||||||
pub trait InternDatabase: SourceDatabase {
|
pub trait InternDatabase: SourceDatabase {
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_function(&self, loc: FunctionLoc) -> crate::FunctionId;
|
fn intern_function(&self, loc: crate::FunctionLoc) -> crate::FunctionId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId;
|
fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId;
|
fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_const(&self, loc: ItemLoc<ast::ConstDef>) -> crate::ConstId;
|
fn intern_const(&self, loc: crate::ConstLoc) -> crate::ConstId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId;
|
fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId;
|
fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_type_alias(&self, loc: ItemLoc<ast::TypeAliasDef>) -> crate::TypeAliasId;
|
fn intern_type_alias(&self, loc: crate::TypeAliasLoc) -> crate::TypeAliasId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId;
|
fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId;
|
||||||
}
|
}
|
||||||
|
@ -63,9 +63,6 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
|
||||||
#[salsa::invoke(TraitData::trait_data_query)]
|
#[salsa::invoke(TraitData::trait_data_query)]
|
||||||
fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
|
fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
|
||||||
|
|
||||||
#[salsa::invoke(TraitItemsIndex::trait_items_index)]
|
|
||||||
fn trait_items_index(&self, module: ModuleId) -> TraitItemsIndex;
|
|
||||||
|
|
||||||
#[salsa::invoke(Body::body_with_source_map_query)]
|
#[salsa::invoke(Body::body_with_source_map_query)]
|
||||||
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
|
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl GenericParams {
|
||||||
let self_param = TypeRef::Path(name::SELF_TYPE.into());
|
let self_param = TypeRef::Path(name::SELF_TYPE.into());
|
||||||
generics.fill_bounds(&it.source(db).value, self_param);
|
generics.fill_bounds(&it.source(db).value, self_param);
|
||||||
}
|
}
|
||||||
GenericDefId::TypeAliasId(it) => generics.fill(&it.source(db).value, start),
|
GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start),
|
||||||
// Note that we don't add `Self` here: in `impl`s, `Self` is not a
|
// Note that we don't add `Self` here: in `impl`s, `Self` is not a
|
||||||
// type-parameter, but rather is a type-alias for impl's target
|
// type-parameter, but rather is a type-alias for impl's target
|
||||||
// type, so this is handled by the resolver.
|
// type, so this is handled by the resolver.
|
||||||
|
|
|
@ -9,8 +9,8 @@ use hir_expand::AstId;
|
||||||
use ra_syntax::ast;
|
use ra_syntax::ast;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionContainerId,
|
db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstLoc, ContainerId,
|
||||||
FunctionLoc, ImplId, Intern, LocationCtx, TypeAliasId,
|
FunctionLoc, ImplId, Intern, TypeAliasLoc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -31,23 +31,32 @@ impl ImplData {
|
||||||
let negative = src.value.is_negative();
|
let negative = src.value.is_negative();
|
||||||
|
|
||||||
let items = if let Some(item_list) = src.value.item_list() {
|
let items = if let Some(item_list) = src.value.item_list() {
|
||||||
let ctx = LocationCtx::new(db, id.module(db), src.file_id);
|
|
||||||
item_list
|
item_list
|
||||||
.impl_items()
|
.impl_items()
|
||||||
.map(|item_node| match item_node {
|
.map(|item_node| match item_node {
|
||||||
ast::ImplItem::FnDef(it) => {
|
ast::ImplItem::FnDef(it) => {
|
||||||
let func_id = FunctionLoc {
|
let def = FunctionLoc {
|
||||||
container: FunctionContainerId::ImplId(id),
|
container: ContainerId::ImplId(id),
|
||||||
ast_id: AstId::new(src.file_id, items.ast_id(&it)),
|
ast_id: AstId::new(src.file_id, items.ast_id(&it)),
|
||||||
}
|
}
|
||||||
.intern(db);
|
.intern(db);
|
||||||
func_id.into()
|
def.into()
|
||||||
}
|
}
|
||||||
ast::ImplItem::ConstDef(it) => {
|
ast::ImplItem::ConstDef(it) => {
|
||||||
ConstId::from_ast_id(ctx, items.ast_id(&it)).into()
|
let def = ConstLoc {
|
||||||
|
container: ContainerId::ImplId(id),
|
||||||
|
ast_id: AstId::new(src.file_id, items.ast_id(&it)),
|
||||||
|
}
|
||||||
|
.intern(db);
|
||||||
|
def.into()
|
||||||
}
|
}
|
||||||
ast::ImplItem::TypeAliasDef(it) => {
|
ast::ImplItem::TypeAliasDef(it) => {
|
||||||
TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into()
|
let def = TypeAliasLoc {
|
||||||
|
container: ContainerId::ImplId(id),
|
||||||
|
ast_id: AstId::new(src.file_id, items.ast_id(&it)),
|
||||||
|
}
|
||||||
|
.intern(db);
|
||||||
|
def.into()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -201,7 +201,7 @@ impl_intern_key!(FunctionId);
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct FunctionLoc {
|
pub struct FunctionLoc {
|
||||||
pub container: FunctionContainerId,
|
pub container: ContainerId,
|
||||||
pub ast_id: AstId<ast::FnDef>,
|
pub ast_id: AstId<ast::FnDef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,13 +219,6 @@ impl Lookup for FunctionId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
pub enum FunctionContainerId {
|
|
||||||
ModuleId(ModuleId),
|
|
||||||
ImplId(ImplId),
|
|
||||||
TraitId(TraitId),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct StructOrUnionId(salsa::InternId);
|
pub struct StructOrUnionId(salsa::InternId);
|
||||||
impl_intern_key!(StructOrUnionId);
|
impl_intern_key!(StructOrUnionId);
|
||||||
|
@ -296,12 +289,23 @@ impl_arena_id!(LocalStructFieldId);
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct ConstId(salsa::InternId);
|
pub struct ConstId(salsa::InternId);
|
||||||
impl_intern_key!(ConstId);
|
impl_intern_key!(ConstId);
|
||||||
impl AstItemDef<ast::ConstDef> for ConstId {
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self {
|
pub struct ConstLoc {
|
||||||
db.intern_const(loc)
|
pub container: ContainerId,
|
||||||
|
pub ast_id: AstId<ast::ConstDef>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Intern for ConstLoc {
|
||||||
|
type ID = ConstId;
|
||||||
|
fn intern(self, db: &impl db::DefDatabase2) -> ConstId {
|
||||||
|
db.intern_const(self)
|
||||||
}
|
}
|
||||||
fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ConstDef> {
|
}
|
||||||
db.lookup_intern_const(self)
|
|
||||||
|
impl Lookup for ConstId {
|
||||||
|
type Data = ConstLoc;
|
||||||
|
fn lookup(&self, db: &impl db::DefDatabase2) -> ConstLoc {
|
||||||
|
db.lookup_intern_const(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,12 +336,24 @@ impl AstItemDef<ast::TraitDef> for TraitId {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct TypeAliasId(salsa::InternId);
|
pub struct TypeAliasId(salsa::InternId);
|
||||||
impl_intern_key!(TypeAliasId);
|
impl_intern_key!(TypeAliasId);
|
||||||
impl AstItemDef<ast::TypeAliasDef> for TypeAliasId {
|
|
||||||
fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self {
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
db.intern_type_alias(loc)
|
pub struct TypeAliasLoc {
|
||||||
|
pub container: ContainerId,
|
||||||
|
pub ast_id: AstId<ast::TypeAliasDef>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Intern for TypeAliasLoc {
|
||||||
|
type ID = TypeAliasId;
|
||||||
|
fn intern(self, db: &impl db::DefDatabase2) -> TypeAliasId {
|
||||||
|
db.intern_type_alias(self)
|
||||||
}
|
}
|
||||||
fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TypeAliasDef> {
|
}
|
||||||
db.lookup_intern_type_alias(self)
|
|
||||||
|
impl Lookup for TypeAliasId {
|
||||||
|
type Data = TypeAliasLoc;
|
||||||
|
fn lookup(&self, db: &impl db::DefDatabase2) -> TypeAliasLoc {
|
||||||
|
db.lookup_intern_type_alias(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +388,13 @@ macro_rules! impl_froms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ContainerId {
|
||||||
|
ModuleId(ModuleId),
|
||||||
|
ImplId(ImplId),
|
||||||
|
TraitId(TraitId),
|
||||||
|
}
|
||||||
|
|
||||||
/// A Data Type
|
/// A Data Type
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum AdtId {
|
pub enum AdtId {
|
||||||
|
@ -469,9 +492,29 @@ pub trait HasModule {
|
||||||
impl HasModule for FunctionLoc {
|
impl HasModule for FunctionLoc {
|
||||||
fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
|
fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
|
||||||
match self.container {
|
match self.container {
|
||||||
FunctionContainerId::ModuleId(it) => it,
|
ContainerId::ModuleId(it) => it,
|
||||||
FunctionContainerId::ImplId(it) => it.module(db),
|
ContainerId::ImplId(it) => it.module(db),
|
||||||
FunctionContainerId::TraitId(it) => it.module(db),
|
ContainerId::TraitId(it) => it.module(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasModule for TypeAliasLoc {
|
||||||
|
fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
|
||||||
|
match self.container {
|
||||||
|
ContainerId::ModuleId(it) => it,
|
||||||
|
ContainerId::ImplId(it) => it.module(db),
|
||||||
|
ContainerId::TraitId(it) => it.module(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasModule for ConstLoc {
|
||||||
|
fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
|
||||||
|
match self.container {
|
||||||
|
ContainerId::ModuleId(it) => it,
|
||||||
|
ContainerId::ImplId(it) => it.module(db),
|
||||||
|
ContainerId::TraitId(it) => it.module(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,3 +532,21 @@ impl HasSource for FunctionLoc {
|
||||||
Source::new(self.ast_id.file_id(), node)
|
Source::new(self.ast_id.file_id(), node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasSource for TypeAliasLoc {
|
||||||
|
type Value = ast::TypeAliasDef;
|
||||||
|
|
||||||
|
fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::TypeAliasDef> {
|
||||||
|
let node = self.ast_id.to_node(db);
|
||||||
|
Source::new(self.ast_id.file_id(), node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasSource for ConstLoc {
|
||||||
|
type Value = ast::ConstDef;
|
||||||
|
|
||||||
|
fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::ConstDef> {
|
||||||
|
let node = self.ast_id.to_node(db);
|
||||||
|
Source::new(self.ast_id.file_id(), node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,9 +19,9 @@ use crate::{
|
||||||
per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode,
|
per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode,
|
||||||
},
|
},
|
||||||
path::{Path, PathKind},
|
path::{Path, PathKind},
|
||||||
AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionContainerId,
|
AdtId, AstId, AstItemDef, ConstLoc, ContainerId, CrateModuleId, EnumId, EnumVariantId,
|
||||||
FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId,
|
FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId,
|
||||||
StructOrUnionId, TraitId, TypeAliasId, UnionId,
|
StructOrUnionId, TraitId, TypeAliasLoc, UnionId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap {
|
pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap {
|
||||||
|
@ -673,13 +673,13 @@ where
|
||||||
let name = def.name.clone();
|
let name = def.name.clone();
|
||||||
let def: PerNs = match def.kind {
|
let def: PerNs = match def.kind {
|
||||||
raw::DefKind::Function(ast_id) => {
|
raw::DefKind::Function(ast_id) => {
|
||||||
let f = FunctionLoc {
|
let def = FunctionLoc {
|
||||||
container: FunctionContainerId::ModuleId(module),
|
container: ContainerId::ModuleId(module),
|
||||||
ast_id: AstId::new(self.file_id, ast_id),
|
ast_id: AstId::new(self.file_id, ast_id),
|
||||||
}
|
}
|
||||||
.intern(self.def_collector.db);
|
.intern(self.def_collector.db);
|
||||||
|
|
||||||
PerNs::values(f.into())
|
PerNs::values(def.into())
|
||||||
}
|
}
|
||||||
raw::DefKind::Struct(ast_id) => {
|
raw::DefKind::Struct(ast_id) => {
|
||||||
let id = StructOrUnionId::from_ast_id(ctx, ast_id).into();
|
let id = StructOrUnionId::from_ast_id(ctx, ast_id).into();
|
||||||
|
@ -692,13 +692,27 @@ where
|
||||||
PerNs::both(u, u)
|
PerNs::both(u, u)
|
||||||
}
|
}
|
||||||
raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
|
raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
|
||||||
raw::DefKind::Const(ast_id) => PerNs::values(ConstId::from_ast_id(ctx, ast_id).into()),
|
raw::DefKind::Const(ast_id) => {
|
||||||
|
let def = ConstLoc {
|
||||||
|
container: ContainerId::ModuleId(module),
|
||||||
|
ast_id: AstId::new(self.file_id, ast_id),
|
||||||
|
}
|
||||||
|
.intern(self.def_collector.db);
|
||||||
|
|
||||||
|
PerNs::values(def.into())
|
||||||
|
}
|
||||||
raw::DefKind::Static(ast_id) => {
|
raw::DefKind::Static(ast_id) => {
|
||||||
PerNs::values(StaticId::from_ast_id(ctx, ast_id).into())
|
PerNs::values(StaticId::from_ast_id(ctx, ast_id).into())
|
||||||
}
|
}
|
||||||
raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()),
|
raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()),
|
||||||
raw::DefKind::TypeAlias(ast_id) => {
|
raw::DefKind::TypeAlias(ast_id) => {
|
||||||
PerNs::types(TypeAliasId::from_ast_id(ctx, ast_id).into())
|
let def = TypeAliasLoc {
|
||||||
|
container: ContainerId::ModuleId(module),
|
||||||
|
ast_id: AstId::new(self.file_id, ast_id),
|
||||||
|
}
|
||||||
|
.intern(self.def_collector.db);
|
||||||
|
|
||||||
|
PerNs::types(def.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let resolution = Resolution { def, import: None };
|
let resolution = Resolution { def, import: None };
|
||||||
|
|
|
@ -8,11 +8,10 @@ use hir_expand::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use ra_syntax::ast::{self, NameOwner};
|
use ra_syntax::ast::{self, NameOwner};
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern,
|
db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId,
|
||||||
LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasId,
|
TypeAliasLoc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -26,8 +25,6 @@ impl TraitData {
|
||||||
pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
|
pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
|
||||||
let src = tr.source(db);
|
let src = tr.source(db);
|
||||||
let name = src.value.name().map(|n| n.as_name());
|
let name = src.value.name().map(|n| n.as_name());
|
||||||
let module = tr.module(db);
|
|
||||||
let ctx = LocationCtx::new(db, module, src.file_id);
|
|
||||||
let auto = src.value.is_auto();
|
let auto = src.value.is_auto();
|
||||||
let ast_id_map = db.ast_id_map(src.file_id);
|
let ast_id_map = db.ast_id_map(src.file_id);
|
||||||
let items = if let Some(item_list) = src.value.item_list() {
|
let items = if let Some(item_list) = src.value.item_list() {
|
||||||
|
@ -35,13 +32,23 @@ impl TraitData {
|
||||||
.impl_items()
|
.impl_items()
|
||||||
.map(|item_node| match item_node {
|
.map(|item_node| match item_node {
|
||||||
ast::ImplItem::FnDef(it) => FunctionLoc {
|
ast::ImplItem::FnDef(it) => FunctionLoc {
|
||||||
container: FunctionContainerId::TraitId(tr),
|
container: ContainerId::TraitId(tr),
|
||||||
|
ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
|
||||||
|
}
|
||||||
|
.intern(db)
|
||||||
|
.into(),
|
||||||
|
ast::ImplItem::ConstDef(it) => ConstLoc {
|
||||||
|
container: ContainerId::TraitId(tr),
|
||||||
|
ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
|
||||||
|
}
|
||||||
|
.intern(db)
|
||||||
|
.into(),
|
||||||
|
ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc {
|
||||||
|
container: ContainerId::TraitId(tr),
|
||||||
ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
|
ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
|
||||||
}
|
}
|
||||||
.intern(db)
|
.intern(db)
|
||||||
.into(),
|
.into(),
|
||||||
ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(),
|
|
||||||
ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(),
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,33 +57,3 @@ impl TraitData {
|
||||||
Arc::new(TraitData { name, items, auto })
|
Arc::new(TraitData { name, items, auto })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct TraitItemsIndex {
|
|
||||||
traits_by_def: FxHashMap<AssocItemId, TraitId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TraitItemsIndex {
|
|
||||||
pub fn trait_items_index(db: &impl DefDatabase2, module: ModuleId) -> TraitItemsIndex {
|
|
||||||
let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() };
|
|
||||||
let crate_def_map = db.crate_def_map(module.krate);
|
|
||||||
for decl in crate_def_map[module.module_id].scope.declarations() {
|
|
||||||
if let ModuleDefId::TraitId(tr) = decl {
|
|
||||||
for item in db.trait_data(tr).items.iter() {
|
|
||||||
match item {
|
|
||||||
AssocItemId::FunctionId(_) => (),
|
|
||||||
_ => {
|
|
||||||
let prev = index.traits_by_def.insert(*item, tr);
|
|
||||||
assert!(prev.is_none());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_parent_trait(&self, item: AssocItemId) -> Option<TraitId> {
|
|
||||||
self.traits_by_def.get(&item).cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -309,7 +309,6 @@ impl RootDatabase {
|
||||||
hir::db::StructDataQuery
|
hir::db::StructDataQuery
|
||||||
hir::db::EnumDataQuery
|
hir::db::EnumDataQuery
|
||||||
hir::db::TraitDataQuery
|
hir::db::TraitDataQuery
|
||||||
hir::db::TraitItemsIndexQuery
|
|
||||||
hir::db::RawItemsWithSourceMapQuery
|
hir::db::RawItemsWithSourceMapQuery
|
||||||
hir::db::RawItemsQuery
|
hir::db::RawItemsQuery
|
||||||
hir::db::CrateDefMapQuery
|
hir::db::CrateDefMapQuery
|
||||||
|
|
|
@ -404,9 +404,7 @@ mod tests {
|
||||||
check_hover_result(
|
check_hover_result(
|
||||||
r#"
|
r#"
|
||||||
//- /main.rs
|
//- /main.rs
|
||||||
fn main() {
|
const foo<|>: u32 = 0;
|
||||||
const foo<|>: u32 = 0;
|
|
||||||
}
|
|
||||||
"#,
|
"#,
|
||||||
&["const foo: u32"],
|
&["const foo: u32"],
|
||||||
);
|
);
|
||||||
|
@ -414,9 +412,7 @@ mod tests {
|
||||||
check_hover_result(
|
check_hover_result(
|
||||||
r#"
|
r#"
|
||||||
//- /main.rs
|
//- /main.rs
|
||||||
fn main() {
|
static foo<|>: u32 = 0;
|
||||||
static foo<|>: u32 = 0;
|
|
||||||
}
|
|
||||||
"#,
|
"#,
|
||||||
&["static foo: u32"],
|
&["static foo: u32"],
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue