mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 15:15:24 +00:00
Move constants to new ID
This allows us to get rid of trait item index
This commit is contained in:
parent
ee95a35664
commit
111891dc2d
16 changed files with 119 additions and 89 deletions
|
@ -729,7 +729,7 @@ pub struct Const {
|
|||
|
||||
impl Const {
|
||||
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> {
|
||||
|
@ -748,22 +748,27 @@ impl Const {
|
|||
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> {
|
||||
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> {
|
||||
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> {
|
||||
if let Some(impl_block) = self.impl_block(db) {
|
||||
Some(impl_block.into())
|
||||
} else if let Some(trait_) = self.parent_trait(db) {
|
||||
Some(trait_.into())
|
||||
} else {
|
||||
None
|
||||
match self.id.lookup(db).container {
|
||||
ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
|
||||
ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
|
||||
ContainerId::ModuleId(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ impl HasSource for Function {
|
|||
impl HasSource for Const {
|
||||
type Ast = 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 {
|
||||
|
|
|
@ -26,7 +26,6 @@ pub use hir_def::db::{
|
|||
BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
|
||||
EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
|
||||
RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery,
|
||||
TraitItemsIndexQuery,
|
||||
};
|
||||
pub use hir_expand::db::{
|
||||
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
||||
|
|
|
@ -79,8 +79,27 @@ impl FromSource for Function {
|
|||
impl FromSource for Const {
|
||||
type Ast = ast::ConstDef;
|
||||
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
|
||||
let id = from_source(db, src)?;
|
||||
Some(Const { id })
|
||||
let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
|
||||
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 {
|
||||
|
@ -292,7 +311,7 @@ impl Container {
|
|||
/// equal if they point to exactly the same object.
|
||||
///
|
||||
/// 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.
|
||||
fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool {
|
||||
s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new)
|
||||
|
|
|
@ -19,14 +19,6 @@ impl HasSource for 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> {
|
||||
db.impl_data(self.id).target_trait().cloned()
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ fn def_with_body_from_child_node(
|
|||
match_ast! {
|
||||
match node {
|
||||
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()) },
|
||||
_ => { None },
|
||||
}
|
||||
|
@ -428,6 +428,11 @@ impl SourceAnalyzer {
|
|||
pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> {
|
||||
self.infer.clone().unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn analyzed_declaration(&self) -> Option<DefWithBody> {
|
||||
self.body_owner
|
||||
}
|
||||
}
|
||||
|
||||
fn scope_for(
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
mod autoderef;
|
||||
pub(crate) mod primitive;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
pub(crate) mod traits;
|
||||
pub(crate) mod method_resolution;
|
||||
mod op;
|
||||
|
@ -12,6 +10,9 @@ mod lower;
|
|||
mod infer;
|
||||
pub(crate) mod display;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use std::{fmt, iter, mem};
|
||||
|
|
|
@ -11,6 +11,7 @@ use ra_syntax::{
|
|||
ast::{self, AstNode},
|
||||
SyntaxKind::*,
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use test_utils::covers;
|
||||
|
||||
use crate::{
|
||||
|
@ -2518,7 +2519,6 @@ fn test() {
|
|||
[167; 179) 'GLOBAL_CONST': u32
|
||||
[189; 191) 'id': 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() {
|
||||
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);
|
||||
infer_def(analyzer.inference_result(), analyzer.body_source_map());
|
||||
if analyzed.insert(analyzer.analyzed_declaration()) {
|
||||
infer_def(analyzer.inference_result(), analyzer.body_source_map());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue