Move constants to new ID

This allows us to get rid of trait item index
This commit is contained in:
Aleksey Kladov 2019-11-20 18:00:01 +03:00
parent ee95a35664
commit 111891dc2d
16 changed files with 119 additions and 89 deletions

View file

@ -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,
}
}

View file

@ -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 {

View file

@ -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,

View file

@ -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)

View file

@ -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()
}

View file

@ -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(

View file

@ -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};

View file

@ -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,12 +4742,15 @@ 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);
if analyzed.insert(analyzer.analyzed_declaration()) {
infer_def(analyzer.inference_result(), analyzer.body_source_map());
}
}
}
acc.truncate(acc.trim_end().len());
acc

View file

@ -155,6 +155,7 @@ impl Body {
(src.file_id, f.module(db), src.value.body().map(ast::Expr::from))
}
DefWithBodyId::ConstId(c) => {
let c = c.lookup(db);
let src = c.source(db);
(src.file_id, c.module(db), src.value.body())
}

View file

@ -13,8 +13,8 @@ use crate::{
raw::{ImportSourceMap, RawItems},
CrateDefMap,
},
traits::{TraitData, TraitItemsIndex},
DefWithBodyId, EnumId, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId,
traits::TraitData,
DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, TraitId,
};
#[salsa::query_group(InternDatabaseStorage)]
@ -26,7 +26,7 @@ pub trait InternDatabase: SourceDatabase {
#[salsa::interned]
fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId;
#[salsa::interned]
fn intern_const(&self, loc: ItemLoc<ast::ConstDef>) -> crate::ConstId;
fn intern_const(&self, loc: crate::ConstLoc) -> crate::ConstId;
#[salsa::interned]
fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId;
#[salsa::interned]
@ -63,9 +63,6 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
#[salsa::invoke(TraitData::trait_data_query)]
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)]
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);

View file

@ -9,8 +9,8 @@ use hir_expand::AstId;
use ra_syntax::ast;
use crate::{
db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, ContainerId,
FunctionLoc, ImplId, Intern, LocationCtx, TypeAliasLoc,
db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstLoc, ContainerId,
FunctionLoc, ImplId, Intern, TypeAliasLoc,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@ -31,7 +31,6 @@ impl ImplData {
let negative = src.value.is_negative();
let items = if let Some(item_list) = src.value.item_list() {
let ctx = LocationCtx::new(db, id.module(db), src.file_id);
item_list
.impl_items()
.map(|item_node| match item_node {
@ -44,7 +43,12 @@ impl ImplData {
def.into()
}
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) => {
let def = TypeAliasLoc {

View file

@ -289,12 +289,23 @@ impl_arena_id!(LocalStructFieldId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConstId(salsa::InternId);
impl_intern_key!(ConstId);
impl AstItemDef<ast::ConstDef> for ConstId {
fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self {
db.intern_const(loc)
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ConstLoc {
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)
}
}
@ -498,6 +509,16 @@ impl HasModule for TypeAliasLoc {
}
}
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),
}
}
}
pub trait HasSource {
type Value;
fn source(&self, db: &impl db::DefDatabase2) -> Source<Self::Value>;
@ -520,3 +541,12 @@ impl HasSource for TypeAliasLoc {
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)
}
}

View file

@ -19,7 +19,7 @@ use crate::{
per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode,
},
path::{Path, PathKind},
AdtId, AstId, AstItemDef, ConstId, ContainerId, CrateModuleId, EnumId, EnumVariantId,
AdtId, AstId, AstItemDef, ConstLoc, ContainerId, CrateModuleId, EnumId, EnumVariantId,
FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId,
StructOrUnionId, TraitId, TypeAliasLoc, UnionId,
};
@ -692,7 +692,15 @@ where
PerNs::both(u, u)
}
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) => {
PerNs::values(StaticId::from_ast_id(ctx, ast_id).into())
}

View file

@ -8,11 +8,10 @@ use hir_expand::{
};
use ra_syntax::ast::{self, NameOwner};
use rustc_hash::FxHashMap;
use crate::{
db::DefDatabase2, AssocItemId, AstItemDef, ConstId, ContainerId, FunctionLoc, Intern,
LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasLoc,
db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId,
TypeAliasLoc,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@ -26,8 +25,6 @@ impl TraitData {
pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
let src = tr.source(db);
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 ast_id_map = db.ast_id_map(src.file_id);
let items = if let Some(item_list) = src.value.item_list() {
@ -40,7 +37,12 @@ impl TraitData {
}
.intern(db)
.into(),
ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).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)),
@ -55,34 +57,3 @@ impl TraitData {
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(_) => (),
AssocItemId::TypeAliasId(_) => (),
_ => {
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()
}
}

View file

@ -309,7 +309,6 @@ impl RootDatabase {
hir::db::StructDataQuery
hir::db::EnumDataQuery
hir::db::TraitDataQuery
hir::db::TraitItemsIndexQuery
hir::db::RawItemsWithSourceMapQuery
hir::db::RawItemsQuery
hir::db::CrateDefMapQuery

View file

@ -404,9 +404,7 @@ mod tests {
check_hover_result(
r#"
//- /main.rs
fn main() {
const foo<|>: u32 = 0;
}
"#,
&["const foo: u32"],
);
@ -414,9 +412,7 @@ mod tests {
check_hover_result(
r#"
//- /main.rs
fn main() {
static foo<|>: u32 = 0;
}
"#,
&["static foo: u32"],
);