aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-03-26 15:27:22 +0000
committerAleksey Kladov <[email protected]>2019-03-26 15:27:22 +0000
commit8f324773127c733b12d1c5ee98a3d9c6a5360db0 (patch)
tree4cc6186b417ae6cff6bec44f17ce53b1af574010 /crates/ra_hir
parent071a19537d4399fd04d1e9594ab7878502a12d21 (diff)
more type safety
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/ids.rs32
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/nameres/collector.rs23
-rw-r--r--crates/ra_hir/src/nameres/raw.rs48
-rw-r--r--crates/ra_hir/src/source_id.rs40
5 files changed, 82 insertions, 63 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index b503e0ee5..c2df5ce00 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -1,5 +1,4 @@
1use std::{ 1use std::{
2 marker::PhantomData,
3 hash::{Hash, Hasher}, 2 hash::{Hash, Hasher},
4 sync::Arc, 3 sync::Arc,
5}; 4};
@@ -10,7 +9,7 @@ use ra_arena::{RawId, ArenaId, impl_arena_id};
10use mbe::MacroRules; 9use mbe::MacroRules;
11 10
12use crate::{ 11use crate::{
13 Module, DefDatabase, SourceItemId, SourceFileItemId, AstId, 12 Module, DefDatabase, AstId, FileAstId,
14}; 13};
15 14
16#[derive(Debug, Default)] 15#[derive(Debug, Default)]
@@ -123,6 +122,7 @@ impl From<MacroCallId> for HirFileId {
123} 122}
124 123
125#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 124#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
125
126pub struct MacroDefId(pub(crate) AstId<ast::MacroCall>); 126pub struct MacroDefId(pub(crate) AstId<ast::MacroCall>);
127 127
128pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { 128pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> {
@@ -161,26 +161,25 @@ impl MacroCallLoc {
161#[derive(Debug)] 161#[derive(Debug)]
162pub struct ItemLoc<N: AstNode> { 162pub struct ItemLoc<N: AstNode> {
163 pub(crate) module: Module, 163 pub(crate) module: Module,
164 raw: SourceItemId, 164 ast_id: AstId<N>,
165 _ty: PhantomData<N>,
166} 165}
167 166
168impl<N: AstNode> PartialEq for ItemLoc<N> { 167impl<N: AstNode> PartialEq for ItemLoc<N> {
169 fn eq(&self, other: &Self) -> bool { 168 fn eq(&self, other: &Self) -> bool {
170 self.module == other.module && self.raw == other.raw 169 self.module == other.module && self.ast_id == other.ast_id
171 } 170 }
172} 171}
173impl<N: AstNode> Eq for ItemLoc<N> {} 172impl<N: AstNode> Eq for ItemLoc<N> {}
174impl<N: AstNode> Hash for ItemLoc<N> { 173impl<N: AstNode> Hash for ItemLoc<N> {
175 fn hash<H: Hasher>(&self, hasher: &mut H) { 174 fn hash<H: Hasher>(&self, hasher: &mut H) {
176 self.module.hash(hasher); 175 self.module.hash(hasher);
177 self.raw.hash(hasher); 176 self.ast_id.hash(hasher);
178 } 177 }
179} 178}
180 179
181impl<N: AstNode> Clone for ItemLoc<N> { 180impl<N: AstNode> Clone for ItemLoc<N> {
182 fn clone(&self) -> ItemLoc<N> { 181 fn clone(&self) -> ItemLoc<N> {
183 ItemLoc { module: self.module, raw: self.raw, _ty: PhantomData } 182 ItemLoc { module: self.module, ast_id: self.ast_id }
184 } 183 }
185} 184}
186 185
@@ -208,25 +207,18 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
208 fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; 207 fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>;
209 fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { 208 fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self {
210 let items = ctx.db.file_items(ctx.file_id); 209 let items = ctx.db.file_items(ctx.file_id);
211 let item_id = items.id_of(ctx.file_id, ast.syntax()); 210 let item_id = items.ast_id(ast);
212 Self::from_source_item_id_unchecked(ctx, item_id) 211 Self::from_ast_id(ctx, item_id)
213 } 212 }
214 fn from_source_item_id_unchecked( 213 fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self {
215 ctx: LocationCtx<&impl DefDatabase>, 214 let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) };
216 item_id: SourceFileItemId,
217 ) -> Self {
218 let raw = SourceItemId { file_id: ctx.file_id, item_id };
219 let loc = ItemLoc { module: ctx.module, raw, _ty: PhantomData };
220
221 Self::interner(ctx.db.as_ref()).loc2id(&loc) 215 Self::interner(ctx.db.as_ref()).loc2id(&loc)
222 } 216 }
223 fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) { 217 fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) {
224 let int = Self::interner(db.as_ref()); 218 let int = Self::interner(db.as_ref());
225 let loc = int.id2loc(self); 219 let loc = int.id2loc(self);
226 let syntax = db.file_item(loc.raw); 220 let ast = loc.ast_id.to_node(db);
227 let ast = 221 (loc.ast_id.file_id(), ast)
228 N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned();
229 (loc.raw.file_id, ast)
230 } 222 }
231 fn module(self, db: &impl DefDatabase) -> Module { 223 fn module(self, db: &impl DefDatabase) -> Module {
232 let int = Self::interner(db.as_ref()); 224 let int = Self::interner(db.as_ref());
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 3fc08c55c..b1f388b06 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -48,7 +48,7 @@ mod marks;
48use crate::{ 48use crate::{
49 db::{HirDatabase, DefDatabase}, 49 db::{HirDatabase, DefDatabase},
50 name::{AsName, KnownName}, 50 name::{AsName, KnownName},
51 source_id::{SourceFileItemId, FileAstId, AstId}, 51 source_id::{FileAstId, AstId},
52}; 52};
53 53
54pub use self::{ 54pub use self::{
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index b5f02ab80..39cadc94a 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -429,23 +429,24 @@ where
429 fn define_def(&mut self, def: &raw::DefData) { 429 fn define_def(&mut self, def: &raw::DefData) {
430 let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; 430 let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id };
431 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into()); 431 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into());
432 macro_rules! id { 432
433 () => { 433 macro_rules! def {
434 AstItemDef::from_source_item_id_unchecked(ctx, def.source_item_id) 434 ($kind:ident, $ast_id:ident) => {
435 $kind { id: AstItemDef::from_ast_id(ctx, $ast_id) }.into()
435 }; 436 };
436 } 437 }
437 let name = def.name.clone(); 438 let name = def.name.clone();
438 let def: PerNs<ModuleDef> = match def.kind { 439 let def: PerNs<ModuleDef> = match def.kind {
439 raw::DefKind::Function => PerNs::values(Function { id: id!() }.into()), 440 raw::DefKind::Function(ast_id) => PerNs::values(def!(Function, ast_id)),
440 raw::DefKind::Struct => { 441 raw::DefKind::Struct(ast_id) => {
441 let s = Struct { id: id!() }.into(); 442 let s = def!(Struct, ast_id);
442 PerNs::both(s, s) 443 PerNs::both(s, s)
443 } 444 }
444 raw::DefKind::Enum => PerNs::types(Enum { id: id!() }.into()), 445 raw::DefKind::Enum(ast_id) => PerNs::types(def!(Enum, ast_id)),
445 raw::DefKind::Const => PerNs::values(Const { id: id!() }.into()), 446 raw::DefKind::Const(ast_id) => PerNs::values(def!(Const, ast_id)),
446 raw::DefKind::Static => PerNs::values(Static { id: id!() }.into()), 447 raw::DefKind::Static(ast_id) => PerNs::values(def!(Static, ast_id)),
447 raw::DefKind::Trait => PerNs::types(Trait { id: id!() }.into()), 448 raw::DefKind::Trait(ast_id) => PerNs::types(def!(Trait, ast_id)),
448 raw::DefKind::TypeAlias => PerNs::types(TypeAlias { id: id!() }.into()), 449 raw::DefKind::TypeAlias(ast_id) => PerNs::types(def!(TypeAlias, ast_id)),
449 }; 450 };
450 let resolution = Resolution { def, import: None }; 451 let resolution = Resolution { def, import: None };
451 self.def_collector.update(self.module_id, None, &[(name, resolution)]) 452 self.def_collector.update(self.module_id, None, &[(name, resolution)])
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 684bd1d50..984478adc 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -12,7 +12,7 @@ use ra_syntax::{
12 12
13use crate::{ 13use crate::{
14 DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, 14 DefDatabase, Name, AsName, Path, HirFileId, ModuleSource,
15 SourceFileItemId, SourceFileItems, FileAstId, 15 SourceFileItems, FileAstId,
16}; 16};
17 17
18/// `RawItems` is a set of top-level items in a file (except for impls). 18/// `RawItems` is a set of top-level items in a file (except for impls).
@@ -138,20 +138,19 @@ impl_arena_id!(Def);
138 138
139#[derive(Debug, PartialEq, Eq)] 139#[derive(Debug, PartialEq, Eq)]
140pub(super) struct DefData { 140pub(super) struct DefData {
141 pub(super) source_item_id: SourceFileItemId,
142 pub(super) name: Name, 141 pub(super) name: Name,
143 pub(super) kind: DefKind, 142 pub(super) kind: DefKind,
144} 143}
145 144
146#[derive(Debug, PartialEq, Eq, Clone, Copy)] 145#[derive(Debug, PartialEq, Eq, Clone, Copy)]
147pub(super) enum DefKind { 146pub(super) enum DefKind {
148 Function, 147 Function(FileAstId<ast::FnDef>),
149 Struct, 148 Struct(FileAstId<ast::StructDef>),
150 Enum, 149 Enum(FileAstId<ast::EnumDef>),
151 Const, 150 Const(FileAstId<ast::ConstDef>),
152 Static, 151 Static(FileAstId<ast::StaticDef>),
153 Trait, 152 Trait(FileAstId<ast::TraitDef>),
154 TypeAlias, 153 TypeAlias(FileAstId<ast::TypeAliasDef>),
155} 154}
156 155
157#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -200,18 +199,31 @@ impl RawItemsCollector {
200 // impls don't participate in name resolution 199 // impls don't participate in name resolution
201 return; 200 return;
202 } 201 }
203 ast::ModuleItemKind::StructDef(it) => (DefKind::Struct, it.name()), 202 ast::ModuleItemKind::StructDef(it) => {
204 ast::ModuleItemKind::EnumDef(it) => (DefKind::Enum, it.name()), 203 (DefKind::Struct(self.source_file_items.ast_id(it)), it.name())
205 ast::ModuleItemKind::FnDef(it) => (DefKind::Function, it.name()), 204 }
206 ast::ModuleItemKind::TraitDef(it) => (DefKind::Trait, it.name()), 205 ast::ModuleItemKind::EnumDef(it) => {
207 ast::ModuleItemKind::TypeAliasDef(it) => (DefKind::TypeAlias, it.name()), 206 (DefKind::Enum(self.source_file_items.ast_id(it)), it.name())
208 ast::ModuleItemKind::ConstDef(it) => (DefKind::Const, it.name()), 207 }
209 ast::ModuleItemKind::StaticDef(it) => (DefKind::Static, it.name()), 208 ast::ModuleItemKind::FnDef(it) => {
209 (DefKind::Function(self.source_file_items.ast_id(it)), it.name())
210 }
211 ast::ModuleItemKind::TraitDef(it) => {
212 (DefKind::Trait(self.source_file_items.ast_id(it)), it.name())
213 }
214 ast::ModuleItemKind::TypeAliasDef(it) => {
215 (DefKind::TypeAlias(self.source_file_items.ast_id(it)), it.name())
216 }
217 ast::ModuleItemKind::ConstDef(it) => {
218 (DefKind::Const(self.source_file_items.ast_id(it)), it.name())
219 }
220 ast::ModuleItemKind::StaticDef(it) => {
221 (DefKind::Static(self.source_file_items.ast_id(it)), it.name())
222 }
210 }; 223 };
211 if let Some(name) = name { 224 if let Some(name) = name {
212 let name = name.as_name(); 225 let name = name.as_name();
213 let source_item_id = self.source_file_items.id_of_unchecked(item.syntax()); 226 let def = self.raw_items.defs.alloc(DefData { name, kind });
214 let def = self.raw_items.defs.alloc(DefData { name, kind, source_item_id });
215 self.push_item(current_module, RawItem::Def(def)) 227 self.push_item(current_module, RawItem::Def(def))
216 } 228 }
217 } 229 }
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs
index 1dadd76c5..2c855897a 100644
--- a/crates/ra_hir/src/source_id.rs
+++ b/crates/ra_hir/src/source_id.rs
@@ -1,11 +1,11 @@
1use std::{marker::PhantomData, sync::Arc}; 1use std::{marker::PhantomData, sync::Arc, hash::{Hash, Hasher}};
2 2
3use ra_arena::{Arena, RawId, impl_arena_id}; 3use ra_arena::{Arena, RawId, impl_arena_id};
4use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast}; 4use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast};
5 5
6use crate::{HirFileId, DefDatabase}; 6use crate::{HirFileId, DefDatabase};
7 7
8#[derive(Debug, PartialEq, Eq, Hash)] 8#[derive(Debug)]
9pub(crate) struct AstId<N: AstNode> { 9pub(crate) struct AstId<N: AstNode> {
10 file_id: HirFileId, 10 file_id: HirFileId,
11 file_ast_id: FileAstId<N>, 11 file_ast_id: FileAstId<N>,
@@ -16,9 +16,20 @@ impl<N: AstNode> Clone for AstId<N> {
16 *self 16 *self
17 } 17 }
18} 18}
19
20impl<N: AstNode> Copy for AstId<N> {} 19impl<N: AstNode> Copy for AstId<N> {}
21 20
21impl<N: AstNode> PartialEq for AstId<N> {
22 fn eq(&self, other: &Self) -> bool {
23 (self.file_id, self.file_ast_id) == (other.file_id, other.file_ast_id)
24 }
25}
26impl<N: AstNode> Eq for AstId<N> {}
27impl<N: AstNode> Hash for AstId<N> {
28 fn hash<H: Hasher>(&self, hasher: &mut H) {
29 (self.file_id, self.file_ast_id).hash(hasher);
30 }
31}
32
22impl<N: AstNode> AstId<N> { 33impl<N: AstNode> AstId<N> {
23 pub(crate) fn file_id(&self) -> HirFileId { 34 pub(crate) fn file_id(&self) -> HirFileId {
24 self.file_id 35 self.file_id
@@ -30,7 +41,7 @@ impl<N: AstNode> AstId<N> {
30 } 41 }
31} 42}
32 43
33#[derive(Debug, PartialEq, Eq, Hash)] 44#[derive(Debug)]
34pub(crate) struct FileAstId<N: AstNode> { 45pub(crate) struct FileAstId<N: AstNode> {
35 raw: SourceFileItemId, 46 raw: SourceFileItemId,
36 _ty: PhantomData<N>, 47 _ty: PhantomData<N>,
@@ -41,9 +52,20 @@ impl<N: AstNode> Clone for FileAstId<N> {
41 *self 52 *self
42 } 53 }
43} 54}
44
45impl<N: AstNode> Copy for FileAstId<N> {} 55impl<N: AstNode> Copy for FileAstId<N> {}
46 56
57impl<N: AstNode> PartialEq for FileAstId<N> {
58 fn eq(&self, other: &Self) -> bool {
59 self.raw == other.raw
60 }
61}
62impl<N: AstNode> Eq for FileAstId<N> {}
63impl<N: AstNode> Hash for FileAstId<N> {
64 fn hash<H: Hasher>(&self, hasher: &mut H) {
65 self.raw.hash(hasher);
66 }
67}
68
47impl<N: AstNode> FileAstId<N> { 69impl<N: AstNode> FileAstId<N> {
48 pub(crate) fn with_file_id(self, file_id: HirFileId) -> AstId<N> { 70 pub(crate) fn with_file_id(self, file_id: HirFileId) -> AstId<N> {
49 AstId { file_id, file_ast_id: self } 71 AstId { file_id, file_ast_id: self }
@@ -116,14 +138,6 @@ impl SourceFileItems {
116 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId { 138 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId {
117 self.arena.alloc(SyntaxNodePtr::new(item)) 139 self.arena.alloc(SyntaxNodePtr::new(item))
118 } 140 }
119 pub(crate) fn id_of(&self, file_id: HirFileId, item: &SyntaxNode) -> SourceFileItemId {
120 assert_eq!(
121 self.file_id, file_id,
122 "SourceFileItems: wrong file, expected {:?}, got {:?}",
123 self.file_id, file_id
124 );
125 self.id_of_unchecked(item)
126 }
127 pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId { 141 pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId {
128 let ptr = SyntaxNodePtr::new(item); 142 let ptr = SyntaxNodePtr::new(item);
129 if let Some((id, _)) = self.arena.iter().find(|(_id, i)| **i == ptr) { 143 if let Some((id, _)) = self.arena.iter().find(|(_id, i)| **i == ptr) {