diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index be69d6f1351..8fbfcc81d28 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -24,7 +24,7 @@ use triomphe::Arc; use crate::{ db::DefDatabase, - item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeNode}, + item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeModItemNode}, lang_item::LangItem, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource}, @@ -82,7 +82,7 @@ impl Attrs { let (fields, item_tree, krate) = match v { VariantId::EnumVariantId(it) => { 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 variant = &item_tree[loc.id.value]; (variant.fields.clone(), item_tree, krate) @@ -606,13 +606,16 @@ fn any_has_attrs<'db>( id.lookup(db).source(db).map(ast::AnyHasAttrs::new) } -fn attrs_from_item_tree(db: &dyn DefDatabase, id: ItemTreeId) -> RawAttrs { +fn attrs_from_item_tree( + db: &dyn DefDatabase, + id: ItemTreeId, +) -> RawAttrs { let tree = id.item_tree(db); let mod_item = N::id_to_mod_item(id.value); 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), lookup: impl Lookup = dyn DefDatabase + 'db, Data = ItemLoc>, ) -> RawAttrs { @@ -620,7 +623,7 @@ fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>( 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), lookup: impl Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, ) -> RawAttrs { diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs index a389a283b59..deb87f87d5e 100644 --- a/crates/hir-def/src/body/pretty.rs +++ b/crates/hir-def/src/body/pretty.rs @@ -18,7 +18,7 @@ use super::*; pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String { let header = match owner { 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 .lookup(db) diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs index 6e302aea653..5d443715213 100644 --- a/crates/hir-def/src/data/adt.rs +++ b/crates/hir-def/src/data/adt.rs @@ -334,7 +334,8 @@ impl EnumVariantData { e: EnumVariantId, ) -> (Arc, DefDiagnostics) { 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 cfg_options = db.crate_graph()[krate].cfg_options.clone(); let variant = &item_tree[loc.id.value]; @@ -343,7 +344,7 @@ impl EnumVariantData { db, krate, loc.id.file_id(), - loc.container.local_id, + container.local_id, &item_tree, &cfg_options, &variant.fields, @@ -395,7 +396,7 @@ impl HasChildSource for VariantId { ( lookup.source(db).map(|it| it.kind()), &item_tree[lookup.id.value].fields, - lookup.container, + lookup.parent.lookup(db).container, ) } VariantId::StructId(it) => { @@ -411,11 +412,7 @@ impl HasChildSource for VariantId { let lookup = it.lookup(db); item_tree = lookup.id.item_tree(db); ( - lookup.source(db).map(|it| { - it.record_field_list() - .map(ast::StructKind::Record) - .unwrap_or(ast::StructKind::Unit) - }), + lookup.source(db).map(|it| it.kind()), &item_tree[lookup.id.value].fields, lookup.container, ) diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 173aa817b0d..c37cf521551 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -337,7 +337,7 @@ from_attrs!( ); /// Trait implemented by all item nodes in the item tree. -pub trait ItemTreeNode: Clone { +pub trait ItemTreeModItemNode: Clone { type Source: AstIdNode + Into; fn ast_id(&self) -> FileAstId; @@ -494,7 +494,7 @@ macro_rules! mod_items { )+ $( - impl ItemTreeNode for $typ { + impl ItemTreeModItemNode for $typ { type Source = $ast; fn ast_id(&self) -> FileAstId { @@ -577,7 +577,7 @@ impl Index for ItemTree { } } -impl Index> for ItemTree { +impl Index> for ItemTree { type Output = N; fn index(&self, id: FileItemTreeId) -> &N { N::lookup(self, id.index()) diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 8d19b5000cf..f6086ed6d9b 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -13,7 +13,7 @@ use crate::{ use super::*; -fn id(index: Idx) -> FileItemTreeId { +fn id(index: Idx) -> FileItemTreeId { FileItemTreeId(index) } diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 1712eaede09..bcd1f37bec4 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -99,8 +99,8 @@ use crate::{ data::adt::VariantData, db::DefDatabase, item_tree::{ - Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules, - Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant, + Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeModItemNode, Macro2, + MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant, }, }; @@ -213,28 +213,28 @@ impl ModuleId { pub type LocalModuleId = Idx; #[derive(Debug)] -pub struct ItemLoc { +pub struct ItemLoc { pub container: ModuleId, pub id: ItemTreeId, } -impl Clone for ItemLoc { +impl Clone for ItemLoc { fn clone(&self) -> Self { Self { container: self.container, id: self.id } } } -impl Copy for ItemLoc {} +impl Copy for ItemLoc {} -impl PartialEq for ItemLoc { +impl PartialEq for ItemLoc { fn eq(&self, other: &Self) -> bool { self.container == other.container && self.id == other.id } } -impl Eq for ItemLoc {} +impl Eq for ItemLoc {} -impl Hash for ItemLoc { +impl Hash for ItemLoc { fn hash(&self, state: &mut H) { self.container.hash(state); self.id.hash(state); @@ -242,28 +242,28 @@ impl Hash for ItemLoc { } #[derive(Debug)] -pub struct AssocItemLoc { +pub struct AssocItemLoc { pub container: ItemContainerId, pub id: ItemTreeId, } -impl Clone for AssocItemLoc { +impl Clone for AssocItemLoc { fn clone(&self) -> Self { Self { container: self.container, id: self.id } } } -impl Copy for AssocItemLoc {} +impl Copy for AssocItemLoc {} -impl PartialEq for AssocItemLoc { +impl PartialEq for AssocItemLoc { fn eq(&self, other: &Self) -> bool { self.container == other.container && self.id == other.id } } -impl Eq for AssocItemLoc {} +impl Eq for AssocItemLoc {} -impl Hash for AssocItemLoc { +impl Hash for AssocItemLoc { fn hash(&self, state: &mut H) { self.container.hash(state); self.id.hash(state); @@ -297,15 +297,14 @@ pub struct EnumId(salsa::InternId); pub type EnumLoc = ItemLoc; 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)] pub struct EnumVariantId(salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EnumVariantLoc { - pub container: ModuleId, pub id: ItemTreeId, pub parent: EnumId, + pub index: u32, } impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant); @@ -992,7 +991,8 @@ impl HasModule for ItemContainerId { } } -impl HasModule for AssocItemLoc { +impl HasModule for AssocItemLoc { + #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { 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 { + #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { self.lookup(db).container } @@ -1017,7 +1032,7 @@ impl HasModule for ExternCrateId { impl HasModule for VariantId { fn module(&self, db: &dyn DefDatabase) -> ModuleId { 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::UnionId(it) => it.lookup(db).container, } @@ -1046,7 +1061,7 @@ impl HasModule for TypeOwnerId { TypeOwnerId::TraitAliasId(it) => it.lookup(db).container, TypeOwnerId::TypeAliasId(it) => it.lookup(db).module(db), 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::StaticId(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), } } @@ -1072,19 +1087,21 @@ impl HasModule for GenericDefId { GenericDefId::TraitAliasId(it) => it.lookup(db).container, GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 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), } } } impl HasModule for TypeAliasId { + #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { self.lookup(db).module(db) } } impl HasModule for TraitId { + #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { self.lookup(db).container } @@ -1099,7 +1116,7 @@ impl ModuleDefId { ModuleDefId::ModuleId(id) => *id, ModuleDefId::FunctionId(id) => id.lookup(db).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::StaticId(id) => id.lookup(db).module(db), ModuleDefId::TraitId(id) => id.lookup(db).container, @@ -1118,7 +1135,7 @@ impl AttrDefId { AttrDefId::FieldId(it) => it.parent.module(db).krate, AttrDefId::AdtId(it) => it.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::ConstId(it) => it.lookup(db).module(db).krate, AttrDefId::TraitId(it) => it.lookup(db).container.krate, diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 760f811ede6..893ad47e241 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -3,7 +3,7 @@ //! `DefCollector::collect` contains the fixed-point iteration loop which //! 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 cfg::{CfgExpr, CfgOptions}; @@ -35,8 +35,8 @@ use crate::{ derive_macro_as_call_id, item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports}, item_tree::{ - self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, - Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, + self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, + ItemTreeModItemNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, }, macro_call_as_call_id, macro_call_as_call_id_with_eager, nameres::{ @@ -1579,7 +1579,10 @@ impl ModCollector<'_, '_> { let attrs = self.item_tree.attrs(db, krate, item.into()); if let Some(cfg) = attrs.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; } } @@ -1717,27 +1720,37 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); update_def(self.def_collector, enum_.into(), &it.name, vis, false); + let mut index = 0; let variants = FileItemTreeId::range_iter(it.variants.clone()) .filter_map(|variant| { - let attrs = self.item_tree.attrs(db, krate, variant.into()); - if let Some(cfg) = attrs.cfg() { - if !self.is_cfg_enabled(&cfg) { + let is_enabled = self + .item_tree + .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.item_tree[variant.index()].ast_id.erase(), + InFile::new( + self.file_id(), + self.item_tree[variant.index()].ast_id.erase(), + ), &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(); self.def_collector.def_map.enum_definitions.insert(enum_, variants); @@ -1927,31 +1940,40 @@ impl ModCollector<'_, '_> { let is_enabled = item_tree .top_level_attrs(db, krate) .cfg() - .map_or(true, |cfg| self.is_cfg_enabled(&cfg)); - if is_enabled { - let module_id = self.push_child_module( - module.name.clone(), - ast_id.value, - Some((file_id, is_mod_rs)), - &self.item_tree[module.visibility], - 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, + .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( + ast_id.map(|it| it.erase()), + &cfg, + ); } - .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); + Ok(()) => { + let module_id = self.push_child_module( + module.name.clone(), + ast_id.value, + Some((file_id, is_mod_rs)), + &self.item_tree[module.visibility], + 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) } - fn emit_unconfigured_diagnostic(&mut self, ast_id: ErasedFileAstId, cfg: &CfgExpr) { - let ast_id = InFile::new(self.file_id(), ast_id); + fn emit_unconfigured_diagnostic(&mut self, ast_id: InFile, cfg: &CfgExpr) { self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code( self.module_id, ast_id, diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index 7300a0628f5..01f79f042f7 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -355,12 +355,12 @@ impl DefMap { ModuleDefId::AdtId(AdtId::EnumId(e)) => { // enum variant cov_mark::hit!(can_import_enum_variant); + let def_map; let loc = e.lookup(db); let tree = loc.id.item_tree(db); let current_def_map = self.krate == loc.container.krate && self.block_id() == loc.container.block; - let def_map; let res = if current_def_map { &self.enum_definitions[&e] } else { diff --git a/crates/hir-def/src/src.rs b/crates/hir-def/src/src.rs index 4698e967eb7..9bd8c8d2215 100644 --- a/crates/hir-def/src/src.rs +++ b/crates/hir-def/src/src.rs @@ -5,7 +5,7 @@ use la_arena::ArenaMap; use syntax::ast; use crate::{ - db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup, + db::DefDatabase, item_tree::ItemTreeModItemNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup, Macro2Loc, MacroRulesLoc, ProcMacroLoc, UseId, }; @@ -14,7 +14,7 @@ pub trait HasSource { fn source(&self, db: &dyn DefDatabase) -> InFile; } -impl HasSource for AssocItemLoc { +impl HasSource for AssocItemLoc { type Value = N::Source; fn source(&self, db: &dyn DefDatabase) -> InFile { @@ -27,7 +27,7 @@ impl HasSource for AssocItemLoc { } } -impl HasSource for ItemLoc { +impl HasSource for ItemLoc { type Value = N::Source; fn source(&self, db: &dyn DefDatabase) -> InFile { diff --git a/crates/hir-def/src/trace.rs b/crates/hir-def/src/trace.rs index 01654f04ccf..04d5b266194 100644 --- a/crates/hir-def/src/trace.rs +++ b/crates/hir-def/src/trace.rs @@ -19,6 +19,10 @@ pub(crate) struct Trace { impl Trace { #[allow(dead_code)] + pub(crate) fn new_for_arena() -> Trace { + Trace { arena: Some(Arena::default()), map: None, len: 0 } + } + pub(crate) fn new_for_map() -> Trace { Trace { arena: None, map: Some(ArenaMap::default()), len: 0 } } diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs index c73ffa334c3..3294ce29a4a 100644 --- a/crates/hir-def/src/visibility.rs +++ b/crates/hir-def/src/visibility.rs @@ -222,11 +222,7 @@ pub(crate) fn field_visibilities_query( db: &dyn DefDatabase, variant_id: VariantId, ) -> Arc> { - let var_data = match variant_id { - 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 var_data = variant_id.variant_data(db); let resolver = variant_id.module(db).resolver(db); let mut res = ArenaMap::default(); for (field_id, field_data) in var_data.fields().iter() { diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index 2e1525ebe17..dae612e6d25 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -257,15 +257,7 @@ pub(crate) fn const_eval_discriminant_variant( let body = db.body(def); if body.exprs[body.body_expr] == Expr::Missing { let loc = variant_id.lookup(db.upcast()); - let parent_id = loc.parent.lookup(db.upcast()).id; - 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 prev_idx = loc.index.checked_sub(1); let value = match prev_idx { Some(prev_idx) => { 1 + db.const_eval_discriminant( diff --git a/crates/hir-ty/src/inhabitedness.rs b/crates/hir-ty/src/inhabitedness.rs index dda5ddd0bae..a63556f450d 100644 --- a/crates/hir-ty/src/inhabitedness.rs +++ b/crates/hir-ty/src/inhabitedness.rs @@ -7,7 +7,7 @@ use chalk_ir::{ }; use hir_def::{ attr::Attrs, data::adt::VariantData, visibility::Visibility, AdtId, EnumVariantId, HasModule, - Lookup, ModuleId, VariantId, + ModuleId, VariantId, }; use rustc_hash::FxHashSet; @@ -30,7 +30,7 @@ pub(crate) fn is_enum_variant_uninhabited_from( target_mod: ModuleId, db: &dyn HirDatabase, ) -> 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 = UninhabitedFrom { target_mod, db, max_depth: 500, recursive_ty: FxHashSet::default() }; diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index e160f05b013..f66b584e3b5 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -1729,16 +1729,19 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS /// Build the type of a tuple struct constructor. fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders { let struct_data = db.struct_data(def); - if let StructKind::Unit = struct_data.variant_data.kind() { - return type_for_adt(db, def.into()); + match struct_data.variant_data.kind() { + 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 { @@ -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. fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders { let e = def.lookup(db.upcast()).parent; - if let StructKind::Unit = db.enum_variant_data(def).variant_data.kind() { - return type_for_adt(db, e.into()); + match db.enum_variant_data(def).variant_data.kind() { + 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 { @@ -1813,7 +1820,7 @@ impl CallableDefId { match self { CallableDefId::FunctionId(f) => f.lookup(db).module(db), CallableDefId::StructId(s) => s.lookup(db).container, - CallableDefId::EnumVariantId(e) => e.lookup(db).container, + CallableDefId::EnumVariantId(e) => e.module(db), } .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 { - let impl_loc = impl_id.lookup(db.upcast()); let impl_data = db.impl_data(impl_id); 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 ctx = TyLoweringContext::new(db, &resolver, impl_id.into()) .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> { - let impl_loc = impl_id.lookup(db.upcast()); let impl_data = db.impl_data(impl_id); 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()) .with_type_param_mode(ParamLoweringMode::Variable); let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders(); diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 431d09c5650..ceb170f6cf7 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -751,19 +751,9 @@ impl Evaluator<'_> { Variants::Single { .. } => &layout, Variants::Multiple { variants, .. } => { &variants[match f.parent { - hir_def::VariantId::EnumVariantId(it) => RustcEnumVariantIdx({ - let lookup = it.lookup(self.db.upcast()); - 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 - }), + hir_def::VariantId::EnumVariantId(it) => { + RustcEnumVariantIdx(it.lookup(self.db.upcast()).index as usize) + } _ => { return Err(MirEvalError::TypeError( "Multivariant layout only happens for enums", @@ -1604,15 +1594,7 @@ impl Evaluator<'_> { }; let mut discriminant = self.const_eval_discriminant(enum_variant_id)?; let lookup = enum_variant_id.lookup(self.db.upcast()); - 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(); - let rustc_enum_variant_idx = RustcEnumVariantIdx(rustc_enum_variant_idx as usize); + let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize); let variant_layout = variants[rustc_enum_variant_idx].clone(); let have_tag = match tag_encoding { TagEncoding::Direct => true, diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 246fc231b47..91f60653543 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -44,7 +44,7 @@ use hir_def::{ data::adt::VariantData, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat}, - item_tree::ItemTreeNode, + item_tree::ItemTreeModItemNode, lang_item::LangItemTarget, layout::{self, ReprOptions, TargetDataLayout}, nameres::{self, diagnostics::DefDiagnostic}, @@ -1294,7 +1294,7 @@ pub struct Variant { impl Variant { 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 { @@ -1340,17 +1340,7 @@ impl Variant { layout::Variants::Multiple { variants, .. } => Layout( { let lookup = self.id.lookup(db.upcast()); - let rustc_enum_variant_idx = lookup.id.value.index().into_raw().into_u32() - - 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); - + let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize); Arc::new(variants[rustc_enum_variant_idx].clone()) }, db.target_data_layout(parent_enum.krate(db).into()).unwrap(), @@ -2838,7 +2828,7 @@ where ID: Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, DEF: From, CTOR: FnOnce(DEF) -> AssocItem, - AST: ItemTreeNode, + AST: ItemTreeModItemNode, { match id.lookup(db.upcast()).container { ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))), diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 1c6157de559..19c2d3be16b 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -440,6 +440,12 @@ impl ast::Struct { } } +impl ast::Union { + pub fn kind(&self) -> StructKind { + StructKind::from_node(self) + } +} + impl ast::RecordExprField { pub fn for_field_name(field_name: &ast::NameRef) -> Option { let candidate = Self::for_name_ref(field_name)?;