This commit is contained in:
Lukas Wirth 2024-01-15 12:03:31 +01:00
parent 1669344b2a
commit 180e9b2bbf
17 changed files with 175 additions and 168 deletions

View file

@ -24,7 +24,7 @@ use triomphe::Arc;
use crate::{ use crate::{
db::DefDatabase, db::DefDatabase,
item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeNode}, item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeModItemNode},
lang_item::LangItem, lang_item::LangItem,
nameres::{ModuleOrigin, ModuleSource}, nameres::{ModuleOrigin, ModuleSource},
src::{HasChildSource, HasSource}, src::{HasChildSource, HasSource},
@ -82,7 +82,7 @@ impl Attrs {
let (fields, item_tree, krate) = match v { let (fields, item_tree, krate) = match v {
VariantId::EnumVariantId(it) => { VariantId::EnumVariantId(it) => {
let loc = it.lookup(db); let loc = it.lookup(db);
let krate = loc.container.krate; let krate = loc.parent.lookup(db).container.krate;
let item_tree = loc.id.item_tree(db); let item_tree = loc.id.item_tree(db);
let variant = &item_tree[loc.id.value]; let variant = &item_tree[loc.id.value];
(variant.fields.clone(), item_tree, krate) (variant.fields.clone(), item_tree, krate)
@ -606,13 +606,16 @@ fn any_has_attrs<'db>(
id.lookup(db).source(db).map(ast::AnyHasAttrs::new) id.lookup(db).source(db).map(ast::AnyHasAttrs::new)
} }
fn attrs_from_item_tree<N: ItemTreeNode>(db: &dyn DefDatabase, id: ItemTreeId<N>) -> RawAttrs { fn attrs_from_item_tree<N: ItemTreeModItemNode>(
db: &dyn DefDatabase,
id: ItemTreeId<N>,
) -> RawAttrs {
let tree = id.item_tree(db); let tree = id.item_tree(db);
let mod_item = N::id_to_mod_item(id.value); let mod_item = N::id_to_mod_item(id.value);
tree.raw_attrs(mod_item.into()).clone() tree.raw_attrs(mod_item.into()).clone()
} }
fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>( fn attrs_from_item_tree_loc<'db, N: ItemTreeModItemNode>(
db: &(dyn DefDatabase + 'db), db: &(dyn DefDatabase + 'db),
lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = ItemLoc<N>>, lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = ItemLoc<N>>,
) -> RawAttrs { ) -> RawAttrs {
@ -620,7 +623,7 @@ fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>(
attrs_from_item_tree(db, id) attrs_from_item_tree(db, id)
} }
fn attrs_from_item_tree_assoc<'db, N: ItemTreeNode>( fn attrs_from_item_tree_assoc<'db, N: ItemTreeModItemNode>(
db: &(dyn DefDatabase + 'db), db: &(dyn DefDatabase + 'db),
lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<N>>, lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<N>>,
) -> RawAttrs { ) -> RawAttrs {

View file

@ -18,7 +18,7 @@ use super::*;
pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String { pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String {
let header = match owner { let header = match owner {
DefWithBodyId::FunctionId(it) => { DefWithBodyId::FunctionId(it) => {
it.lookup(db).id.resolved(db, |it| format!("fn {} = ", it.name.display(db.upcast()))) it.lookup(db).id.resolved(db, |it| format!("fn {}", it.name.display(db.upcast())))
} }
DefWithBodyId::StaticId(it) => it DefWithBodyId::StaticId(it) => it
.lookup(db) .lookup(db)

View file

@ -334,7 +334,8 @@ impl EnumVariantData {
e: EnumVariantId, e: EnumVariantId,
) -> (Arc<EnumVariantData>, DefDiagnostics) { ) -> (Arc<EnumVariantData>, DefDiagnostics) {
let loc = e.lookup(db); let loc = e.lookup(db);
let krate = loc.container.krate; let container = loc.parent.lookup(db).container;
let krate = container.krate;
let item_tree = loc.id.item_tree(db); let item_tree = loc.id.item_tree(db);
let cfg_options = db.crate_graph()[krate].cfg_options.clone(); let cfg_options = db.crate_graph()[krate].cfg_options.clone();
let variant = &item_tree[loc.id.value]; let variant = &item_tree[loc.id.value];
@ -343,7 +344,7 @@ impl EnumVariantData {
db, db,
krate, krate,
loc.id.file_id(), loc.id.file_id(),
loc.container.local_id, container.local_id,
&item_tree, &item_tree,
&cfg_options, &cfg_options,
&variant.fields, &variant.fields,
@ -395,7 +396,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
( (
lookup.source(db).map(|it| it.kind()), lookup.source(db).map(|it| it.kind()),
&item_tree[lookup.id.value].fields, &item_tree[lookup.id.value].fields,
lookup.container, lookup.parent.lookup(db).container,
) )
} }
VariantId::StructId(it) => { VariantId::StructId(it) => {
@ -411,11 +412,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
let lookup = it.lookup(db); let lookup = it.lookup(db);
item_tree = lookup.id.item_tree(db); item_tree = lookup.id.item_tree(db);
( (
lookup.source(db).map(|it| { lookup.source(db).map(|it| it.kind()),
it.record_field_list()
.map(ast::StructKind::Record)
.unwrap_or(ast::StructKind::Unit)
}),
&item_tree[lookup.id.value].fields, &item_tree[lookup.id.value].fields,
lookup.container, lookup.container,
) )

View file

@ -337,7 +337,7 @@ from_attrs!(
); );
/// Trait implemented by all item nodes in the item tree. /// Trait implemented by all item nodes in the item tree.
pub trait ItemTreeNode: Clone { pub trait ItemTreeModItemNode: Clone {
type Source: AstIdNode + Into<ast::Item>; type Source: AstIdNode + Into<ast::Item>;
fn ast_id(&self) -> FileAstId<Self::Source>; fn ast_id(&self) -> FileAstId<Self::Source>;
@ -494,7 +494,7 @@ macro_rules! mod_items {
)+ )+
$( $(
impl ItemTreeNode for $typ { impl ItemTreeModItemNode for $typ {
type Source = $ast; type Source = $ast;
fn ast_id(&self) -> FileAstId<Self::Source> { fn ast_id(&self) -> FileAstId<Self::Source> {
@ -577,7 +577,7 @@ impl Index<RawVisibilityId> for ItemTree {
} }
} }
impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { impl<N: ItemTreeModItemNode> Index<FileItemTreeId<N>> for ItemTree {
type Output = N; type Output = N;
fn index(&self, id: FileItemTreeId<N>) -> &N { fn index(&self, id: FileItemTreeId<N>) -> &N {
N::lookup(self, id.index()) N::lookup(self, id.index())

View file

@ -13,7 +13,7 @@ use crate::{
use super::*; use super::*;
fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> { fn id<N: ItemTreeModItemNode>(index: Idx<N>) -> FileItemTreeId<N> {
FileItemTreeId(index) FileItemTreeId(index)
} }

View file

@ -99,8 +99,8 @@ use crate::{
data::adt::VariantData, data::adt::VariantData,
db::DefDatabase, db::DefDatabase,
item_tree::{ item_tree::{
Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules, Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeModItemNode, Macro2,
Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant, MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant,
}, },
}; };
@ -213,28 +213,28 @@ impl ModuleId {
pub type LocalModuleId = Idx<nameres::ModuleData>; pub type LocalModuleId = Idx<nameres::ModuleData>;
#[derive(Debug)] #[derive(Debug)]
pub struct ItemLoc<N: ItemTreeNode> { pub struct ItemLoc<N: ItemTreeModItemNode> {
pub container: ModuleId, pub container: ModuleId,
pub id: ItemTreeId<N>, pub id: ItemTreeId<N>,
} }
impl<N: ItemTreeNode> Clone for ItemLoc<N> { impl<N: ItemTreeModItemNode> Clone for ItemLoc<N> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { container: self.container, id: self.id } Self { container: self.container, id: self.id }
} }
} }
impl<N: ItemTreeNode> Copy for ItemLoc<N> {} impl<N: ItemTreeModItemNode> Copy for ItemLoc<N> {}
impl<N: ItemTreeNode> PartialEq for ItemLoc<N> { impl<N: ItemTreeModItemNode> PartialEq for ItemLoc<N> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.container == other.container && self.id == other.id self.container == other.container && self.id == other.id
} }
} }
impl<N: ItemTreeNode> Eq for ItemLoc<N> {} impl<N: ItemTreeModItemNode> Eq for ItemLoc<N> {}
impl<N: ItemTreeNode> Hash for ItemLoc<N> { impl<N: ItemTreeModItemNode> Hash for ItemLoc<N> {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.container.hash(state); self.container.hash(state);
self.id.hash(state); self.id.hash(state);
@ -242,28 +242,28 @@ impl<N: ItemTreeNode> Hash for ItemLoc<N> {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct AssocItemLoc<N: ItemTreeNode> { pub struct AssocItemLoc<N: ItemTreeModItemNode> {
pub container: ItemContainerId, pub container: ItemContainerId,
pub id: ItemTreeId<N>, pub id: ItemTreeId<N>,
} }
impl<N: ItemTreeNode> Clone for AssocItemLoc<N> { impl<N: ItemTreeModItemNode> Clone for AssocItemLoc<N> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { container: self.container, id: self.id } Self { container: self.container, id: self.id }
} }
} }
impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {} impl<N: ItemTreeModItemNode> Copy for AssocItemLoc<N> {}
impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> { impl<N: ItemTreeModItemNode> PartialEq for AssocItemLoc<N> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.container == other.container && self.id == other.id self.container == other.container && self.id == other.id
} }
} }
impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {} impl<N: ItemTreeModItemNode> Eq for AssocItemLoc<N> {}
impl<N: ItemTreeNode> Hash for AssocItemLoc<N> { impl<N: ItemTreeModItemNode> Hash for AssocItemLoc<N> {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.container.hash(state); self.container.hash(state);
self.id.hash(state); self.id.hash(state);
@ -297,15 +297,14 @@ pub struct EnumId(salsa::InternId);
pub type EnumLoc = ItemLoc<Enum>; pub type EnumLoc = ItemLoc<Enum>;
impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
// FIXME: rename to `VariantId`, only enums can ave variants
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EnumVariantId(salsa::InternId); pub struct EnumVariantId(salsa::InternId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EnumVariantLoc { pub struct EnumVariantLoc {
pub container: ModuleId,
pub id: ItemTreeId<Variant>, pub id: ItemTreeId<Variant>,
pub parent: EnumId, pub parent: EnumId,
pub index: u32,
} }
impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant); impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
@ -992,7 +991,8 @@ impl HasModule for ItemContainerId {
} }
} }
impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> { impl<N: ItemTreeModItemNode> HasModule for AssocItemLoc<N> {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId { fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.container.module(db) self.container.module(db)
} }
@ -1008,7 +1008,22 @@ impl HasModule for AdtId {
} }
} }
impl HasModule for EnumId {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.lookup(db).container
}
}
impl HasModule for EnumVariantId {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.lookup(db).parent.module(db)
}
}
impl HasModule for ExternCrateId { impl HasModule for ExternCrateId {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId { fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.lookup(db).container self.lookup(db).container
} }
@ -1017,7 +1032,7 @@ impl HasModule for ExternCrateId {
impl HasModule for VariantId { impl HasModule for VariantId {
fn module(&self, db: &dyn DefDatabase) -> ModuleId { fn module(&self, db: &dyn DefDatabase) -> ModuleId {
match self { match self {
VariantId::EnumVariantId(it) => it.lookup(db).container, VariantId::EnumVariantId(it) => it.lookup(db).parent.module(db),
VariantId::StructId(it) => it.lookup(db).container, VariantId::StructId(it) => it.lookup(db).container,
VariantId::UnionId(it) => it.lookup(db).container, VariantId::UnionId(it) => it.lookup(db).container,
} }
@ -1046,7 +1061,7 @@ impl HasModule for TypeOwnerId {
TypeOwnerId::TraitAliasId(it) => it.lookup(db).container, TypeOwnerId::TraitAliasId(it) => it.lookup(db).container,
TypeOwnerId::TypeAliasId(it) => it.lookup(db).module(db), TypeOwnerId::TypeAliasId(it) => it.lookup(db).module(db),
TypeOwnerId::ImplId(it) => it.lookup(db).container, TypeOwnerId::ImplId(it) => it.lookup(db).container,
TypeOwnerId::EnumVariantId(it) => it.lookup(db).container, TypeOwnerId::EnumVariantId(it) => it.lookup(db).parent.module(db),
} }
} }
} }
@ -1057,7 +1072,7 @@ impl HasModule for DefWithBodyId {
DefWithBodyId::FunctionId(it) => it.lookup(db).module(db), DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
DefWithBodyId::StaticId(it) => it.lookup(db).module(db), DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
DefWithBodyId::ConstId(it) => it.lookup(db).module(db), DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
DefWithBodyId::VariantId(it) => it.lookup(db).container, DefWithBodyId::VariantId(it) => it.lookup(db).parent.module(db),
DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db), DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
} }
} }
@ -1072,19 +1087,21 @@ impl HasModule for GenericDefId {
GenericDefId::TraitAliasId(it) => it.lookup(db).container, GenericDefId::TraitAliasId(it) => it.lookup(db).container,
GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
GenericDefId::ImplId(it) => it.lookup(db).container, GenericDefId::ImplId(it) => it.lookup(db).container,
GenericDefId::EnumVariantId(it) => it.lookup(db).container, GenericDefId::EnumVariantId(it) => it.lookup(db).parent.lookup(db).container,
GenericDefId::ConstId(it) => it.lookup(db).module(db), GenericDefId::ConstId(it) => it.lookup(db).module(db),
} }
} }
} }
impl HasModule for TypeAliasId { impl HasModule for TypeAliasId {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId { fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.lookup(db).module(db) self.lookup(db).module(db)
} }
} }
impl HasModule for TraitId { impl HasModule for TraitId {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId { fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.lookup(db).container self.lookup(db).container
} }
@ -1099,7 +1116,7 @@ impl ModuleDefId {
ModuleDefId::ModuleId(id) => *id, ModuleDefId::ModuleId(id) => *id,
ModuleDefId::FunctionId(id) => id.lookup(db).module(db), ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
ModuleDefId::AdtId(id) => id.module(db), ModuleDefId::AdtId(id) => id.module(db),
ModuleDefId::EnumVariantId(id) => id.lookup(db).container, ModuleDefId::EnumVariantId(id) => id.lookup(db).parent.module(db),
ModuleDefId::ConstId(id) => id.lookup(db).container.module(db), ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
ModuleDefId::StaticId(id) => id.lookup(db).module(db), ModuleDefId::StaticId(id) => id.lookup(db).module(db),
ModuleDefId::TraitId(id) => id.lookup(db).container, ModuleDefId::TraitId(id) => id.lookup(db).container,
@ -1118,7 +1135,7 @@ impl AttrDefId {
AttrDefId::FieldId(it) => it.parent.module(db).krate, AttrDefId::FieldId(it) => it.parent.module(db).krate,
AttrDefId::AdtId(it) => it.module(db).krate, AttrDefId::AdtId(it) => it.module(db).krate,
AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate, AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
AttrDefId::EnumVariantId(it) => it.lookup(db).container.krate, AttrDefId::EnumVariantId(it) => it.lookup(db).parent.module(db).krate,
AttrDefId::StaticId(it) => it.lookup(db).module(db).krate, AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
AttrDefId::ConstId(it) => it.lookup(db).module(db).krate, AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
AttrDefId::TraitId(it) => it.lookup(db).container.krate, AttrDefId::TraitId(it) => it.lookup(db).container.krate,

View file

@ -3,7 +3,7 @@
//! `DefCollector::collect` contains the fixed-point iteration loop which //! `DefCollector::collect` contains the fixed-point iteration loop which
//! resolves imports and expands macros. //! resolves imports and expands macros.
use std::{cmp::Ordering, iter, mem}; use std::{cmp::Ordering, iter, mem, ops::Not};
use base_db::{CrateId, Dependency, Edition, FileId}; use base_db::{CrateId, Dependency, Edition, FileId};
use cfg::{CfgExpr, CfgOptions}; use cfg::{CfgExpr, CfgOptions};
@ -35,8 +35,8 @@ use crate::{
derive_macro_as_call_id, derive_macro_as_call_id,
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports}, item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
item_tree::{ item_tree::{
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId,
Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, ItemTreeModItemNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
}, },
macro_call_as_call_id, macro_call_as_call_id_with_eager, macro_call_as_call_id, macro_call_as_call_id_with_eager,
nameres::{ nameres::{
@ -1579,7 +1579,10 @@ impl ModCollector<'_, '_> {
let attrs = self.item_tree.attrs(db, krate, item.into()); let attrs = self.item_tree.attrs(db, krate, item.into());
if let Some(cfg) = attrs.cfg() { if let Some(cfg) = attrs.cfg() {
if !self.is_cfg_enabled(&cfg) { if !self.is_cfg_enabled(&cfg) {
self.emit_unconfigured_diagnostic(item.ast_id(self.item_tree).erase(), &cfg); self.emit_unconfigured_diagnostic(
InFile::new(self.file_id(), item.ast_id(self.item_tree).erase()),
&cfg,
);
return; return;
} }
} }
@ -1717,27 +1720,37 @@ impl ModCollector<'_, '_> {
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
update_def(self.def_collector, enum_.into(), &it.name, vis, false); update_def(self.def_collector, enum_.into(), &it.name, vis, false);
let mut index = 0;
let variants = FileItemTreeId::range_iter(it.variants.clone()) let variants = FileItemTreeId::range_iter(it.variants.clone())
.filter_map(|variant| { .filter_map(|variant| {
let attrs = self.item_tree.attrs(db, krate, variant.into()); let is_enabled = self
if let Some(cfg) = attrs.cfg() { .item_tree
if !self.is_cfg_enabled(&cfg) { .attrs(db, krate, variant.into())
.cfg()
.and_then(|cfg| self.is_cfg_enabled(&cfg).not().then_some(cfg))
.map_or(Ok(()), Err);
match is_enabled {
Err(cfg) => {
self.emit_unconfigured_diagnostic( self.emit_unconfigured_diagnostic(
self.item_tree[variant.index()].ast_id.erase(), InFile::new(
self.file_id(),
self.item_tree[variant.index()].ast_id.erase(),
),
&cfg, &cfg,
); );
return None; None
} }
Ok(()) => Some({
let loc = EnumVariantLoc {
id: ItemTreeId::new(self.tree_id, variant),
parent: enum_,
index,
}
.intern(db);
index += 1;
loc
}),
} }
Some(
EnumVariantLoc {
container: module,
id: ItemTreeId::new(self.tree_id, variant),
parent: enum_,
}
.intern(db),
)
}) })
.collect(); .collect();
self.def_collector.def_map.enum_definitions.insert(enum_, variants); self.def_collector.def_map.enum_definitions.insert(enum_, variants);
@ -1927,31 +1940,40 @@ impl ModCollector<'_, '_> {
let is_enabled = item_tree let is_enabled = item_tree
.top_level_attrs(db, krate) .top_level_attrs(db, krate)
.cfg() .cfg()
.map_or(true, |cfg| self.is_cfg_enabled(&cfg)); .and_then(|cfg| self.is_cfg_enabled(&cfg).not().then_some(cfg))
if is_enabled { .map_or(Ok(()), Err);
let module_id = self.push_child_module( match is_enabled {
module.name.clone(), Err(cfg) => {
ast_id.value, self.emit_unconfigured_diagnostic(
Some((file_id, is_mod_rs)), ast_id.map(|it| it.erase()),
&self.item_tree[module.visibility], &cfg,
module_id, );
);
ModCollector {
def_collector: self.def_collector,
macro_depth: self.macro_depth,
module_id,
tree_id: TreeId::new(file_id.into(), None),
item_tree: &item_tree,
mod_dir,
} }
.collect_in_top_module(item_tree.top_level_items()); Ok(()) => {
let is_macro_use = is_macro_use let module_id = self.push_child_module(
|| item_tree module.name.clone(),
.top_level_attrs(db, krate) ast_id.value,
.by_key("macro_use") Some((file_id, is_mod_rs)),
.exists(); &self.item_tree[module.visibility],
if is_macro_use { module_id,
self.import_all_legacy_macros(module_id); );
ModCollector {
def_collector: self.def_collector,
macro_depth: self.macro_depth,
module_id,
tree_id: TreeId::new(file_id.into(), None),
item_tree: &item_tree,
mod_dir,
}
.collect_in_top_module(item_tree.top_level_items());
let is_macro_use = is_macro_use
|| item_tree
.top_level_attrs(db, krate)
.by_key("macro_use")
.exists();
if is_macro_use {
self.import_all_legacy_macros(module_id);
}
} }
} }
} }
@ -2382,8 +2404,7 @@ impl ModCollector<'_, '_> {
self.def_collector.cfg_options.check(cfg) != Some(false) self.def_collector.cfg_options.check(cfg) != Some(false)
} }
fn emit_unconfigured_diagnostic(&mut self, ast_id: ErasedFileAstId, cfg: &CfgExpr) { fn emit_unconfigured_diagnostic(&mut self, ast_id: InFile<ErasedFileAstId>, cfg: &CfgExpr) {
let ast_id = InFile::new(self.file_id(), ast_id);
self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code( self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
self.module_id, self.module_id,
ast_id, ast_id,

View file

@ -355,12 +355,12 @@ impl DefMap {
ModuleDefId::AdtId(AdtId::EnumId(e)) => { ModuleDefId::AdtId(AdtId::EnumId(e)) => {
// enum variant // enum variant
cov_mark::hit!(can_import_enum_variant); cov_mark::hit!(can_import_enum_variant);
let def_map;
let loc = e.lookup(db); let loc = e.lookup(db);
let tree = loc.id.item_tree(db); let tree = loc.id.item_tree(db);
let current_def_map = let current_def_map =
self.krate == loc.container.krate && self.block_id() == loc.container.block; self.krate == loc.container.krate && self.block_id() == loc.container.block;
let def_map;
let res = if current_def_map { let res = if current_def_map {
&self.enum_definitions[&e] &self.enum_definitions[&e]
} else { } else {

View file

@ -5,7 +5,7 @@ use la_arena::ArenaMap;
use syntax::ast; use syntax::ast;
use crate::{ use crate::{
db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup, db::DefDatabase, item_tree::ItemTreeModItemNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup,
Macro2Loc, MacroRulesLoc, ProcMacroLoc, UseId, Macro2Loc, MacroRulesLoc, ProcMacroLoc, UseId,
}; };
@ -14,7 +14,7 @@ pub trait HasSource {
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value>; fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value>;
} }
impl<N: ItemTreeNode> HasSource for AssocItemLoc<N> { impl<N: ItemTreeModItemNode> HasSource for AssocItemLoc<N> {
type Value = N::Source; type Value = N::Source;
fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> { fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
@ -27,7 +27,7 @@ impl<N: ItemTreeNode> HasSource for AssocItemLoc<N> {
} }
} }
impl<N: ItemTreeNode> HasSource for ItemLoc<N> { impl<N: ItemTreeModItemNode> HasSource for ItemLoc<N> {
type Value = N::Source; type Value = N::Source;
fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> { fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {

View file

@ -19,6 +19,10 @@ pub(crate) struct Trace<T, V> {
impl<T, V> Trace<T, V> { impl<T, V> Trace<T, V> {
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn new_for_arena() -> Trace<T, V> {
Trace { arena: Some(Arena::default()), map: None, len: 0 }
}
pub(crate) fn new_for_map() -> Trace<T, V> { pub(crate) fn new_for_map() -> Trace<T, V> {
Trace { arena: None, map: Some(ArenaMap::default()), len: 0 } Trace { arena: None, map: Some(ArenaMap::default()), len: 0 }
} }

View file

@ -222,11 +222,7 @@ pub(crate) fn field_visibilities_query(
db: &dyn DefDatabase, db: &dyn DefDatabase,
variant_id: VariantId, variant_id: VariantId,
) -> Arc<ArenaMap<LocalFieldId, Visibility>> { ) -> Arc<ArenaMap<LocalFieldId, Visibility>> {
let var_data = match variant_id { let var_data = variant_id.variant_data(db);
VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
VariantId::EnumVariantId(it) => db.enum_variant_data(it).variant_data.clone(),
};
let resolver = variant_id.module(db).resolver(db); let resolver = variant_id.module(db).resolver(db);
let mut res = ArenaMap::default(); let mut res = ArenaMap::default();
for (field_id, field_data) in var_data.fields().iter() { for (field_id, field_data) in var_data.fields().iter() {

View file

@ -257,15 +257,7 @@ pub(crate) fn const_eval_discriminant_variant(
let body = db.body(def); let body = db.body(def);
if body.exprs[body.body_expr] == Expr::Missing { if body.exprs[body.body_expr] == Expr::Missing {
let loc = variant_id.lookup(db.upcast()); let loc = variant_id.lookup(db.upcast());
let parent_id = loc.parent.lookup(db.upcast()).id; let prev_idx = loc.index.checked_sub(1);
let index = loc.id.value.index().into_raw().into_u32()
- parent_id.item_tree(db.upcast())[parent_id.value]
.variants
.start
.index()
.into_raw()
.into_u32();
let prev_idx = index.checked_sub(1);
let value = match prev_idx { let value = match prev_idx {
Some(prev_idx) => { Some(prev_idx) => {
1 + db.const_eval_discriminant( 1 + db.const_eval_discriminant(

View file

@ -7,7 +7,7 @@ use chalk_ir::{
}; };
use hir_def::{ use hir_def::{
attr::Attrs, data::adt::VariantData, visibility::Visibility, AdtId, EnumVariantId, HasModule, attr::Attrs, data::adt::VariantData, visibility::Visibility, AdtId, EnumVariantId, HasModule,
Lookup, ModuleId, VariantId, ModuleId, VariantId,
}; };
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
@ -30,7 +30,7 @@ pub(crate) fn is_enum_variant_uninhabited_from(
target_mod: ModuleId, target_mod: ModuleId,
db: &dyn HirDatabase, db: &dyn HirDatabase,
) -> bool { ) -> bool {
let is_local = variant.lookup(db.upcast()).container.krate() == target_mod.krate(); let is_local = variant.module(db.upcast()).krate() == target_mod.krate();
let mut uninhabited_from = let mut uninhabited_from =
UninhabitedFrom { target_mod, db, max_depth: 500, recursive_ty: FxHashSet::default() }; UninhabitedFrom { target_mod, db, max_depth: 500, recursive_ty: FxHashSet::default() };

View file

@ -1729,16 +1729,19 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
/// Build the type of a tuple struct constructor. /// Build the type of a tuple struct constructor.
fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> { fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
let struct_data = db.struct_data(def); let struct_data = db.struct_data(def);
if let StructKind::Unit = struct_data.variant_data.kind() { match struct_data.variant_data.kind() {
return type_for_adt(db, def.into()); StructKind::Record => unreachable!("callers check for valueness of variant"),
StructKind::Unit => return type_for_adt(db, def.into()),
StructKind::Tuple => {
let generics = generics(db.upcast(), AdtId::from(def).into());
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
make_binders(
db,
&generics,
TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
)
}
} }
let generics = generics(db.upcast(), AdtId::from(def).into());
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
make_binders(
db,
&generics,
TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
)
} }
fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@ -1756,16 +1759,20 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
/// Build the type of a tuple enum variant constructor. /// Build the type of a tuple enum variant constructor.
fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> { fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
let e = def.lookup(db.upcast()).parent; let e = def.lookup(db.upcast()).parent;
if let StructKind::Unit = db.enum_variant_data(def).variant_data.kind() { match db.enum_variant_data(def).variant_data.kind() {
return type_for_adt(db, e.into()); StructKind::Record => unreachable!("callers check for valueness of variant"),
StructKind::Unit => return type_for_adt(db, e.into()),
StructKind::Tuple => {
let generics = generics(db.upcast(), e.into());
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
make_binders(
db,
&generics,
TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs)
.intern(Interner),
)
}
} }
let generics = generics(db.upcast(), e.into());
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
make_binders(
db,
&generics,
TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
)
} }
fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
@ -1813,7 +1820,7 @@ impl CallableDefId {
match self { match self {
CallableDefId::FunctionId(f) => f.lookup(db).module(db), CallableDefId::FunctionId(f) => f.lookup(db).module(db),
CallableDefId::StructId(s) => s.lookup(db).container, CallableDefId::StructId(s) => s.lookup(db).container,
CallableDefId::EnumVariantId(e) => e.lookup(db).container, CallableDefId::EnumVariantId(e) => e.module(db),
} }
.krate() .krate()
} }
@ -1894,12 +1901,8 @@ pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders
} }
pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> { pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
let impl_loc = impl_id.lookup(db.upcast());
let impl_data = db.impl_data(impl_id); let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db.upcast()); let resolver = impl_id.resolver(db.upcast());
let _cx = stdx::panic_context::enter(format!(
"impl_self_ty_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
));
let generics = generics(db.upcast(), impl_id.into()); let generics = generics(db.upcast(), impl_id.into());
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into()) let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
.with_type_param_mode(ParamLoweringMode::Variable); .with_type_param_mode(ParamLoweringMode::Variable);
@ -1931,12 +1934,8 @@ pub(crate) fn impl_self_ty_recover(
} }
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
let impl_loc = impl_id.lookup(db.upcast());
let impl_data = db.impl_data(impl_id); let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db.upcast()); let resolver = impl_id.resolver(db.upcast());
let _cx = stdx::panic_context::enter(format!(
"impl_trait_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
));
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into()) let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
.with_type_param_mode(ParamLoweringMode::Variable); .with_type_param_mode(ParamLoweringMode::Variable);
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders(); let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();

View file

@ -751,19 +751,9 @@ impl Evaluator<'_> {
Variants::Single { .. } => &layout, Variants::Single { .. } => &layout,
Variants::Multiple { variants, .. } => { Variants::Multiple { variants, .. } => {
&variants[match f.parent { &variants[match f.parent {
hir_def::VariantId::EnumVariantId(it) => RustcEnumVariantIdx({ hir_def::VariantId::EnumVariantId(it) => {
let lookup = it.lookup(self.db.upcast()); RustcEnumVariantIdx(it.lookup(self.db.upcast()).index as usize)
let rustc_enum_variant_idx = }
lookup.id.value.index().into_raw().into_u32()
- lookup.id.item_tree(self.db.upcast())
[lookup.parent.lookup(self.db.upcast()).id.value]
.variants
.start
.index()
.into_raw()
.into_u32();
rustc_enum_variant_idx as usize
}),
_ => { _ => {
return Err(MirEvalError::TypeError( return Err(MirEvalError::TypeError(
"Multivariant layout only happens for enums", "Multivariant layout only happens for enums",
@ -1604,15 +1594,7 @@ impl Evaluator<'_> {
}; };
let mut discriminant = self.const_eval_discriminant(enum_variant_id)?; let mut discriminant = self.const_eval_discriminant(enum_variant_id)?;
let lookup = enum_variant_id.lookup(self.db.upcast()); let lookup = enum_variant_id.lookup(self.db.upcast());
let rustc_enum_variant_idx = lookup.id.value.index().into_raw().into_u32() let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize);
- lookup.id.item_tree(self.db.upcast())
[lookup.parent.lookup(self.db.upcast()).id.value]
.variants
.start
.index()
.into_raw()
.into_u32();
let rustc_enum_variant_idx = RustcEnumVariantIdx(rustc_enum_variant_idx as usize);
let variant_layout = variants[rustc_enum_variant_idx].clone(); let variant_layout = variants[rustc_enum_variant_idx].clone();
let have_tag = match tag_encoding { let have_tag = match tag_encoding {
TagEncoding::Direct => true, TagEncoding::Direct => true,

View file

@ -44,7 +44,7 @@ use hir_def::{
data::adt::VariantData, data::adt::VariantData,
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat}, hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat},
item_tree::ItemTreeNode, item_tree::ItemTreeModItemNode,
lang_item::LangItemTarget, lang_item::LangItemTarget,
layout::{self, ReprOptions, TargetDataLayout}, layout::{self, ReprOptions, TargetDataLayout},
nameres::{self, diagnostics::DefDiagnostic}, nameres::{self, diagnostics::DefDiagnostic},
@ -1294,7 +1294,7 @@ pub struct Variant {
impl Variant { impl Variant {
pub fn module(self, db: &dyn HirDatabase) -> Module { pub fn module(self, db: &dyn HirDatabase) -> Module {
Module { id: self.id.lookup(db.upcast()).container } Module { id: self.id.module(db.upcast()) }
} }
pub fn parent_enum(self, db: &dyn HirDatabase) -> Enum { pub fn parent_enum(self, db: &dyn HirDatabase) -> Enum {
@ -1340,17 +1340,7 @@ impl Variant {
layout::Variants::Multiple { variants, .. } => Layout( layout::Variants::Multiple { variants, .. } => Layout(
{ {
let lookup = self.id.lookup(db.upcast()); let lookup = self.id.lookup(db.upcast());
let rustc_enum_variant_idx = lookup.id.value.index().into_raw().into_u32() let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize);
- lookup.id.item_tree(db.upcast())
[lookup.parent.lookup(db.upcast()).id.value]
.variants
.start
.index()
.into_raw()
.into_u32();
let rustc_enum_variant_idx =
RustcEnumVariantIdx(rustc_enum_variant_idx as usize);
Arc::new(variants[rustc_enum_variant_idx].clone()) Arc::new(variants[rustc_enum_variant_idx].clone())
}, },
db.target_data_layout(parent_enum.krate(db).into()).unwrap(), db.target_data_layout(parent_enum.krate(db).into()).unwrap(),
@ -2838,7 +2828,7 @@ where
ID: Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<AST>>, ID: Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<AST>>,
DEF: From<ID>, DEF: From<ID>,
CTOR: FnOnce(DEF) -> AssocItem, CTOR: FnOnce(DEF) -> AssocItem,
AST: ItemTreeNode, AST: ItemTreeModItemNode,
{ {
match id.lookup(db.upcast()).container { match id.lookup(db.upcast()).container {
ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))), ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))),

View file

@ -440,6 +440,12 @@ impl ast::Struct {
} }
} }
impl ast::Union {
pub fn kind(&self) -> StructKind {
StructKind::from_node(self)
}
}
impl ast::RecordExprField { impl ast::RecordExprField {
pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> { pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> {
let candidate = Self::for_name_ref(field_name)?; let candidate = Self::for_name_ref(field_name)?;