diff options
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/attr.rs | 66 | ||||
-rw-r--r-- | crates/hir_def/src/db.rs | 15 | ||||
-rw-r--r-- | crates/hir_def/src/item_scope.rs | 13 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 34 |
5 files changed, 107 insertions, 29 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index ab77d924a..d9df7564d 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -16,7 +16,7 @@ use mbe::ast_to_token_tree; | |||
16 | use smallvec::{smallvec, SmallVec}; | 16 | use smallvec::{smallvec, SmallVec}; |
17 | use syntax::{ | 17 | use syntax::{ |
18 | ast::{self, AstNode, AttrsOwner}, | 18 | ast::{self, AstNode, AttrsOwner}, |
19 | match_ast, AstToken, SmolStr, SyntaxNode, TextRange, TextSize, | 19 | match_ast, AstPtr, AstToken, SmolStr, SyntaxNode, TextRange, TextSize, |
20 | }; | 20 | }; |
21 | use tt::Subtree; | 21 | use tt::Subtree; |
22 | 22 | ||
@@ -215,12 +215,11 @@ impl Attrs { | |||
215 | let mut res = ArenaMap::default(); | 215 | let mut res = ArenaMap::default(); |
216 | 216 | ||
217 | for (id, fld) in src.value.iter() { | 217 | for (id, fld) in src.value.iter() { |
218 | let attrs = match fld { | 218 | let owner: &dyn AttrsOwner = match fld { |
219 | Either::Left(_tuple) => Attrs::default(), | 219 | Either::Left(tuple) => tuple, |
220 | Either::Right(record) => { | 220 | Either::Right(record) => record, |
221 | RawAttrs::from_attrs_owner(db, src.with_value(record)).filter(db, krate) | ||
222 | } | ||
223 | }; | 221 | }; |
222 | let attrs = RawAttrs::from_attrs_owner(db, src.with_value(owner)).filter(db, krate); | ||
224 | 223 | ||
225 | res.insert(id, attrs); | 224 | res.insert(id, attrs); |
226 | } | 225 | } |
@@ -404,10 +403,14 @@ impl AttrsWithOwner { | |||
404 | return AttrSourceMap { attrs }; | 403 | return AttrSourceMap { attrs }; |
405 | } | 404 | } |
406 | AttrDefId::FieldId(id) => { | 405 | AttrDefId::FieldId(id) => { |
407 | id.parent.child_source(db).map(|source| match &source[id.local_id] { | 406 | let map = db.fields_attrs_source_map(id.parent); |
408 | Either::Left(field) => ast::AttrsOwnerNode::new(field.clone()), | 407 | let file_id = id.parent.file_id(db); |
409 | Either::Right(field) => ast::AttrsOwnerNode::new(field.clone()), | 408 | let root = db.parse_or_expand(file_id).unwrap(); |
410 | }) | 409 | let owner = match &map[id.local_id] { |
410 | Either::Left(it) => ast::AttrsOwnerNode::new(it.to_node(&root)), | ||
411 | Either::Right(it) => ast::AttrsOwnerNode::new(it.to_node(&root)), | ||
412 | }; | ||
413 | InFile::new(file_id, owner) | ||
411 | } | 414 | } |
412 | AttrDefId::AdtId(adt) => match adt { | 415 | AttrDefId::AdtId(adt) => match adt { |
413 | AdtId::StructId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), | 416 | AdtId::StructId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), |
@@ -415,10 +418,12 @@ impl AttrsWithOwner { | |||
415 | AdtId::EnumId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), | 418 | AdtId::EnumId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), |
416 | }, | 419 | }, |
417 | AttrDefId::FunctionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), | 420 | AttrDefId::FunctionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), |
418 | AttrDefId::EnumVariantId(id) => id | 421 | AttrDefId::EnumVariantId(id) => { |
419 | .parent | 422 | let map = db.variants_attrs_source_map(id.parent); |
420 | .child_source(db) | 423 | let file_id = id.parent.lookup(db).id.file_id(); |
421 | .map(|source| ast::AttrsOwnerNode::new(source[id.local_id].clone())), | 424 | let root = db.parse_or_expand(file_id).unwrap(); |
425 | InFile::new(file_id, ast::AttrsOwnerNode::new(map[id.local_id].to_node(&root))) | ||
426 | } | ||
422 | AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), | 427 | AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), |
423 | AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), | 428 | AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), |
424 | AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), | 429 | AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), |
@@ -747,3 +752,36 @@ fn collect_attrs( | |||
747 | 752 | ||
748 | attrs.into_iter().map(|(_, attr)| attr) | 753 | attrs.into_iter().map(|(_, attr)| attr) |
749 | } | 754 | } |
755 | |||
756 | pub(crate) fn variants_attrs_source_map( | ||
757 | db: &dyn DefDatabase, | ||
758 | def: EnumId, | ||
759 | ) -> Arc<ArenaMap<LocalEnumVariantId, AstPtr<ast::Variant>>> { | ||
760 | let mut res = ArenaMap::default(); | ||
761 | let child_source = def.child_source(db); | ||
762 | |||
763 | for (idx, variant) in child_source.value.iter() { | ||
764 | res.insert(idx, AstPtr::new(variant)); | ||
765 | } | ||
766 | |||
767 | Arc::new(res) | ||
768 | } | ||
769 | |||
770 | pub(crate) fn fields_attrs_source_map( | ||
771 | db: &dyn DefDatabase, | ||
772 | def: VariantId, | ||
773 | ) -> Arc<ArenaMap<LocalFieldId, Either<AstPtr<ast::TupleField>, AstPtr<ast::RecordField>>>> { | ||
774 | let mut res = ArenaMap::default(); | ||
775 | let child_source = def.child_source(db); | ||
776 | |||
777 | for (idx, variant) in child_source.value.iter() { | ||
778 | res.insert( | ||
779 | idx, | ||
780 | variant | ||
781 | .as_ref() | ||
782 | .either(|l| Either::Left(AstPtr::new(l)), |r| Either::Right(AstPtr::new(r))), | ||
783 | ); | ||
784 | } | ||
785 | |||
786 | Arc::new(res) | ||
787 | } | ||
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs index 9b7a213a1..7eadc8e0d 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs | |||
@@ -2,9 +2,10 @@ | |||
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; | 4 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; |
5 | use either::Either; | ||
5 | use hir_expand::{db::AstDatabase, HirFileId}; | 6 | use hir_expand::{db::AstDatabase, HirFileId}; |
6 | use la_arena::ArenaMap; | 7 | use la_arena::ArenaMap; |
7 | use syntax::SmolStr; | 8 | use syntax::{ast, AstPtr, SmolStr}; |
8 | 9 | ||
9 | use crate::{ | 10 | use crate::{ |
10 | adt::{EnumData, StructData}, | 11 | adt::{EnumData, StructData}, |
@@ -122,6 +123,18 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> { | |||
122 | #[salsa::invoke(Attrs::fields_attrs_query)] | 123 | #[salsa::invoke(Attrs::fields_attrs_query)] |
123 | fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>; | 124 | fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>; |
124 | 125 | ||
126 | #[salsa::invoke(crate::attr::variants_attrs_source_map)] | ||
127 | fn variants_attrs_source_map( | ||
128 | &self, | ||
129 | def: EnumId, | ||
130 | ) -> Arc<ArenaMap<LocalEnumVariantId, AstPtr<ast::Variant>>>; | ||
131 | |||
132 | #[salsa::invoke(crate::attr::fields_attrs_source_map)] | ||
133 | fn fields_attrs_source_map( | ||
134 | &self, | ||
135 | def: VariantId, | ||
136 | ) -> Arc<ArenaMap<LocalFieldId, Either<AstPtr<ast::TupleField>, AstPtr<ast::RecordField>>>>; | ||
137 | |||
125 | #[salsa::invoke(AttrsWithOwner::attrs_query)] | 138 | #[salsa::invoke(AttrsWithOwner::attrs_query)] |
126 | fn attrs(&self, def: AttrDefId) -> AttrsWithOwner; | 139 | fn attrs(&self, def: AttrDefId) -> AttrsWithOwner; |
127 | 140 | ||
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index a8ee5eeac..9014468ea 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs | |||
@@ -11,7 +11,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
11 | use stdx::format_to; | 11 | use stdx::format_to; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ImplId, | 14 | db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ConstId, ImplId, |
15 | LocalModuleId, MacroDefId, ModuleDefId, ModuleId, TraitId, | 15 | LocalModuleId, MacroDefId, ModuleDefId, ModuleId, TraitId, |
16 | }; | 16 | }; |
17 | 17 | ||
@@ -37,6 +37,7 @@ pub struct ItemScope { | |||
37 | 37 | ||
38 | defs: Vec<ModuleDefId>, | 38 | defs: Vec<ModuleDefId>, |
39 | impls: Vec<ImplId>, | 39 | impls: Vec<ImplId>, |
40 | unnamed_consts: Vec<ConstId>, | ||
40 | /// Traits imported via `use Trait as _;`. | 41 | /// Traits imported via `use Trait as _;`. |
41 | unnamed_trait_imports: FxHashMap<TraitId, Visibility>, | 42 | unnamed_trait_imports: FxHashMap<TraitId, Visibility>, |
42 | /// Macros visible in current module in legacy textual scope | 43 | /// Macros visible in current module in legacy textual scope |
@@ -106,6 +107,10 @@ impl ItemScope { | |||
106 | .map(|(_, v)| v) | 107 | .map(|(_, v)| v) |
107 | } | 108 | } |
108 | 109 | ||
110 | pub fn unnamed_consts(&self) -> impl Iterator<Item = ConstId> + '_ { | ||
111 | self.unnamed_consts.iter().copied() | ||
112 | } | ||
113 | |||
109 | /// Iterate over all module scoped macros | 114 | /// Iterate over all module scoped macros |
110 | pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { | 115 | pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { |
111 | self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_))) | 116 | self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_))) |
@@ -156,6 +161,10 @@ impl ItemScope { | |||
156 | self.impls.push(imp) | 161 | self.impls.push(imp) |
157 | } | 162 | } |
158 | 163 | ||
164 | pub(crate) fn define_unnamed_const(&mut self, konst: ConstId) { | ||
165 | self.unnamed_consts.push(konst); | ||
166 | } | ||
167 | |||
159 | pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) { | 168 | pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) { |
160 | self.legacy_macros.insert(name, mac); | 169 | self.legacy_macros.insert(name, mac); |
161 | } | 170 | } |
@@ -295,6 +304,7 @@ impl ItemScope { | |||
295 | unresolved, | 304 | unresolved, |
296 | defs, | 305 | defs, |
297 | impls, | 306 | impls, |
307 | unnamed_consts, | ||
298 | unnamed_trait_imports, | 308 | unnamed_trait_imports, |
299 | legacy_macros, | 309 | legacy_macros, |
300 | } = self; | 310 | } = self; |
@@ -304,6 +314,7 @@ impl ItemScope { | |||
304 | unresolved.shrink_to_fit(); | 314 | unresolved.shrink_to_fit(); |
305 | defs.shrink_to_fit(); | 315 | defs.shrink_to_fit(); |
306 | impls.shrink_to_fit(); | 316 | impls.shrink_to_fit(); |
317 | unnamed_consts.shrink_to_fit(); | ||
307 | unnamed_trait_imports.shrink_to_fit(); | 318 | unnamed_trait_imports.shrink_to_fit(); |
308 | legacy_macros.shrink_to_fit(); | 319 | legacy_macros.shrink_to_fit(); |
309 | } | 320 | } |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index abd6c553f..e2af0e514 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -453,6 +453,14 @@ impl VariantId { | |||
453 | } | 453 | } |
454 | } | 454 | } |
455 | } | 455 | } |
456 | |||
457 | pub fn file_id(self, db: &dyn db::DefDatabase) -> HirFileId { | ||
458 | match self { | ||
459 | VariantId::EnumVariantId(it) => it.parent.lookup(db).id.file_id(), | ||
460 | VariantId::StructId(it) => it.lookup(db).id.file_id(), | ||
461 | VariantId::UnionId(it) => it.lookup(db).id.file_id(), | ||
462 | } | ||
463 | } | ||
456 | } | 464 | } |
457 | 465 | ||
458 | trait Intern { | 466 | trait Intern { |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index f42f92702..492d8c71f 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -1163,19 +1163,27 @@ impl ModCollector<'_, '_> { | |||
1163 | } | 1163 | } |
1164 | ModItem::Const(id) => { | 1164 | ModItem::Const(id) => { |
1165 | let it = &self.item_tree[id]; | 1165 | let it = &self.item_tree[id]; |
1166 | 1166 | let const_id = ConstLoc { | |
1167 | if let Some(name) = &it.name { | 1167 | container: module.into(), |
1168 | def = Some(DefData { | 1168 | id: ItemTreeId::new(self.file_id, id), |
1169 | id: ConstLoc { | 1169 | } |
1170 | container: module.into(), | 1170 | .intern(self.def_collector.db); |
1171 | id: ItemTreeId::new(self.file_id, id), | 1171 | |
1172 | } | 1172 | match &it.name { |
1173 | .intern(self.def_collector.db) | 1173 | Some(name) => { |
1174 | .into(), | 1174 | def = Some(DefData { |
1175 | name, | 1175 | id: const_id.into(), |
1176 | visibility: &self.item_tree[it.visibility], | 1176 | name, |
1177 | has_constructor: false, | 1177 | visibility: &self.item_tree[it.visibility], |
1178 | }); | 1178 | has_constructor: false, |
1179 | }); | ||
1180 | } | ||
1181 | None => { | ||
1182 | // const _: T = ...; | ||
1183 | self.def_collector.def_map.modules[self.module_id] | ||
1184 | .scope | ||
1185 | .define_unnamed_const(const_id); | ||
1186 | } | ||
1179 | } | 1187 | } |
1180 | } | 1188 | } |
1181 | ModItem::Static(id) => { | 1189 | ModItem::Static(id) => { |