aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/adt.rs152
-rw-r--r--crates/ra_hir_def/src/attr.rs76
-rw-r--r--crates/ra_hir_def/src/body.rs16
-rw-r--r--crates/ra_hir_def/src/body/lower.rs6
-rw-r--r--crates/ra_hir_def/src/body/scope.rs6
-rw-r--r--crates/ra_hir_def/src/data.rs14
-rw-r--r--crates/ra_hir_def/src/db.rs46
-rw-r--r--crates/ra_hir_def/src/docs.rs68
-rw-r--r--crates/ra_hir_def/src/generics.rs8
-rw-r--r--crates/ra_hir_def/src/lang_item.rs120
-rw-r--r--crates/ra_hir_def/src/lib.rs160
-rw-r--r--crates/ra_hir_def/src/nameres.rs83
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs59
-rw-r--r--crates/ra_hir_def/src/nameres/mod_resolution.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs17
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs40
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/tests/mod_resolution.rs2
-rw-r--r--crates/ra_hir_def/src/per_ns.rs (renamed from crates/ra_hir_def/src/nameres/per_ns.rs)0
-rw-r--r--crates/ra_hir_def/src/resolver.rs75
-rw-r--r--crates/ra_hir_def/src/test_db.rs2
-rw-r--r--crates/ra_hir_def/src/trace.rs49
22 files changed, 698 insertions, 309 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index 2bd18255c..20e9a1eb5 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -2,13 +2,17 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_expand::name::{AsName, Name}; 5use hir_expand::{
6use ra_arena::Arena; 6 either::Either,
7 name::{AsName, Name},
8 Source,
9};
10use ra_arena::{map::ArenaMap, Arena};
7use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
8 12
9use crate::{ 13use crate::{
10 db::DefDatabase2, type_ref::TypeRef, AstItemDef, EnumId, LocalEnumVariantId, 14 db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource,
11 LocalStructFieldId, StructOrUnionId, 15 LocalEnumVariantId, LocalStructFieldId, StructOrUnionId, VariantId,
12}; 16};
13 17
14/// Note that we use `StructData` for unions as well! 18/// Note that we use `StructData` for unions as well!
@@ -45,10 +49,7 @@ pub struct StructFieldData {
45} 49}
46 50
47impl StructData { 51impl StructData {
48 pub(crate) fn struct_data_query( 52 pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructOrUnionId) -> Arc<StructData> {
49 db: &impl DefDatabase2,
50 id: StructOrUnionId,
51 ) -> Arc<StructData> {
52 let src = id.source(db); 53 let src = id.source(db);
53 let name = src.value.name().map(|n| n.as_name()); 54 let name = src.value.name().map(|n| n.as_name());
54 let variant_data = VariantData::new(src.value.kind()); 55 let variant_data = VariantData::new(src.value.kind());
@@ -58,20 +59,12 @@ impl StructData {
58} 59}
59 60
60impl EnumData { 61impl EnumData {
61 pub(crate) fn enum_data_query(db: &impl DefDatabase2, e: EnumId) -> Arc<EnumData> { 62 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> {
62 let src = e.source(db); 63 let src = e.source(db);
63 let name = src.value.name().map(|n| n.as_name()); 64 let name = src.value.name().map(|n| n.as_name());
64 let variants = src 65 let mut trace = Trace::new_for_arena();
65 .value 66 lower_enum(&mut trace, &src.value);
66 .variant_list() 67 Arc::new(EnumData { name, variants: trace.into_arena() })
67 .into_iter()
68 .flat_map(|it| it.variants())
69 .map(|var| EnumVariantData {
70 name: var.name().map(|it| it.as_name()),
71 variant_data: Arc::new(VariantData::new(var.kind())),
72 })
73 .collect();
74 Arc::new(EnumData { name, variants })
75 } 68 }
76 69
77 pub(crate) fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> { 70 pub(crate) fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> {
@@ -80,38 +73,109 @@ impl EnumData {
80 } 73 }
81} 74}
82 75
76impl HasChildSource for EnumId {
77 type ChildId = LocalEnumVariantId;
78 type Value = ast::EnumVariant;
79 fn child_source(&self, db: &impl DefDatabase) -> Source<ArenaMap<Self::ChildId, Self::Value>> {
80 let src = self.source(db);
81 let mut trace = Trace::new_for_map();
82 lower_enum(&mut trace, &src.value);
83 src.with_value(trace.into_map())
84 }
85}
86
87fn lower_enum(
88 trace: &mut Trace<LocalEnumVariantId, EnumVariantData, ast::EnumVariant>,
89 ast: &ast::EnumDef,
90) {
91 for var in ast.variant_list().into_iter().flat_map(|it| it.variants()) {
92 trace.alloc(
93 || var.clone(),
94 || EnumVariantData {
95 name: var.name().map(|it| it.as_name()),
96 variant_data: Arc::new(VariantData::new(var.kind())),
97 },
98 )
99 }
100}
101
83impl VariantData { 102impl VariantData {
84 fn new(flavor: ast::StructKind) -> Self { 103 fn new(flavor: ast::StructKind) -> Self {
85 match flavor { 104 let mut trace = Trace::new_for_arena();
86 ast::StructKind::Tuple(fl) => { 105 match lower_struct(&mut trace, &flavor) {
87 let fields = fl 106 StructKind::Tuple => VariantData::Tuple(trace.into_arena()),
88 .fields() 107 StructKind::Record => VariantData::Record(trace.into_arena()),
89 .enumerate() 108 StructKind::Unit => VariantData::Unit,
90 .map(|(i, fd)| StructFieldData {
91 name: Name::new_tuple_field(i),
92 type_ref: TypeRef::from_ast_opt(fd.type_ref()),
93 })
94 .collect();
95 VariantData::Tuple(fields)
96 }
97 ast::StructKind::Record(fl) => {
98 let fields = fl
99 .fields()
100 .map(|fd| StructFieldData {
101 name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
102 type_ref: TypeRef::from_ast_opt(fd.ascribed_type()),
103 })
104 .collect();
105 VariantData::Record(fields)
106 }
107 ast::StructKind::Unit => VariantData::Unit,
108 } 109 }
109 } 110 }
110 111
111 pub fn fields(&self) -> Option<&Arena<LocalStructFieldId, StructFieldData>> { 112 pub fn fields(&self) -> Option<&Arena<LocalStructFieldId, StructFieldData>> {
112 match self { 113 match &self {
113 VariantData::Record(fields) | VariantData::Tuple(fields) => Some(fields), 114 VariantData::Record(fields) | VariantData::Tuple(fields) => Some(fields),
114 _ => None, 115 _ => None,
115 } 116 }
116 } 117 }
117} 118}
119
120impl HasChildSource for VariantId {
121 type ChildId = LocalStructFieldId;
122 type Value = Either<ast::TupleFieldDef, ast::RecordFieldDef>;
123
124 fn child_source(&self, db: &impl DefDatabase) -> Source<ArenaMap<Self::ChildId, Self::Value>> {
125 let src = match self {
126 VariantId::EnumVariantId(it) => {
127 // I don't really like the fact that we call into parent source
128 // here, this might add to more queries then necessary.
129 let src = it.parent.child_source(db);
130 src.map(|map| map[it.local_id].kind())
131 }
132 VariantId::StructId(it) => it.0.source(db).map(|it| it.kind()),
133 };
134 let mut trace = Trace::new_for_map();
135 lower_struct(&mut trace, &src.value);
136 src.with_value(trace.into_map())
137 }
138}
139
140enum StructKind {
141 Tuple,
142 Record,
143 Unit,
144}
145
146fn lower_struct(
147 trace: &mut Trace<
148 LocalStructFieldId,
149 StructFieldData,
150 Either<ast::TupleFieldDef, ast::RecordFieldDef>,
151 >,
152 ast: &ast::StructKind,
153) -> StructKind {
154 match ast {
155 ast::StructKind::Tuple(fl) => {
156 for (i, fd) in fl.fields().enumerate() {
157 trace.alloc(
158 || Either::A(fd.clone()),
159 || StructFieldData {
160 name: Name::new_tuple_field(i),
161 type_ref: TypeRef::from_ast_opt(fd.type_ref()),
162 },
163 )
164 }
165 StructKind::Tuple
166 }
167 ast::StructKind::Record(fl) => {
168 for fd in fl.fields() {
169 trace.alloc(
170 || Either::B(fd.clone()),
171 || StructFieldData {
172 name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
173 type_ref: TypeRef::from_ast_opt(fd.ascribed_type()),
174 },
175 )
176 }
177 StructKind::Record
178 }
179 ast::StructKind::Unit => StructKind::Unit,
180 }
181}
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 7a9d0fdf4..48ce8cd93 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -2,7 +2,7 @@
2 2
3use std::{ops, sync::Arc}; 3use std::{ops, sync::Arc};
4 4
5use hir_expand::hygiene::Hygiene; 5use hir_expand::{either::Either, hygiene::Hygiene, AstId};
6use mbe::ast_to_token_tree; 6use mbe::ast_to_token_tree;
7use ra_cfg::CfgOptions; 7use ra_cfg::CfgOptions;
8use ra_syntax::{ 8use ra_syntax::{
@@ -11,7 +11,9 @@ use ra_syntax::{
11}; 11};
12use tt::Subtree; 12use tt::Subtree;
13 13
14use crate::path::Path; 14use crate::{
15 db::DefDatabase, path::Path, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup,
16};
15 17
16#[derive(Default, Debug, Clone, PartialEq, Eq)] 18#[derive(Default, Debug, Clone, PartialEq, Eq)]
17pub struct Attrs { 19pub struct Attrs {
@@ -30,9 +32,59 @@ impl ops::Deref for Attrs {
30} 32}
31 33
32impl Attrs { 34impl Attrs {
35 pub(crate) fn attrs_query(db: &impl DefDatabase, def: AttrDefId) -> Attrs {
36 match def {
37 AttrDefId::ModuleId(module) => {
38 let def_map = db.crate_def_map(module.krate);
39 let src = match def_map[module.module_id].declaration_source(db) {
40 Some(it) => it,
41 None => return Attrs::default(),
42 };
43 let hygiene = Hygiene::new(db, src.file_id);
44 Attr::from_attrs_owner(&src.value, &hygiene)
45 }
46 AttrDefId::StructFieldId(it) => {
47 let src = it.parent.child_source(db);
48 match &src.value[it.local_id] {
49 Either::A(_tuple) => Attrs::default(),
50 Either::B(record) => {
51 let hygiene = Hygiene::new(db, src.file_id);
52 Attr::from_attrs_owner(record, &hygiene)
53 }
54 }
55 }
56 AttrDefId::EnumVariantId(it) => {
57 let src = it.parent.child_source(db);
58 let hygiene = Hygiene::new(db, src.file_id);
59 Attr::from_attrs_owner(&src.value[it.local_id], &hygiene)
60 }
61 AttrDefId::AdtId(it) => match it {
62 AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db),
63 AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
64 AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db),
65 },
66 AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
67 AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
68 AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db),
69 AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
70 AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db),
71 AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db),
72 AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db),
73 }
74 }
75
33 pub fn has_atom(&self, atom: &str) -> bool { 76 pub fn has_atom(&self, atom: &str) -> bool {
34 self.iter().any(|it| it.is_simple_atom(atom)) 77 self.iter().any(|it| it.is_simple_atom(atom))
35 } 78 }
79
80 pub fn find_string_value(&self, key: &str) -> Option<SmolStr> {
81 self.iter().filter(|attr| attr.is_simple_atom(key)).find_map(|attr| {
82 match attr.input.as_ref()? {
83 AttrInput::Literal(it) => Some(it.clone()),
84 _ => None,
85 }
86 })
87 }
36} 88}
37 89
38#[derive(Debug, Clone, PartialEq, Eq)] 90#[derive(Debug, Clone, PartialEq, Eq)]
@@ -106,3 +158,23 @@ impl Attr {
106 cfg_options.is_cfg_enabled(self.as_cfg()?) 158 cfg_options.is_cfg_enabled(self.as_cfg()?)
107 } 159 }
108} 160}
161
162fn attrs_from_ast<D, N>(src: AstId<N>, db: &D) -> Attrs
163where
164 N: ast::AttrsOwner,
165 D: DefDatabase,
166{
167 let hygiene = Hygiene::new(db, src.file_id());
168 Attr::from_attrs_owner(&src.to_node(db), &hygiene)
169}
170
171fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs
172where
173 T: HasSource,
174 T::Value: ast::AttrsOwner,
175 D: DefDatabase,
176{
177 let src = node.source(db);
178 let hygiene = Hygiene::new(db, src.file_id);
179 Attr::from_attrs_owner(&src.value, &hygiene)
180}
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index dfb79a30a..225638b42 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -13,7 +13,7 @@ use ra_syntax::{ast, AstNode, AstPtr};
13use rustc_hash::FxHashMap; 13use rustc_hash::FxHashMap;
14 14
15use crate::{ 15use crate::{
16 db::DefDatabase2, 16 db::DefDatabase,
17 expr::{Expr, ExprId, Pat, PatId}, 17 expr::{Expr, ExprId, Pat, PatId},
18 nameres::CrateDefMap, 18 nameres::CrateDefMap,
19 path::Path, 19 path::Path,
@@ -28,7 +28,7 @@ pub struct Expander {
28} 28}
29 29
30impl Expander { 30impl Expander {
31 pub fn new(db: &impl DefDatabase2, current_file_id: HirFileId, module: ModuleId) -> Expander { 31 pub fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander {
32 let crate_def_map = db.crate_def_map(module.krate); 32 let crate_def_map = db.crate_def_map(module.krate);
33 let hygiene = Hygiene::new(db, current_file_id); 33 let hygiene = Hygiene::new(db, current_file_id);
34 Expander { crate_def_map, current_file_id, hygiene, module } 34 Expander { crate_def_map, current_file_id, hygiene, module }
@@ -36,7 +36,7 @@ impl Expander {
36 36
37 fn enter_expand( 37 fn enter_expand(
38 &mut self, 38 &mut self,
39 db: &impl DefDatabase2, 39 db: &impl DefDatabase,
40 macro_call: ast::MacroCall, 40 macro_call: ast::MacroCall,
41 ) -> Option<(Mark, ast::Expr)> { 41 ) -> Option<(Mark, ast::Expr)> {
42 let ast_id = AstId::new( 42 let ast_id = AstId::new(
@@ -67,7 +67,7 @@ impl Expander {
67 None 67 None
68 } 68 }
69 69
70 fn exit(&mut self, db: &impl DefDatabase2, mark: Mark) { 70 fn exit(&mut self, db: &impl DefDatabase, mark: Mark) {
71 self.hygiene = Hygiene::new(db, mark.file_id); 71 self.hygiene = Hygiene::new(db, mark.file_id);
72 self.current_file_id = mark.file_id; 72 self.current_file_id = mark.file_id;
73 std::mem::forget(mark); 73 std::mem::forget(mark);
@@ -81,7 +81,7 @@ impl Expander {
81 Path::from_src(path, &self.hygiene) 81 Path::from_src(path, &self.hygiene)
82 } 82 }
83 83
84 fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option<MacroDefId> { 84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
85 self.crate_def_map.resolve_path(db, self.module.module_id, path).0.get_macros() 85 self.crate_def_map.resolve_path(db, self.module.module_id, path).0.get_macros()
86 } 86 }
87} 87}
@@ -142,7 +142,7 @@ pub struct BodySourceMap {
142 142
143impl Body { 143impl Body {
144 pub(crate) fn body_with_source_map_query( 144 pub(crate) fn body_with_source_map_query(
145 db: &impl DefDatabase2, 145 db: &impl DefDatabase,
146 def: DefWithBodyId, 146 def: DefWithBodyId,
147 ) -> (Arc<Body>, Arc<BodySourceMap>) { 147 ) -> (Arc<Body>, Arc<BodySourceMap>) {
148 let mut params = None; 148 let mut params = None;
@@ -169,12 +169,12 @@ impl Body {
169 (Arc::new(body), Arc::new(source_map)) 169 (Arc::new(body), Arc::new(source_map))
170 } 170 }
171 171
172 pub(crate) fn body_query(db: &impl DefDatabase2, def: DefWithBodyId) -> Arc<Body> { 172 pub(crate) fn body_query(db: &impl DefDatabase, def: DefWithBodyId) -> Arc<Body> {
173 db.body_with_source_map(def).0 173 db.body_with_source_map(def).0
174 } 174 }
175 175
176 fn new( 176 fn new(
177 db: &impl DefDatabase2, 177 db: &impl DefDatabase,
178 expander: Expander, 178 expander: Expander,
179 params: Option<ast::ParamList>, 179 params: Option<ast::ParamList>,
180 body: Option<ast::Expr>, 180 body: Option<ast::Expr>,
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index d8e911aa5..f4640dfa4 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -17,7 +17,7 @@ use test_utils::tested_by;
17use crate::{ 17use crate::{
18 body::{Body, BodySourceMap, Expander, PatPtr}, 18 body::{Body, BodySourceMap, Expander, PatPtr},
19 builtin_type::{BuiltinFloat, BuiltinInt}, 19 builtin_type::{BuiltinFloat, BuiltinInt},
20 db::DefDatabase2, 20 db::DefDatabase,
21 expr::{ 21 expr::{
22 ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, 22 ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
23 MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, 23 MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
@@ -28,7 +28,7 @@ use crate::{
28}; 28};
29 29
30pub(super) fn lower( 30pub(super) fn lower(
31 db: &impl DefDatabase2, 31 db: &impl DefDatabase,
32 expander: Expander, 32 expander: Expander,
33 params: Option<ast::ParamList>, 33 params: Option<ast::ParamList>,
34 body: Option<ast::Expr>, 34 body: Option<ast::Expr>,
@@ -57,7 +57,7 @@ struct ExprCollector<DB> {
57 57
58impl<'a, DB> ExprCollector<&'a DB> 58impl<'a, DB> ExprCollector<&'a DB>
59where 59where
60 DB: DefDatabase2, 60 DB: DefDatabase,
61{ 61{
62 fn collect( 62 fn collect(
63 mut self, 63 mut self,
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 58740b679..20d707bc4 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -7,7 +7,7 @@ use rustc_hash::FxHashMap;
7 7
8use crate::{ 8use crate::{
9 body::Body, 9 body::Body,
10 db::DefDatabase2, 10 db::DefDatabase,
11 expr::{Expr, ExprId, Pat, PatId, Statement}, 11 expr::{Expr, ExprId, Pat, PatId, Statement},
12 DefWithBodyId, 12 DefWithBodyId,
13}; 13};
@@ -45,7 +45,7 @@ pub struct ScopeData {
45} 45}
46 46
47impl ExprScopes { 47impl ExprScopes {
48 pub(crate) fn expr_scopes_query(db: &impl DefDatabase2, def: DefWithBodyId) -> Arc<ExprScopes> { 48 pub(crate) fn expr_scopes_query(db: &impl DefDatabase, def: DefWithBodyId) -> Arc<ExprScopes> {
49 let body = db.body(def); 49 let body = db.body(def);
50 Arc::new(ExprScopes::new(&*body)) 50 Arc::new(ExprScopes::new(&*body))
51 } 51 }
@@ -176,7 +176,7 @@ mod tests {
176 use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 176 use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
177 use test_utils::{assert_eq_text, covers, extract_offset}; 177 use test_utils::{assert_eq_text, covers, extract_offset};
178 178
179 use crate::{db::DefDatabase2, test_db::TestDB, FunctionId, ModuleDefId}; 179 use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId};
180 180
181 fn find_function(db: &TestDB, file_id: FileId) -> FunctionId { 181 fn find_function(db: &TestDB, file_id: FileId) -> FunctionId {
182 let krate = db.test_crate(); 182 let krate = db.test_crate();
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 91bac7415..f0b3e198a 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -9,7 +9,7 @@ use hir_expand::{
9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase2, 12 db::DefDatabase,
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, HasSource, 14 AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, HasSource,
15 ImplId, Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, 15 ImplId, Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
@@ -26,7 +26,7 @@ pub struct FunctionData {
26} 26}
27 27
28impl FunctionData { 28impl FunctionData {
29 pub(crate) fn fn_data_query(db: &impl DefDatabase2, func: FunctionId) -> Arc<FunctionData> { 29 pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> {
30 let src = func.lookup(db).source(db); 30 let src = func.lookup(db).source(db);
31 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); 31 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
32 let mut params = Vec::new(); 32 let mut params = Vec::new();
@@ -74,7 +74,7 @@ pub struct TypeAliasData {
74 74
75impl TypeAliasData { 75impl TypeAliasData {
76 pub(crate) fn type_alias_data_query( 76 pub(crate) fn type_alias_data_query(
77 db: &impl DefDatabase2, 77 db: &impl DefDatabase,
78 typ: TypeAliasId, 78 typ: TypeAliasId,
79 ) -> Arc<TypeAliasData> { 79 ) -> Arc<TypeAliasData> {
80 let node = typ.lookup(db).source(db).value; 80 let node = typ.lookup(db).source(db).value;
@@ -92,7 +92,7 @@ pub struct TraitData {
92} 92}
93 93
94impl TraitData { 94impl TraitData {
95 pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> { 95 pub(crate) fn trait_data_query(db: &impl DefDatabase, tr: TraitId) -> Arc<TraitData> {
96 let src = tr.source(db); 96 let src = tr.source(db);
97 let name = src.value.name().map(|n| n.as_name()); 97 let name = src.value.name().map(|n| n.as_name());
98 let auto = src.value.is_auto(); 98 let auto = src.value.is_auto();
@@ -144,7 +144,7 @@ pub struct ImplData {
144} 144}
145 145
146impl ImplData { 146impl ImplData {
147 pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc<ImplData> { 147 pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> {
148 let src = id.source(db); 148 let src = id.source(db);
149 let items = db.ast_id_map(src.file_id); 149 let items = db.ast_id_map(src.file_id);
150 150
@@ -198,12 +198,12 @@ pub struct ConstData {
198} 198}
199 199
200impl ConstData { 200impl ConstData {
201 pub(crate) fn const_data_query(db: &impl DefDatabase2, konst: ConstId) -> Arc<ConstData> { 201 pub(crate) fn const_data_query(db: &impl DefDatabase, konst: ConstId) -> Arc<ConstData> {
202 let node = konst.lookup(db).source(db).value; 202 let node = konst.lookup(db).source(db).value;
203 const_data_for(&node) 203 const_data_for(&node)
204 } 204 }
205 205
206 pub(crate) fn static_data_query(db: &impl DefDatabase2, konst: StaticId) -> Arc<ConstData> { 206 pub(crate) fn static_data_query(db: &impl DefDatabase, konst: StaticId) -> Arc<ConstData> {
207 let node = konst.source(db).value; 207 let node = konst.source(db).value;
208 const_data_for(&node) 208 const_data_for(&node)
209 } 209 }
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 2c660ab88..7fec2e8c0 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -3,43 +3,46 @@ use std::sync::Arc;
3 3
4use hir_expand::{db::AstDatabase, HirFileId}; 4use hir_expand::{db::AstDatabase, HirFileId};
5use ra_db::{salsa, CrateId, SourceDatabase}; 5use ra_db::{salsa, CrateId, SourceDatabase};
6use ra_syntax::ast; 6use ra_syntax::{ast, SmolStr};
7 7
8use crate::{ 8use crate::{
9 adt::{EnumData, StructData}, 9 adt::{EnumData, StructData},
10 attr::Attrs,
10 body::{scope::ExprScopes, Body, BodySourceMap}, 11 body::{scope::ExprScopes, Body, BodySourceMap},
11 data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData}, 12 data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData},
13 docs::Documentation,
12 generics::GenericParams, 14 generics::GenericParams,
15 lang_item::{LangItemTarget, LangItems},
13 nameres::{ 16 nameres::{
14 raw::{ImportSourceMap, RawItems}, 17 raw::{ImportSourceMap, RawItems},
15 CrateDefMap, 18 CrateDefMap,
16 }, 19 },
17 ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId, 20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId,
18 StructOrUnionId, TraitId, TypeAliasId, 21 ImplId, ItemLoc, ModuleId, StaticId, StructOrUnionId, TraitId, TypeAliasId, TypeAliasLoc,
19}; 22};
20 23
21#[salsa::query_group(InternDatabaseStorage)] 24#[salsa::query_group(InternDatabaseStorage)]
22pub trait InternDatabase: SourceDatabase { 25pub trait InternDatabase: SourceDatabase {
23 #[salsa::interned] 26 #[salsa::interned]
24 fn intern_function(&self, loc: crate::FunctionLoc) -> crate::FunctionId; 27 fn intern_function(&self, loc: FunctionLoc) -> FunctionId;
25 #[salsa::interned] 28 #[salsa::interned]
26 fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId; 29 fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> StructOrUnionId;
27 #[salsa::interned] 30 #[salsa::interned]
28 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId; 31 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId;
29 #[salsa::interned] 32 #[salsa::interned]
30 fn intern_const(&self, loc: crate::ConstLoc) -> crate::ConstId; 33 fn intern_const(&self, loc: ConstLoc) -> ConstId;
31 #[salsa::interned] 34 #[salsa::interned]
32 fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId; 35 fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> StaticId;
33 #[salsa::interned] 36 #[salsa::interned]
34 fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId; 37 fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> TraitId;
35 #[salsa::interned] 38 #[salsa::interned]
36 fn intern_type_alias(&self, loc: crate::TypeAliasLoc) -> crate::TypeAliasId; 39 fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId;
37 #[salsa::interned] 40 #[salsa::interned]
38 fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId; 41 fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> ImplId;
39} 42}
40 43
41#[salsa::query_group(DefDatabase2Storage)] 44#[salsa::query_group(DefDatabaseStorage)]
42pub trait DefDatabase2: InternDatabase + AstDatabase { 45pub trait DefDatabase: InternDatabase + AstDatabase {
43 #[salsa::invoke(RawItems::raw_items_with_source_map_query)] 46 #[salsa::invoke(RawItems::raw_items_with_source_map_query)]
44 fn raw_items_with_source_map( 47 fn raw_items_with_source_map(
45 &self, 48 &self,
@@ -87,4 +90,21 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
87 90
88 #[salsa::invoke(GenericParams::generic_params_query)] 91 #[salsa::invoke(GenericParams::generic_params_query)]
89 fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; 92 fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
93
94 #[salsa::invoke(Attrs::attrs_query)]
95 fn attrs(&self, def: AttrDefId) -> Attrs;
96
97 #[salsa::invoke(LangItems::module_lang_items_query)]
98 fn module_lang_items(&self, module: ModuleId) -> Option<Arc<LangItems>>;
99
100 #[salsa::invoke(LangItems::crate_lang_items_query)]
101 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
102
103 #[salsa::invoke(LangItems::lang_item_query)]
104 fn lang_item(&self, start_crate: CrateId, item: SmolStr) -> Option<LangItemTarget>;
105
106 // FIXME(https://github.com/rust-analyzer/rust-analyzer/issues/2148#issuecomment-550519102)
107 // Remove this query completely, in favor of `Attrs::docs` method
108 #[salsa::invoke(Documentation::documentation_query)]
109 fn documentation(&self, def: AttrDefId) -> Option<Documentation>;
90} 110}
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
new file mode 100644
index 000000000..69846fd1b
--- /dev/null
+++ b/crates/ra_hir_def/src/docs.rs
@@ -0,0 +1,68 @@
1//! FIXME: write short doc here
2
3use std::sync::Arc;
4
5use hir_expand::either::Either;
6use ra_syntax::ast;
7
8use crate::{db::DefDatabase, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup};
9
10/// Holds documentation
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Documentation(Arc<str>);
13
14impl Into<String> for Documentation {
15 fn into(self) -> String {
16 self.as_str().to_owned()
17 }
18}
19
20impl Documentation {
21 fn new(s: &str) -> Documentation {
22 Documentation(s.into())
23 }
24
25 pub fn as_str(&self) -> &str {
26 &*self.0
27 }
28
29 pub(crate) fn documentation_query(
30 db: &impl DefDatabase,
31 def: AttrDefId,
32 ) -> Option<Documentation> {
33 match def {
34 AttrDefId::ModuleId(module) => {
35 let def_map = db.crate_def_map(module.krate);
36 let src = def_map[module.module_id].declaration_source(db)?;
37 docs_from_ast(&src.value)
38 }
39 AttrDefId::StructFieldId(it) => {
40 let src = it.parent.child_source(db);
41 match &src.value[it.local_id] {
42 Either::A(_tuple) => None,
43 Either::B(record) => docs_from_ast(record),
44 }
45 }
46 AttrDefId::AdtId(it) => match it {
47 AdtId::StructId(it) => docs_from_ast(&it.0.source(db).value),
48 AdtId::EnumId(it) => docs_from_ast(&it.source(db).value),
49 AdtId::UnionId(it) => docs_from_ast(&it.0.source(db).value),
50 },
51 AttrDefId::EnumVariantId(it) => {
52 let src = it.parent.child_source(db);
53 docs_from_ast(&src.value[it.local_id])
54 }
55 AttrDefId::StaticId(it) => docs_from_ast(&it.source(db).value),
56 AttrDefId::TraitId(it) => docs_from_ast(&it.source(db).value),
57 AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id.to_node(db)),
58 AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value),
59 AttrDefId::FunctionId(it) => docs_from_ast(&it.lookup(db).source(db).value),
60 AttrDefId::TypeAliasId(it) => docs_from_ast(&it.lookup(db).source(db).value),
61 AttrDefId::ImplId(_) => None,
62 }
63 }
64}
65
66pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> {
67 node.doc_comment_text().map(|it| Documentation::new(&it))
68}
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 9e2e4c3cc..015fe772e 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -8,7 +8,7 @@ use hir_expand::name::{self, AsName, Name};
8use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; 8use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
9 9
10use crate::{ 10use crate::{
11 db::DefDatabase2, 11 db::DefDatabase,
12 type_ref::{TypeBound, TypeRef}, 12 type_ref::{TypeBound, TypeRef},
13 AdtId, AstItemDef, ContainerId, GenericDefId, HasSource, Lookup, 13 AdtId, AstItemDef, ContainerId, GenericDefId, HasSource, Lookup,
14}; 14};
@@ -42,7 +42,7 @@ pub struct WherePredicate {
42 42
43impl GenericParams { 43impl GenericParams {
44 pub(crate) fn generic_params_query( 44 pub(crate) fn generic_params_query(
45 db: &impl DefDatabase2, 45 db: &impl DefDatabase,
46 def: GenericDefId, 46 def: GenericDefId,
47 ) -> Arc<GenericParams> { 47 ) -> Arc<GenericParams> {
48 let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it)); 48 let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it));
@@ -50,7 +50,7 @@ impl GenericParams {
50 } 50 }
51 51
52 fn new( 52 fn new(
53 db: &impl DefDatabase2, 53 db: &impl DefDatabase,
54 def: GenericDefId, 54 def: GenericDefId,
55 parent_params: Option<Arc<GenericParams>>, 55 parent_params: Option<Arc<GenericParams>>,
56 ) -> GenericParams { 56 ) -> GenericParams {
@@ -168,7 +168,7 @@ impl GenericParams {
168 } 168 }
169} 169}
170 170
171fn parent_generic_def(db: &impl DefDatabase2, def: GenericDefId) -> Option<GenericDefId> { 171fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option<GenericDefId> {
172 let container = match def { 172 let container = match def {
173 GenericDefId::FunctionId(it) => it.lookup(db).container, 173 GenericDefId::FunctionId(it) => it.lookup(db).container,
174 GenericDefId::TypeAliasId(it) => it.lookup(db).container, 174 GenericDefId::TypeAliasId(it) => it.lookup(db).container,
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
new file mode 100644
index 000000000..df951c533
--- /dev/null
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -0,0 +1,120 @@
1//! Collects lang items: items marked with `#[lang = "..."]` attribute.
2//!
3//! This attribute to tell the compiler about semi built-in std library
4//! features, such as Fn family of traits.
5use std::sync::Arc;
6
7use ra_syntax::SmolStr;
8use rustc_hash::FxHashMap;
9
10use crate::{
11 db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, ModuleId,
12 StaticId, StructId, TraitId,
13};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub enum LangItemTarget {
17 EnumId(EnumId),
18 FunctionId(FunctionId),
19 ImplBlockId(ImplId),
20 StaticId(StaticId),
21 StructId(StructId),
22 TraitId(TraitId),
23}
24
25#[derive(Default, Debug, Clone, PartialEq, Eq)]
26pub struct LangItems {
27 items: FxHashMap<SmolStr, LangItemTarget>,
28}
29
30impl LangItems {
31 pub fn target<'a>(&'a self, item: &str) -> Option<&'a LangItemTarget> {
32 self.items.get(item)
33 }
34
35 /// Salsa query. This will look for lang items in a specific crate.
36 pub(crate) fn crate_lang_items_query(db: &impl DefDatabase, krate: CrateId) -> Arc<LangItems> {
37 let mut lang_items = LangItems::default();
38
39 let crate_def_map = db.crate_def_map(krate);
40
41 crate_def_map
42 .modules()
43 .filter_map(|module_id| db.module_lang_items(ModuleId { krate, module_id }))
44 .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v))));
45
46 Arc::new(lang_items)
47 }
48
49 pub(crate) fn module_lang_items_query(
50 db: &impl DefDatabase,
51 module: ModuleId,
52 ) -> Option<Arc<LangItems>> {
53 let mut lang_items = LangItems::default();
54 lang_items.collect_lang_items(db, module);
55 if lang_items.items.is_empty() {
56 None
57 } else {
58 Some(Arc::new(lang_items))
59 }
60 }
61
62 /// Salsa query. Look for a lang item, starting from the specified crate and recursively
63 /// traversing its dependencies.
64 pub(crate) fn lang_item_query(
65 db: &impl DefDatabase,
66 start_crate: CrateId,
67 item: SmolStr,
68 ) -> Option<LangItemTarget> {
69 let lang_items = db.crate_lang_items(start_crate);
70 let start_crate_target = lang_items.items.get(&item);
71 if let Some(target) = start_crate_target {
72 return Some(*target);
73 }
74 db.crate_graph()
75 .dependencies(start_crate)
76 .find_map(|dep| db.lang_item(dep.crate_id, item.clone()))
77 }
78
79 fn collect_lang_items(&mut self, db: &impl DefDatabase, module: ModuleId) {
80 // Look for impl targets
81 let def_map = db.crate_def_map(module.krate);
82 let module_data = &def_map[module.module_id];
83 for &impl_block in module_data.impls.iter() {
84 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId)
85 }
86
87 for def in module_data.scope.declarations() {
88 match def {
89 ModuleDefId::TraitId(trait_) => {
90 self.collect_lang_item(db, trait_, LangItemTarget::TraitId)
91 }
92 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
93 self.collect_lang_item(db, e, LangItemTarget::EnumId)
94 }
95 ModuleDefId::AdtId(AdtId::StructId(s)) => {
96 self.collect_lang_item(db, s, LangItemTarget::StructId)
97 }
98 ModuleDefId::FunctionId(f) => {
99 self.collect_lang_item(db, f, LangItemTarget::FunctionId)
100 }
101 ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::StaticId),
102 _ => {}
103 }
104 }
105 }
106
107 fn collect_lang_item<T>(
108 &mut self,
109 db: &impl DefDatabase,
110 item: T,
111 constructor: fn(T) -> LangItemTarget,
112 ) where
113 T: Into<AttrDefId> + Copy,
114 {
115 let attrs = db.attrs(item.into());
116 if let Some(lang_item_name) = attrs.find_string_value("lang") {
117 self.items.entry(lang_item_name).or_insert_with(|| constructor(item));
118 }
119 }
120}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 3a0420da0..1d195d65d 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -19,96 +19,42 @@ pub mod body;
19pub mod generics; 19pub mod generics;
20pub mod resolver; 20pub mod resolver;
21pub mod data; 21pub mod data;
22pub mod lang_item;
23pub mod docs;
24pub mod per_ns;
25
26mod trace;
27mod nameres;
22 28
23#[cfg(test)] 29#[cfg(test)]
24mod test_db; 30mod test_db;
25#[cfg(test)] 31#[cfg(test)]
26mod marks; 32mod marks;
27 33
28// FIXME: this should be private
29pub mod nameres;
30
31use std::hash::{Hash, Hasher}; 34use std::hash::{Hash, Hasher};
32 35
33use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, Source}; 36use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source};
34use ra_arena::{impl_arena_id, RawId}; 37use ra_arena::{impl_arena_id, map::ArenaMap, RawId};
35use ra_db::{salsa, CrateId, FileId}; 38use ra_db::{salsa, CrateId};
36use ra_syntax::{ast, AstNode, SyntaxNode}; 39use ra_syntax::{ast, AstNode};
37 40
38use crate::{builtin_type::BuiltinType, db::InternDatabase}; 41use crate::{builtin_type::BuiltinType, db::InternDatabase};
39 42
40pub enum ModuleSource { 43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
41 SourceFile(ast::SourceFile), 44pub struct LocalImportId(RawId);
42 Module(ast::Module), 45impl_arena_id!(LocalImportId);
43}
44
45impl ModuleSource {
46 pub fn new(
47 db: &impl db::DefDatabase2,
48 file_id: Option<FileId>,
49 decl_id: Option<AstId<ast::Module>>,
50 ) -> ModuleSource {
51 match (file_id, decl_id) {
52 (Some(file_id), _) => {
53 let source_file = db.parse(file_id).tree();
54 ModuleSource::SourceFile(source_file)
55 }
56 (None, Some(item_id)) => {
57 let module = item_id.to_node(db);
58 assert!(module.item_list().is_some(), "expected inline module");
59 ModuleSource::Module(module)
60 }
61 (None, None) => panic!(),
62 }
63 }
64
65 // FIXME: this methods do not belong here
66 pub fn from_position(
67 db: &impl db::DefDatabase2,
68 position: ra_db::FilePosition,
69 ) -> ModuleSource {
70 let parse = db.parse(position.file_id);
71 match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
72 parse.tree().syntax(),
73 position.offset,
74 ) {
75 Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
76 _ => {
77 let source_file = parse.tree();
78 ModuleSource::SourceFile(source_file)
79 }
80 }
81 }
82
83 pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource {
84 if let Some(m) =
85 child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
86 {
87 ModuleSource::Module(m)
88 } else {
89 let file_id = child.file_id.original_file(db);
90 let source_file = db.parse(file_id).tree();
91 ModuleSource::SourceFile(source_file)
92 }
93 }
94
95 pub fn from_file_id(db: &impl db::DefDatabase2, file_id: FileId) -> ModuleSource {
96 let source_file = db.parse(file_id).tree();
97 ModuleSource::SourceFile(source_file)
98 }
99}
100 46
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
102pub struct ModuleId { 48pub struct ModuleId {
103 pub krate: CrateId, 49 pub krate: CrateId,
104 pub module_id: CrateModuleId, 50 pub module_id: LocalModuleId,
105} 51}
106 52
107/// An ID of a module, **local** to a specific crate 53/// An ID of a module, **local** to a specific crate
108// FIXME: rename to `LocalModuleId`. 54// FIXME: rename to `LocalModuleId`.
109#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 55#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
110pub struct CrateModuleId(RawId); 56pub struct LocalModuleId(RawId);
111impl_arena_id!(CrateModuleId); 57impl_arena_id!(LocalModuleId);
112 58
113macro_rules! impl_intern_key { 59macro_rules! impl_intern_key {
114 ($name:ident) => { 60 ($name:ident) => {
@@ -207,14 +153,14 @@ pub struct FunctionLoc {
207 153
208impl Intern for FunctionLoc { 154impl Intern for FunctionLoc {
209 type ID = FunctionId; 155 type ID = FunctionId;
210 fn intern(self, db: &impl db::DefDatabase2) -> FunctionId { 156 fn intern(self, db: &impl db::DefDatabase) -> FunctionId {
211 db.intern_function(self) 157 db.intern_function(self)
212 } 158 }
213} 159}
214 160
215impl Lookup for FunctionId { 161impl Lookup for FunctionId {
216 type Data = FunctionLoc; 162 type Data = FunctionLoc;
217 fn lookup(&self, db: &impl db::DefDatabase2) -> FunctionLoc { 163 fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc {
218 db.lookup_intern_function(*self) 164 db.lookup_intern_function(*self)
219 } 165 }
220} 166}
@@ -278,8 +224,8 @@ pub enum VariantId {
278 224
279#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 225#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
280pub struct StructFieldId { 226pub struct StructFieldId {
281 parent: VariantId, 227 pub parent: VariantId,
282 local_id: LocalStructFieldId, 228 pub local_id: LocalStructFieldId,
283} 229}
284 230
285#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 231#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -297,14 +243,14 @@ pub struct ConstLoc {
297 243
298impl Intern for ConstLoc { 244impl Intern for ConstLoc {
299 type ID = ConstId; 245 type ID = ConstId;
300 fn intern(self, db: &impl db::DefDatabase2) -> ConstId { 246 fn intern(self, db: &impl db::DefDatabase) -> ConstId {
301 db.intern_const(self) 247 db.intern_const(self)
302 } 248 }
303} 249}
304 250
305impl Lookup for ConstId { 251impl Lookup for ConstId {
306 type Data = ConstLoc; 252 type Data = ConstLoc;
307 fn lookup(&self, db: &impl db::DefDatabase2) -> ConstLoc { 253 fn lookup(&self, db: &impl db::DefDatabase) -> ConstLoc {
308 db.lookup_intern_const(*self) 254 db.lookup_intern_const(*self)
309 } 255 }
310} 256}
@@ -345,14 +291,14 @@ pub struct TypeAliasLoc {
345 291
346impl Intern for TypeAliasLoc { 292impl Intern for TypeAliasLoc {
347 type ID = TypeAliasId; 293 type ID = TypeAliasId;
348 fn intern(self, db: &impl db::DefDatabase2) -> TypeAliasId { 294 fn intern(self, db: &impl db::DefDatabase) -> TypeAliasId {
349 db.intern_type_alias(self) 295 db.intern_type_alias(self)
350 } 296 }
351} 297}
352 298
353impl Lookup for TypeAliasId { 299impl Lookup for TypeAliasId {
354 type Data = TypeAliasLoc; 300 type Data = TypeAliasLoc;
355 fn lookup(&self, db: &impl db::DefDatabase2) -> TypeAliasLoc { 301 fn lookup(&self, db: &impl db::DefDatabase) -> TypeAliasLoc {
356 db.lookup_intern_type_alias(*self) 302 db.lookup_intern_type_alias(*self)
357 } 303 }
358} 304}
@@ -475,22 +421,51 @@ impl_froms!(
475 ConstId 421 ConstId
476); 422);
477 423
424#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
425pub enum AttrDefId {
426 ModuleId(ModuleId),
427 StructFieldId(StructFieldId),
428 AdtId(AdtId),
429 FunctionId(FunctionId),
430 EnumVariantId(EnumVariantId),
431 StaticId(StaticId),
432 ConstId(ConstId),
433 TraitId(TraitId),
434 TypeAliasId(TypeAliasId),
435 MacroDefId(MacroDefId),
436 ImplId(ImplId),
437}
438
439impl_froms!(
440 AttrDefId: ModuleId,
441 StructFieldId,
442 AdtId(StructId, EnumId, UnionId),
443 EnumVariantId,
444 StaticId,
445 ConstId,
446 FunctionId,
447 TraitId,
448 TypeAliasId,
449 MacroDefId,
450 ImplId
451);
452
478trait Intern { 453trait Intern {
479 type ID; 454 type ID;
480 fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; 455 fn intern(self, db: &impl db::DefDatabase) -> Self::ID;
481} 456}
482 457
483pub trait Lookup { 458pub trait Lookup {
484 type Data; 459 type Data;
485 fn lookup(&self, db: &impl db::DefDatabase2) -> Self::Data; 460 fn lookup(&self, db: &impl db::DefDatabase) -> Self::Data;
486} 461}
487 462
488pub trait HasModule { 463pub trait HasModule {
489 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId; 464 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
490} 465}
491 466
492impl HasModule for FunctionLoc { 467impl HasModule for FunctionLoc {
493 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { 468 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
494 match self.container { 469 match self.container {
495 ContainerId::ModuleId(it) => it, 470 ContainerId::ModuleId(it) => it,
496 ContainerId::ImplId(it) => it.module(db), 471 ContainerId::ImplId(it) => it.module(db),
@@ -500,7 +475,7 @@ impl HasModule for FunctionLoc {
500} 475}
501 476
502impl HasModule for TypeAliasLoc { 477impl HasModule for TypeAliasLoc {
503 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { 478 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
504 match self.container { 479 match self.container {
505 ContainerId::ModuleId(it) => it, 480 ContainerId::ModuleId(it) => it,
506 ContainerId::ImplId(it) => it.module(db), 481 ContainerId::ImplId(it) => it.module(db),
@@ -510,7 +485,7 @@ impl HasModule for TypeAliasLoc {
510} 485}
511 486
512impl HasModule for ConstLoc { 487impl HasModule for ConstLoc {
513 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { 488 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
514 match self.container { 489 match self.container {
515 ContainerId::ModuleId(it) => it, 490 ContainerId::ModuleId(it) => it,
516 ContainerId::ImplId(it) => it.module(db), 491 ContainerId::ImplId(it) => it.module(db),
@@ -521,13 +496,13 @@ impl HasModule for ConstLoc {
521 496
522pub trait HasSource { 497pub trait HasSource {
523 type Value; 498 type Value;
524 fn source(&self, db: &impl db::DefDatabase2) -> Source<Self::Value>; 499 fn source(&self, db: &impl db::DefDatabase) -> Source<Self::Value>;
525} 500}
526 501
527impl HasSource for FunctionLoc { 502impl HasSource for FunctionLoc {
528 type Value = ast::FnDef; 503 type Value = ast::FnDef;
529 504
530 fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::FnDef> { 505 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::FnDef> {
531 let node = self.ast_id.to_node(db); 506 let node = self.ast_id.to_node(db);
532 Source::new(self.ast_id.file_id(), node) 507 Source::new(self.ast_id.file_id(), node)
533 } 508 }
@@ -536,7 +511,7 @@ impl HasSource for FunctionLoc {
536impl HasSource for TypeAliasLoc { 511impl HasSource for TypeAliasLoc {
537 type Value = ast::TypeAliasDef; 512 type Value = ast::TypeAliasDef;
538 513
539 fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::TypeAliasDef> { 514 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::TypeAliasDef> {
540 let node = self.ast_id.to_node(db); 515 let node = self.ast_id.to_node(db);
541 Source::new(self.ast_id.file_id(), node) 516 Source::new(self.ast_id.file_id(), node)
542 } 517 }
@@ -545,8 +520,17 @@ impl HasSource for TypeAliasLoc {
545impl HasSource for ConstLoc { 520impl HasSource for ConstLoc {
546 type Value = ast::ConstDef; 521 type Value = ast::ConstDef;
547 522
548 fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::ConstDef> { 523 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::ConstDef> {
549 let node = self.ast_id.to_node(db); 524 let node = self.ast_id.to_node(db);
550 Source::new(self.ast_id.file_id(), node) 525 Source::new(self.ast_id.file_id(), node)
551 } 526 }
552} 527}
528
529pub trait HasChildSource {
530 type ChildId;
531 type Value;
532 fn child_source(
533 &self,
534 db: &impl db::DefDatabase,
535 ) -> Source<ArenaMap<Self::ChildId, Self::Value>>;
536}
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index c01e020ef..3b2e99647 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -47,8 +47,7 @@
47//! path and, upon success, we run macro expansion and "collect module" phase on 47//! path and, upon success, we run macro expansion and "collect module" phase on
48//! the result 48//! the result
49 49
50pub mod raw; 50pub(crate) mod raw;
51pub mod per_ns;
52mod collector; 51mod collector;
53mod mod_resolution; 52mod mod_resolution;
54mod path_resolution; 53mod path_resolution;
@@ -58,7 +57,10 @@ mod tests;
58 57
59use std::sync::Arc; 58use std::sync::Arc;
60 59
61use hir_expand::{ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, MacroDefId}; 60use hir_expand::{
61 ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId,
62 Source,
63};
62use once_cell::sync::Lazy; 64use once_cell::sync::Lazy;
63use ra_arena::Arena; 65use ra_arena::Arena;
64use ra_db::{CrateId, Edition, FileId}; 66use ra_db::{CrateId, Edition, FileId};
@@ -68,12 +70,11 @@ use rustc_hash::{FxHashMap, FxHashSet};
68 70
69use crate::{ 71use crate::{
70 builtin_type::BuiltinType, 72 builtin_type::BuiltinType,
71 db::DefDatabase2, 73 db::DefDatabase,
72 nameres::{ 74 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
73 diagnostics::DefDiagnostic, path_resolution::ResolveMode, per_ns::PerNs, raw::ImportId,
74 },
75 path::Path, 75 path::Path,
76 AstId, CrateModuleId, FunctionId, ImplId, ModuleDefId, ModuleId, TraitId, 76 per_ns::PerNs,
77 AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId,
77}; 78};
78 79
79/// Contains all top-level defs from a macro-expanded crate 80/// Contains all top-level defs from a macro-expanded crate
@@ -86,8 +87,8 @@ pub struct CrateDefMap {
86 /// a dependency (`std` or `core`). 87 /// a dependency (`std` or `core`).
87 prelude: Option<ModuleId>, 88 prelude: Option<ModuleId>,
88 extern_prelude: FxHashMap<Name, ModuleDefId>, 89 extern_prelude: FxHashMap<Name, ModuleDefId>,
89 root: CrateModuleId, 90 root: LocalModuleId,
90 modules: Arena<CrateModuleId, ModuleData>, 91 modules: Arena<LocalModuleId, ModuleData>,
91 92
92 /// Some macros are not well-behavior, which leads to infinite loop 93 /// Some macros are not well-behavior, which leads to infinite loop
93 /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } } 94 /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } }
@@ -104,24 +105,27 @@ pub struct CrateDefMap {
104 diagnostics: Vec<DefDiagnostic>, 105 diagnostics: Vec<DefDiagnostic>,
105} 106}
106 107
107impl std::ops::Index<CrateModuleId> for CrateDefMap { 108impl std::ops::Index<LocalModuleId> for CrateDefMap {
108 type Output = ModuleData; 109 type Output = ModuleData;
109 fn index(&self, id: CrateModuleId) -> &ModuleData { 110 fn index(&self, id: LocalModuleId) -> &ModuleData {
110 &self.modules[id] 111 &self.modules[id]
111 } 112 }
112} 113}
113 114
114#[derive(Default, Debug, PartialEq, Eq)] 115#[derive(Default, Debug, PartialEq, Eq)]
115pub struct ModuleData { 116pub struct ModuleData {
116 pub parent: Option<CrateModuleId>, 117 pub parent: Option<LocalModuleId>,
117 pub children: FxHashMap<Name, CrateModuleId>, 118 pub children: FxHashMap<Name, LocalModuleId>,
118 pub scope: ModuleScope, 119 pub scope: ModuleScope,
120
121 // FIXME: these can't be both null, we need a three-state enum here.
119 /// None for root 122 /// None for root
120 pub declaration: Option<AstId<ast::Module>>, 123 pub declaration: Option<AstId<ast::Module>>,
121 /// None for inline modules. 124 /// None for inline modules.
122 /// 125 ///
123 /// Note that non-inline modules, by definition, live inside non-macro file. 126 /// Note that non-inline modules, by definition, live inside non-macro file.
124 pub definition: Option<FileId>, 127 pub definition: Option<FileId>,
128
125 pub impls: Vec<ImplId>, 129 pub impls: Vec<ImplId>,
126} 130}
127 131
@@ -207,21 +211,21 @@ pub struct Resolution {
207 /// None for unresolved 211 /// None for unresolved
208 pub def: PerNs, 212 pub def: PerNs,
209 /// ident by which this is imported into local scope. 213 /// ident by which this is imported into local scope.
210 pub import: Option<ImportId>, 214 pub import: Option<LocalImportId>,
211} 215}
212 216
213impl CrateDefMap { 217impl CrateDefMap {
214 pub(crate) fn crate_def_map_query( 218 pub(crate) fn crate_def_map_query(
215 // Note that this doesn't have `+ AstDatabase`! 219 // Note that this doesn't have `+ AstDatabase`!
216 // This gurantess that `CrateDefMap` is stable across reparses. 220 // This gurantess that `CrateDefMap` is stable across reparses.
217 db: &impl DefDatabase2, 221 db: &impl DefDatabase,
218 krate: CrateId, 222 krate: CrateId,
219 ) -> Arc<CrateDefMap> { 223 ) -> Arc<CrateDefMap> {
220 let _p = profile("crate_def_map_query"); 224 let _p = profile("crate_def_map_query");
221 let def_map = { 225 let def_map = {
222 let crate_graph = db.crate_graph(); 226 let crate_graph = db.crate_graph();
223 let edition = crate_graph.edition(krate); 227 let edition = crate_graph.edition(krate);
224 let mut modules: Arena<CrateModuleId, ModuleData> = Arena::default(); 228 let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
225 let root = modules.alloc(ModuleData::default()); 229 let root = modules.alloc(ModuleData::default());
226 CrateDefMap { 230 CrateDefMap {
227 krate, 231 krate,
@@ -242,7 +246,7 @@ impl CrateDefMap {
242 self.krate 246 self.krate
243 } 247 }
244 248
245 pub fn root(&self) -> CrateModuleId { 249 pub fn root(&self) -> LocalModuleId {
246 self.root 250 self.root
247 } 251 }
248 252
@@ -256,8 +260,8 @@ impl CrateDefMap {
256 260
257 pub fn add_diagnostics( 261 pub fn add_diagnostics(
258 &self, 262 &self,
259 db: &impl DefDatabase2, 263 db: &impl DefDatabase,
260 module: CrateModuleId, 264 module: LocalModuleId,
261 sink: &mut DiagnosticSink, 265 sink: &mut DiagnosticSink,
262 ) { 266 ) {
263 self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) 267 self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink))
@@ -265,19 +269,19 @@ impl CrateDefMap {
265 269
266 pub fn resolve_path( 270 pub fn resolve_path(
267 &self, 271 &self,
268 db: &impl DefDatabase2, 272 db: &impl DefDatabase,
269 original_module: CrateModuleId, 273 original_module: LocalModuleId,
270 path: &Path, 274 path: &Path,
271 ) -> (PerNs, Option<usize>) { 275 ) -> (PerNs, Option<usize>) {
272 let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); 276 let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path);
273 (res.resolved_def, res.segment_index) 277 (res.resolved_def, res.segment_index)
274 } 278 }
275 279
276 pub fn modules(&self) -> impl Iterator<Item = CrateModuleId> + '_ { 280 pub fn modules(&self) -> impl Iterator<Item = LocalModuleId> + '_ {
277 self.modules.iter().map(|(id, _data)| id) 281 self.modules.iter().map(|(id, _data)| id)
278 } 282 }
279 283
280 pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = CrateModuleId> + '_ { 284 pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ {
281 self.modules 285 self.modules
282 .iter() 286 .iter()
283 .filter(move |(_id, data)| data.definition == Some(file_id)) 287 .filter(move |(_id, data)| data.definition == Some(file_id))
@@ -285,17 +289,40 @@ impl CrateDefMap {
285 } 289 }
286} 290}
287 291
292impl ModuleData {
293 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
294 pub fn definition_source(
295 &self,
296 db: &impl DefDatabase,
297 ) -> Source<Either<ast::SourceFile, ast::Module>> {
298 if let Some(file_id) = self.definition {
299 let sf = db.parse(file_id).tree();
300 return Source::new(file_id.into(), Either::A(sf));
301 }
302 let decl = self.declaration.unwrap();
303 Source::new(decl.file_id(), Either::B(decl.to_node(db)))
304 }
305
306 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
307 /// `None` for the crate root.
308 pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<Source<ast::Module>> {
309 let decl = self.declaration?;
310 let value = decl.to_node(db);
311 Some(Source { file_id: decl.file_id(), value })
312 }
313}
314
288mod diagnostics { 315mod diagnostics {
289 use hir_expand::diagnostics::DiagnosticSink; 316 use hir_expand::diagnostics::DiagnosticSink;
290 use ra_db::RelativePathBuf; 317 use ra_db::RelativePathBuf;
291 use ra_syntax::{ast, AstPtr}; 318 use ra_syntax::{ast, AstPtr};
292 319
293 use crate::{db::DefDatabase2, diagnostics::UnresolvedModule, nameres::CrateModuleId, AstId}; 320 use crate::{db::DefDatabase, diagnostics::UnresolvedModule, nameres::LocalModuleId, AstId};
294 321
295 #[derive(Debug, PartialEq, Eq)] 322 #[derive(Debug, PartialEq, Eq)]
296 pub(super) enum DefDiagnostic { 323 pub(super) enum DefDiagnostic {
297 UnresolvedModule { 324 UnresolvedModule {
298 module: CrateModuleId, 325 module: LocalModuleId,
299 declaration: AstId<ast::Module>, 326 declaration: AstId<ast::Module>,
300 candidate: RelativePathBuf, 327 candidate: RelativePathBuf,
301 }, 328 },
@@ -304,8 +331,8 @@ mod diagnostics {
304 impl DefDiagnostic { 331 impl DefDiagnostic {
305 pub(super) fn add_to( 332 pub(super) fn add_to(
306 &self, 333 &self,
307 db: &impl DefDatabase2, 334 db: &impl DefDatabase,
308 target_module: CrateModuleId, 335 target_module: LocalModuleId,
309 sink: &mut DiagnosticSink, 336 sink: &mut DiagnosticSink,
310 ) { 337 ) {
311 match self { 338 match self {
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 7902293e8..b02364e86 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -13,18 +13,19 @@ use test_utils::tested_by;
13 13
14use crate::{ 14use crate::{
15 attr::Attrs, 15 attr::Attrs,
16 db::DefDatabase2, 16 db::DefDatabase,
17 nameres::{ 17 nameres::{
18 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 18 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
19 per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, 19 raw, CrateDefMap, ModuleData, Resolution, ResolveMode,
20 }, 20 },
21 path::{Path, PathKind}, 21 path::{Path, PathKind},
22 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, CrateModuleId, EnumId, EnumVariantId, 22 per_ns::PerNs,
23 FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, 23 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId,
24 Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId,
24 StructOrUnionId, TraitId, TypeAliasLoc, UnionId, 25 StructOrUnionId, TraitId, TypeAliasLoc, UnionId,
25}; 26};
26 27
27pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { 28pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
28 let crate_graph = db.crate_graph(); 29 let crate_graph = db.crate_graph();
29 30
30 // populate external prelude 31 // populate external prelude
@@ -94,10 +95,10 @@ impl MacroStackMonitor {
94struct DefCollector<'a, DB> { 95struct DefCollector<'a, DB> {
95 db: &'a DB, 96 db: &'a DB,
96 def_map: CrateDefMap, 97 def_map: CrateDefMap,
97 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, 98 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>,
98 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, 99 unresolved_imports: Vec<(LocalModuleId, LocalImportId, raw::ImportData)>,
99 unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, 100 unexpanded_macros: Vec<(LocalModuleId, AstId<ast::MacroCall>, Path)>,
100 mod_dirs: FxHashMap<CrateModuleId, ModDir>, 101 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
101 102
102 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly 103 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly
103 /// To prevent stack overflow, we add a deep counter here for prevent that. 104 /// To prevent stack overflow, we add a deep counter here for prevent that.
@@ -108,7 +109,7 @@ struct DefCollector<'a, DB> {
108 109
109impl<DB> DefCollector<'_, DB> 110impl<DB> DefCollector<'_, DB>
110where 111where
111 DB: DefDatabase2, 112 DB: DefDatabase,
112{ 113{
113 fn collect(&mut self) { 114 fn collect(&mut self) {
114 let crate_graph = self.db.crate_graph(); 115 let crate_graph = self.db.crate_graph();
@@ -173,7 +174,7 @@ where
173 /// ``` 174 /// ```
174 fn define_macro( 175 fn define_macro(
175 &mut self, 176 &mut self,
176 module_id: CrateModuleId, 177 module_id: LocalModuleId,
177 name: Name, 178 name: Name,
178 macro_: MacroDefId, 179 macro_: MacroDefId,
179 export: bool, 180 export: bool,
@@ -200,7 +201,7 @@ where
200 /// the definition of current module. 201 /// the definition of current module.
201 /// And also, `macro_use` on a module will import all legacy macros visable inside to 202 /// And also, `macro_use` on a module will import all legacy macros visable inside to
202 /// current legacy scope, with possible shadowing. 203 /// current legacy scope, with possible shadowing.
203 fn define_legacy_macro(&mut self, module_id: CrateModuleId, name: Name, macro_: MacroDefId) { 204 fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, macro_: MacroDefId) {
204 // Always shadowing 205 // Always shadowing
205 self.def_map.modules[module_id].scope.legacy_macros.insert(name, macro_); 206 self.def_map.modules[module_id].scope.legacy_macros.insert(name, macro_);
206 } 207 }
@@ -208,7 +209,7 @@ where
208 /// Import macros from `#[macro_use] extern crate`. 209 /// Import macros from `#[macro_use] extern crate`.
209 fn import_macros_from_extern_crate( 210 fn import_macros_from_extern_crate(
210 &mut self, 211 &mut self,
211 current_module_id: CrateModuleId, 212 current_module_id: LocalModuleId,
212 import: &raw::ImportData, 213 import: &raw::ImportData,
213 ) { 214 ) {
214 log::debug!( 215 log::debug!(
@@ -235,7 +236,7 @@ where
235 /// Exported macros are just all macros in the root module scope. 236 /// Exported macros are just all macros in the root module scope.
236 /// Note that it contains not only all `#[macro_export]` macros, but also all aliases 237 /// Note that it contains not only all `#[macro_export]` macros, but also all aliases
237 /// created by `use` in the root module, ignoring the visibility of `use`. 238 /// created by `use` in the root module, ignoring the visibility of `use`.
238 fn import_all_macros_exported(&mut self, current_module_id: CrateModuleId, krate: CrateId) { 239 fn import_all_macros_exported(&mut self, current_module_id: LocalModuleId, krate: CrateId) {
239 let def_map = self.db.crate_def_map(krate); 240 let def_map = self.db.crate_def_map(krate);
240 for (name, def) in def_map[def_map.root].scope.macros() { 241 for (name, def) in def_map[def_map.root].scope.macros() {
241 // `macro_use` only bring things into legacy scope. 242 // `macro_use` only bring things into legacy scope.
@@ -265,7 +266,7 @@ where
265 266
266 fn resolve_import( 267 fn resolve_import(
267 &self, 268 &self,
268 module_id: CrateModuleId, 269 module_id: LocalModuleId,
269 import: &raw::ImportData, 270 import: &raw::ImportData,
270 ) -> (PerNs, ReachedFixedPoint) { 271 ) -> (PerNs, ReachedFixedPoint) {
271 log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); 272 log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition);
@@ -291,9 +292,9 @@ where
291 292
292 fn record_resolved_import( 293 fn record_resolved_import(
293 &mut self, 294 &mut self,
294 module_id: CrateModuleId, 295 module_id: LocalModuleId,
295 def: PerNs, 296 def: PerNs,
296 import_id: raw::ImportId, 297 import_id: LocalImportId,
297 import: &raw::ImportData, 298 import: &raw::ImportData,
298 ) { 299 ) {
299 if import.is_glob { 300 if import.is_glob {
@@ -387,8 +388,8 @@ where
387 388
388 fn update( 389 fn update(
389 &mut self, 390 &mut self,
390 module_id: CrateModuleId, 391 module_id: LocalModuleId,
391 import: Option<raw::ImportId>, 392 import: Option<LocalImportId>,
392 resolutions: &[(Name, Resolution)], 393 resolutions: &[(Name, Resolution)],
393 ) { 394 ) {
394 self.update_recursive(module_id, import, resolutions, 0) 395 self.update_recursive(module_id, import, resolutions, 0)
@@ -396,8 +397,8 @@ where
396 397
397 fn update_recursive( 398 fn update_recursive(
398 &mut self, 399 &mut self,
399 module_id: CrateModuleId, 400 module_id: LocalModuleId,
400 import: Option<raw::ImportId>, 401 import: Option<LocalImportId>,
401 resolutions: &[(Name, Resolution)], 402 resolutions: &[(Name, Resolution)],
402 depth: usize, 403 depth: usize,
403 ) { 404 ) {
@@ -484,7 +485,7 @@ where
484 485
485 fn collect_macro_expansion( 486 fn collect_macro_expansion(
486 &mut self, 487 &mut self,
487 module_id: CrateModuleId, 488 module_id: LocalModuleId,
488 macro_call_id: MacroCallId, 489 macro_call_id: MacroCallId,
489 macro_def_id: MacroDefId, 490 macro_def_id: MacroDefId,
490 ) { 491 ) {
@@ -522,7 +523,7 @@ where
522/// Walks a single module, populating defs, imports and macros 523/// Walks a single module, populating defs, imports and macros
523struct ModCollector<'a, D> { 524struct ModCollector<'a, D> {
524 def_collector: D, 525 def_collector: D,
525 module_id: CrateModuleId, 526 module_id: LocalModuleId,
526 file_id: HirFileId, 527 file_id: HirFileId,
527 raw_items: &'a raw::RawItems, 528 raw_items: &'a raw::RawItems,
528 mod_dir: ModDir, 529 mod_dir: ModDir,
@@ -530,7 +531,7 @@ struct ModCollector<'a, D> {
530 531
531impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>> 532impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>>
532where 533where
533 DB: DefDatabase2, 534 DB: DefDatabase,
534{ 535{
535 fn collect(&mut self, items: &[raw::RawItem]) { 536 fn collect(&mut self, items: &[raw::RawItem]) {
536 // Note: don't assert that inserted value is fresh: it's simply not true 537 // Note: don't assert that inserted value is fresh: it's simply not true
@@ -647,7 +648,7 @@ where
647 name: Name, 648 name: Name,
648 declaration: AstId<ast::Module>, 649 declaration: AstId<ast::Module>,
649 definition: Option<FileId>, 650 definition: Option<FileId>,
650 ) -> CrateModuleId { 651 ) -> LocalModuleId {
651 let modules = &mut self.def_collector.def_map.modules; 652 let modules = &mut self.def_collector.def_map.modules;
652 let res = modules.alloc(ModuleData::default()); 653 let res = modules.alloc(ModuleData::default());
653 modules[res].parent = Some(self.module_id); 654 modules[res].parent = Some(self.module_id);
@@ -772,7 +773,7 @@ where
772 self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path)); 773 self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path));
773 } 774 }
774 775
775 fn import_all_legacy_macros(&mut self, module_id: CrateModuleId) { 776 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
776 let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone(); 777 let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone();
777 for (name, macro_) in macros { 778 for (name, macro_) in macros {
778 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); 779 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_);
@@ -798,12 +799,12 @@ mod tests {
798 use ra_db::{fixture::WithFixture, SourceDatabase}; 799 use ra_db::{fixture::WithFixture, SourceDatabase};
799 use rustc_hash::FxHashSet; 800 use rustc_hash::FxHashSet;
800 801
801 use crate::{db::DefDatabase2, test_db::TestDB}; 802 use crate::{db::DefDatabase, test_db::TestDB};
802 803
803 use super::*; 804 use super::*;
804 805
805 fn do_collect_defs( 806 fn do_collect_defs(
806 db: &impl DefDatabase2, 807 db: &impl DefDatabase,
807 def_map: CrateDefMap, 808 def_map: CrateDefMap,
808 monitor: MacroStackMonitor, 809 monitor: MacroStackMonitor,
809 ) -> CrateDefMap { 810 ) -> CrateDefMap {
@@ -827,7 +828,7 @@ mod tests {
827 828
828 let def_map = { 829 let def_map = {
829 let edition = db.crate_graph().edition(krate); 830 let edition = db.crate_graph().edition(krate);
830 let mut modules: Arena<CrateModuleId, ModuleData> = Arena::default(); 831 let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
831 let root = modules.alloc(ModuleData::default()); 832 let root = modules.alloc(ModuleData::default());
832 CrateDefMap { 833 CrateDefMap {
833 krate, 834 krate,
diff --git a/crates/ra_hir_def/src/nameres/mod_resolution.rs b/crates/ra_hir_def/src/nameres/mod_resolution.rs
index b3b1379d0..14fb8ba3a 100644
--- a/crates/ra_hir_def/src/nameres/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/mod_resolution.rs
@@ -3,7 +3,7 @@ use hir_expand::name::Name;
3use ra_db::{FileId, RelativePathBuf}; 3use ra_db::{FileId, RelativePathBuf};
4use ra_syntax::SmolStr; 4use ra_syntax::SmolStr;
5 5
6use crate::{db::DefDatabase2, HirFileId}; 6use crate::{db::DefDatabase, HirFileId};
7 7
8#[derive(Clone, Debug)] 8#[derive(Clone, Debug)]
9pub(super) struct ModDir { 9pub(super) struct ModDir {
@@ -40,7 +40,7 @@ impl ModDir {
40 40
41 pub(super) fn resolve_declaration( 41 pub(super) fn resolve_declaration(
42 &self, 42 &self,
43 db: &impl DefDatabase2, 43 db: &impl DefDatabase,
44 file_id: HirFileId, 44 file_id: HirFileId,
45 name: &Name, 45 name: &Name,
46 attr_path: Option<&SmolStr>, 46 attr_path: Option<&SmolStr>,
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 95692f826..9455f22bb 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -15,10 +15,11 @@ use ra_db::Edition;
15use test_utils::tested_by; 15use test_utils::tested_by;
16 16
17use crate::{ 17use crate::{
18 db::DefDatabase2, 18 db::DefDatabase,
19 nameres::{per_ns::PerNs, CrateDefMap}, 19 nameres::CrateDefMap,
20 path::{Path, PathKind}, 20 path::{Path, PathKind},
21 AdtId, CrateModuleId, EnumVariantId, ModuleDefId, ModuleId, 21 per_ns::PerNs,
22 AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
22}; 23};
23 24
24#[derive(Debug, Clone, Copy, PartialEq, Eq)] 25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -63,9 +64,9 @@ impl CrateDefMap {
63 // the result. 64 // the result.
64 pub(super) fn resolve_path_fp_with_macro( 65 pub(super) fn resolve_path_fp_with_macro(
65 &self, 66 &self,
66 db: &impl DefDatabase2, 67 db: &impl DefDatabase,
67 mode: ResolveMode, 68 mode: ResolveMode,
68 original_module: CrateModuleId, 69 original_module: LocalModuleId,
69 path: &Path, 70 path: &Path,
70 ) -> ResolvePathResult { 71 ) -> ResolvePathResult {
71 let mut segments = path.segments.iter().enumerate(); 72 let mut segments = path.segments.iter().enumerate();
@@ -216,8 +217,8 @@ impl CrateDefMap {
216 217
217 fn resolve_name_in_module( 218 fn resolve_name_in_module(
218 &self, 219 &self,
219 db: &impl DefDatabase2, 220 db: &impl DefDatabase,
220 module: CrateModuleId, 221 module: LocalModuleId,
221 name: &Name, 222 name: &Name,
222 ) -> PerNs { 223 ) -> PerNs {
223 // Resolve in: 224 // Resolve in:
@@ -243,7 +244,7 @@ impl CrateDefMap {
243 from_crate_root.or(from_extern_prelude) 244 from_crate_root.or(from_extern_prelude)
244 } 245 }
245 246
246 fn resolve_in_prelude(&self, db: &impl DefDatabase2, name: &Name) -> PerNs { 247 fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs {
247 if let Some(prelude) = self.prelude { 248 if let Some(prelude) = self.prelude {
248 let keep; 249 let keep;
249 let def_map = if prelude.krate == self.krate { 250 let def_map = if prelude.krate == self.krate {
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 55a9634f8..552cbe544 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -12,15 +12,15 @@ use hir_expand::{
12use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 12use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
13use ra_syntax::{ 13use ra_syntax::{
14 ast::{self, AttrsOwner, NameOwner}, 14 ast::{self, AttrsOwner, NameOwner},
15 AstNode, AstPtr, SourceFile, 15 AstNode, AstPtr,
16}; 16};
17use test_utils::tested_by; 17use test_utils::tested_by;
18 18
19use crate::{ 19use crate::{
20 attr::{Attr, Attrs}, 20 attr::{Attr, Attrs},
21 db::DefDatabase2, 21 db::DefDatabase,
22 path::Path, 22 path::Path,
23 FileAstId, HirFileId, ModuleSource, Source, 23 FileAstId, HirFileId, LocalImportId, Source,
24}; 24};
25 25
26/// `RawItems` is a set of top-level items in a file (except for impls). 26/// `RawItems` is a set of top-level items in a file (except for impls).
@@ -30,7 +30,7 @@ use crate::{
30#[derive(Debug, Default, PartialEq, Eq)] 30#[derive(Debug, Default, PartialEq, Eq)]
31pub struct RawItems { 31pub struct RawItems {
32 modules: Arena<Module, ModuleData>, 32 modules: Arena<Module, ModuleData>,
33 imports: Arena<ImportId, ImportData>, 33 imports: Arena<LocalImportId, ImportData>,
34 defs: Arena<Def, DefData>, 34 defs: Arena<Def, DefData>,
35 macros: Arena<Macro, MacroData>, 35 macros: Arena<Macro, MacroData>,
36 impls: Arena<Impl, ImplData>, 36 impls: Arena<Impl, ImplData>,
@@ -40,41 +40,31 @@ pub struct RawItems {
40 40
41#[derive(Debug, Default, PartialEq, Eq)] 41#[derive(Debug, Default, PartialEq, Eq)]
42pub struct ImportSourceMap { 42pub struct ImportSourceMap {
43 map: ArenaMap<ImportId, ImportSourcePtr>, 43 map: ArenaMap<LocalImportId, ImportSourcePtr>,
44} 44}
45 45
46type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; 46type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
47type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>;
48
49fn to_node(ptr: ImportSourcePtr, file: &SourceFile) -> ImportSource {
50 ptr.map(|ptr| ptr.to_node(file.syntax()), |ptr| ptr.to_node(file.syntax()))
51}
52 47
53impl ImportSourceMap { 48impl ImportSourceMap {
54 fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { 49 fn insert(&mut self, import: LocalImportId, ptr: ImportSourcePtr) {
55 self.map.insert(import, ptr) 50 self.map.insert(import, ptr)
56 } 51 }
57 52
58 pub fn get(&self, source: &ModuleSource, import: ImportId) -> ImportSource { 53 pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
59 let file = match source { 54 self.map[import].clone()
60 ModuleSource::SourceFile(file) => file.clone(),
61 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
62 };
63
64 to_node(self.map[import], &file)
65 } 55 }
66} 56}
67 57
68impl RawItems { 58impl RawItems {
69 pub(crate) fn raw_items_query( 59 pub(crate) fn raw_items_query(
70 db: &(impl DefDatabase2 + AstDatabase), 60 db: &(impl DefDatabase + AstDatabase),
71 file_id: HirFileId, 61 file_id: HirFileId,
72 ) -> Arc<RawItems> { 62 ) -> Arc<RawItems> {
73 db.raw_items_with_source_map(file_id).0 63 db.raw_items_with_source_map(file_id).0
74 } 64 }
75 65
76 pub(crate) fn raw_items_with_source_map_query( 66 pub(crate) fn raw_items_with_source_map_query(
77 db: &(impl DefDatabase2 + AstDatabase), 67 db: &(impl DefDatabase + AstDatabase),
78 file_id: HirFileId, 68 file_id: HirFileId,
79 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { 69 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
80 let mut collector = RawItemsCollector { 70 let mut collector = RawItemsCollector {
@@ -106,9 +96,9 @@ impl Index<Module> for RawItems {
106 } 96 }
107} 97}
108 98
109impl Index<ImportId> for RawItems { 99impl Index<LocalImportId> for RawItems {
110 type Output = ImportData; 100 type Output = ImportData;
111 fn index(&self, idx: ImportId) -> &ImportData { 101 fn index(&self, idx: LocalImportId) -> &ImportData {
112 &self.imports[idx] 102 &self.imports[idx]
113 } 103 }
114} 104}
@@ -143,7 +133,7 @@ pub(super) struct RawItem {
143#[derive(Debug, PartialEq, Eq, Clone, Copy)] 133#[derive(Debug, PartialEq, Eq, Clone, Copy)]
144pub(super) enum RawItemKind { 134pub(super) enum RawItemKind {
145 Module(Module), 135 Module(Module),
146 Import(ImportId), 136 Import(LocalImportId),
147 Def(Def), 137 Def(Def),
148 Macro(Macro), 138 Macro(Macro),
149 Impl(Impl), 139 Impl(Impl),
@@ -159,10 +149,6 @@ pub(super) enum ModuleData {
159 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, 149 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
160} 150}
161 151
162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
163pub struct ImportId(RawId);
164impl_arena_id!(ImportId);
165
166#[derive(Debug, Clone, PartialEq, Eq)] 152#[derive(Debug, Clone, PartialEq, Eq)]
167pub struct ImportData { 153pub struct ImportData {
168 pub(super) path: Path, 154 pub(super) path: Path,
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 256f7d4be..f0b86af7c 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -10,7 +10,7 @@ use insta::assert_snapshot;
10use ra_db::{fixture::WithFixture, SourceDatabase}; 10use ra_db::{fixture::WithFixture, SourceDatabase};
11use test_utils::covers; 11use test_utils::covers;
12 12
13use crate::{db::DefDatabase2, nameres::*, test_db::TestDB, CrateModuleId}; 13use crate::{db::DefDatabase, nameres::*, test_db::TestDB, LocalModuleId};
14 14
15fn def_map(fixtute: &str) -> String { 15fn def_map(fixtute: &str) -> String {
16 let dm = compute_crate_def_map(fixtute); 16 let dm = compute_crate_def_map(fixtute);
@@ -28,7 +28,7 @@ fn render_crate_def_map(map: &CrateDefMap) -> String {
28 go(&mut buf, map, "\ncrate", map.root()); 28 go(&mut buf, map, "\ncrate", map.root());
29 return buf.trim().to_string(); 29 return buf.trim().to_string();
30 30
31 fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: CrateModuleId) { 31 fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) {
32 *buf += path; 32 *buf += path;
33 *buf += "\n"; 33 *buf += "\n";
34 34
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
index eb7b85c07..e11530062 100644
--- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
@@ -665,7 +665,7 @@ fn unresolved_module_diagnostics() {
665 @r###" 665 @r###"
666 [ 666 [
667 UnresolvedModule { 667 UnresolvedModule {
668 module: CrateModuleId( 668 module: LocalModuleId(
669 0, 669 0,
670 ), 670 ),
671 declaration: AstId { 671 declaration: AstId {
diff --git a/crates/ra_hir_def/src/nameres/per_ns.rs b/crates/ra_hir_def/src/per_ns.rs
index 717ed1ef9..717ed1ef9 100644
--- a/crates/ra_hir_def/src/nameres/per_ns.rs
+++ b/crates/ra_hir_def/src/per_ns.rs
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 7b5c3ec06..b56de44dd 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -11,14 +11,15 @@ use rustc_hash::FxHashSet;
11use crate::{ 11use crate::{
12 body::scope::{ExprScopes, ScopeId}, 12 body::scope::{ExprScopes, ScopeId},
13 builtin_type::BuiltinType, 13 builtin_type::BuiltinType,
14 db::DefDatabase2, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 nameres::{per_ns::PerNs, CrateDefMap}, 17 nameres::CrateDefMap,
18 path::{Path, PathKind}, 18 path::{Path, PathKind},
19 AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, 19 per_ns::PerNs,
20 FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, 20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
21 TypeAliasId, 21 GenericDefId, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId,
22 TraitId, TypeAliasId,
22}; 23};
23 24
24#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -30,7 +31,7 @@ pub struct Resolver {
30#[derive(Debug, Clone)] 31#[derive(Debug, Clone)]
31pub(crate) struct ModuleItemMap { 32pub(crate) struct ModuleItemMap {
32 crate_def_map: Arc<CrateDefMap>, 33 crate_def_map: Arc<CrateDefMap>,
33 module_id: CrateModuleId, 34 module_id: LocalModuleId,
34} 35}
35 36
36#[derive(Debug, Clone)] 37#[derive(Debug, Clone)]
@@ -87,7 +88,7 @@ pub enum ValueNs {
87 88
88impl Resolver { 89impl Resolver {
89 /// Resolve known trait from std, like `std::futures::Future` 90 /// Resolve known trait from std, like `std::futures::Future`
90 pub fn resolve_known_trait(&self, db: &impl DefDatabase2, path: &Path) -> Option<TraitId> { 91 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> {
91 let res = self.resolve_module_path(db, path).take_types()?; 92 let res = self.resolve_module_path(db, path).take_types()?;
92 match res { 93 match res {
93 ModuleDefId::TraitId(it) => Some(it), 94 ModuleDefId::TraitId(it) => Some(it),
@@ -96,7 +97,7 @@ impl Resolver {
96 } 97 }
97 98
98 /// Resolve known struct from std, like `std::boxed::Box` 99 /// Resolve known struct from std, like `std::boxed::Box`
99 pub fn resolve_known_struct(&self, db: &impl DefDatabase2, path: &Path) -> Option<StructId> { 100 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> {
100 let res = self.resolve_module_path(db, path).take_types()?; 101 let res = self.resolve_module_path(db, path).take_types()?;
101 match res { 102 match res {
102 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), 103 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
@@ -105,7 +106,7 @@ impl Resolver {
105 } 106 }
106 107
107 /// Resolve known enum from std, like `std::result::Result` 108 /// Resolve known enum from std, like `std::result::Result`
108 pub fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option<EnumId> { 109 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> {
109 let res = self.resolve_module_path(db, path).take_types()?; 110 let res = self.resolve_module_path(db, path).take_types()?;
110 match res { 111 match res {
111 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), 112 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
@@ -114,7 +115,7 @@ impl Resolver {
114 } 115 }
115 116
116 /// pub only for source-binder 117 /// pub only for source-binder
117 pub fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs { 118 pub fn resolve_module_path(&self, db: &impl DefDatabase, path: &Path) -> PerNs {
118 let (item_map, module) = match self.module() { 119 let (item_map, module) = match self.module() {
119 Some(it) => it, 120 Some(it) => it,
120 None => return PerNs::none(), 121 None => return PerNs::none(),
@@ -128,7 +129,7 @@ impl Resolver {
128 129
129 pub fn resolve_path_in_type_ns( 130 pub fn resolve_path_in_type_ns(
130 &self, 131 &self,
131 db: &impl DefDatabase2, 132 db: &impl DefDatabase,
132 path: &Path, 133 path: &Path,
133 ) -> Option<(TypeNs, Option<usize>)> { 134 ) -> Option<(TypeNs, Option<usize>)> {
134 if path.is_type_relative() { 135 if path.is_type_relative() {
@@ -184,7 +185,7 @@ impl Resolver {
184 185
185 pub fn resolve_path_in_type_ns_fully( 186 pub fn resolve_path_in_type_ns_fully(
186 &self, 187 &self,
187 db: &impl DefDatabase2, 188 db: &impl DefDatabase,
188 path: &Path, 189 path: &Path,
189 ) -> Option<TypeNs> { 190 ) -> Option<TypeNs> {
190 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; 191 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
@@ -196,7 +197,7 @@ impl Resolver {
196 197
197 pub fn resolve_path_in_value_ns<'p>( 198 pub fn resolve_path_in_value_ns<'p>(
198 &self, 199 &self,
199 db: &impl DefDatabase2, 200 db: &impl DefDatabase,
200 path: &'p Path, 201 path: &'p Path,
201 ) -> Option<ResolveValueResult> { 202 ) -> Option<ResolveValueResult> {
202 if path.is_type_relative() { 203 if path.is_type_relative() {
@@ -296,7 +297,7 @@ impl Resolver {
296 297
297 pub fn resolve_path_in_value_ns_fully( 298 pub fn resolve_path_in_value_ns_fully(
298 &self, 299 &self,
299 db: &impl DefDatabase2, 300 db: &impl DefDatabase,
300 path: &Path, 301 path: &Path,
301 ) -> Option<ValueNs> { 302 ) -> Option<ValueNs> {
302 match self.resolve_path_in_value_ns(db, path)? { 303 match self.resolve_path_in_value_ns(db, path)? {
@@ -305,18 +306,18 @@ impl Resolver {
305 } 306 }
306 } 307 }
307 308
308 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option<MacroDefId> { 309 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
309 let (item_map, module) = self.module()?; 310 let (item_map, module) = self.module()?;
310 item_map.resolve_path(db, module, path).0.get_macros() 311 item_map.resolve_path(db, module, path).0.get_macros()
311 } 312 }
312 313
313 pub fn process_all_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { 314 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
314 for scope in self.scopes.iter().rev() { 315 for scope in self.scopes.iter().rev() {
315 scope.process_names(db, f); 316 scope.process_names(db, f);
316 } 317 }
317 } 318 }
318 319
319 pub fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet<TraitId> { 320 pub fn traits_in_scope(&self, db: &impl DefDatabase) -> FxHashSet<TraitId> {
320 let mut traits = FxHashSet::default(); 321 let mut traits = FxHashSet::default();
321 for scope in &self.scopes { 322 for scope in &self.scopes {
322 if let Scope::ModuleScope(m) = scope { 323 if let Scope::ModuleScope(m) = scope {
@@ -330,7 +331,7 @@ impl Resolver {
330 traits 331 traits
331 } 332 }
332 333
333 fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { 334 fn module(&self) -> Option<(&CrateDefMap, LocalModuleId)> {
334 self.scopes.iter().rev().find_map(|scope| match scope { 335 self.scopes.iter().rev().find_map(|scope| match scope {
335 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), 336 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
336 337
@@ -378,7 +379,7 @@ pub enum ScopeDef {
378} 379}
379 380
380impl Scope { 381impl Scope {
381 fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { 382 fn process_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
382 match self { 383 match self {
383 Scope::ModuleScope(m) => { 384 Scope::ModuleScope(m) => {
384 // FIXME: should we provide `self` here? 385 // FIXME: should we provide `self` here?
@@ -425,17 +426,13 @@ impl Scope {
425} 426}
426 427
427// needs arbitrary_self_types to be a method... or maybe move to the def? 428// needs arbitrary_self_types to be a method... or maybe move to the def?
428pub fn resolver_for_expr( 429pub fn resolver_for_expr(db: &impl DefDatabase, owner: DefWithBodyId, expr_id: ExprId) -> Resolver {
429 db: &impl DefDatabase2,
430 owner: DefWithBodyId,
431 expr_id: ExprId,
432) -> Resolver {
433 let scopes = db.expr_scopes(owner); 430 let scopes = db.expr_scopes(owner);
434 resolver_for_scope(db, owner, scopes.scope_for(expr_id)) 431 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
435} 432}
436 433
437pub fn resolver_for_scope( 434pub fn resolver_for_scope(
438 db: &impl DefDatabase2, 435 db: &impl DefDatabase,
439 owner: DefWithBodyId, 436 owner: DefWithBodyId,
440 scope_id: Option<ScopeId>, 437 scope_id: Option<ScopeId>,
441) -> Resolver { 438) -> Resolver {
@@ -454,7 +451,7 @@ impl Resolver {
454 self 451 self
455 } 452 }
456 453
457 fn push_generic_params_scope(self, db: &impl DefDatabase2, def: GenericDefId) -> Resolver { 454 fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver {
458 let params = db.generic_params(def); 455 let params = db.generic_params(def);
459 if params.params.is_empty() { 456 if params.params.is_empty() {
460 self 457 self
@@ -470,7 +467,7 @@ impl Resolver {
470 fn push_module_scope( 467 fn push_module_scope(
471 self, 468 self,
472 crate_def_map: Arc<CrateDefMap>, 469 crate_def_map: Arc<CrateDefMap>,
473 module_id: CrateModuleId, 470 module_id: LocalModuleId,
474 ) -> Resolver { 471 ) -> Resolver {
475 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) 472 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
476 } 473 }
@@ -487,24 +484,24 @@ impl Resolver {
487 484
488pub trait HasResolver { 485pub trait HasResolver {
489 /// Builds a resolver for type references inside this def. 486 /// Builds a resolver for type references inside this def.
490 fn resolver(self, db: &impl DefDatabase2) -> Resolver; 487 fn resolver(self, db: &impl DefDatabase) -> Resolver;
491} 488}
492 489
493impl HasResolver for ModuleId { 490impl HasResolver for ModuleId {
494 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 491 fn resolver(self, db: &impl DefDatabase) -> Resolver {
495 let def_map = db.crate_def_map(self.krate); 492 let def_map = db.crate_def_map(self.krate);
496 Resolver::default().push_module_scope(def_map, self.module_id) 493 Resolver::default().push_module_scope(def_map, self.module_id)
497 } 494 }
498} 495}
499 496
500impl HasResolver for TraitId { 497impl HasResolver for TraitId {
501 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 498 fn resolver(self, db: &impl DefDatabase) -> Resolver {
502 self.module(db).resolver(db).push_generic_params_scope(db, self.into()) 499 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
503 } 500 }
504} 501}
505 502
506impl<T: Into<AdtId>> HasResolver for T { 503impl<T: Into<AdtId>> HasResolver for T {
507 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 504 fn resolver(self, db: &impl DefDatabase) -> Resolver {
508 let def = self.into(); 505 let def = self.into();
509 let module = match def { 506 let module = match def {
510 AdtId::StructId(it) => it.0.module(db), 507 AdtId::StructId(it) => it.0.module(db),
@@ -520,13 +517,13 @@ impl<T: Into<AdtId>> HasResolver for T {
520} 517}
521 518
522impl HasResolver for FunctionId { 519impl HasResolver for FunctionId {
523 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 520 fn resolver(self, db: &impl DefDatabase) -> Resolver {
524 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) 521 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
525 } 522 }
526} 523}
527 524
528impl HasResolver for DefWithBodyId { 525impl HasResolver for DefWithBodyId {
529 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 526 fn resolver(self, db: &impl DefDatabase) -> Resolver {
530 match self { 527 match self {
531 DefWithBodyId::ConstId(c) => c.resolver(db), 528 DefWithBodyId::ConstId(c) => c.resolver(db),
532 DefWithBodyId::FunctionId(f) => f.resolver(db), 529 DefWithBodyId::FunctionId(f) => f.resolver(db),
@@ -536,25 +533,25 @@ impl HasResolver for DefWithBodyId {
536} 533}
537 534
538impl HasResolver for ConstId { 535impl HasResolver for ConstId {
539 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 536 fn resolver(self, db: &impl DefDatabase) -> Resolver {
540 self.lookup(db).container.resolver(db) 537 self.lookup(db).container.resolver(db)
541 } 538 }
542} 539}
543 540
544impl HasResolver for StaticId { 541impl HasResolver for StaticId {
545 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 542 fn resolver(self, db: &impl DefDatabase) -> Resolver {
546 self.module(db).resolver(db) 543 self.module(db).resolver(db)
547 } 544 }
548} 545}
549 546
550impl HasResolver for TypeAliasId { 547impl HasResolver for TypeAliasId {
551 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 548 fn resolver(self, db: &impl DefDatabase) -> Resolver {
552 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) 549 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
553 } 550 }
554} 551}
555 552
556impl HasResolver for ContainerId { 553impl HasResolver for ContainerId {
557 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 554 fn resolver(self, db: &impl DefDatabase) -> Resolver {
558 match self { 555 match self {
559 ContainerId::TraitId(it) => it.resolver(db), 556 ContainerId::TraitId(it) => it.resolver(db),
560 ContainerId::ImplId(it) => it.resolver(db), 557 ContainerId::ImplId(it) => it.resolver(db),
@@ -564,7 +561,7 @@ impl HasResolver for ContainerId {
564} 561}
565 562
566impl HasResolver for GenericDefId { 563impl HasResolver for GenericDefId {
567 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 564 fn resolver(self, db: &impl DefDatabase) -> Resolver {
568 match self { 565 match self {
569 GenericDefId::FunctionId(inner) => inner.resolver(db), 566 GenericDefId::FunctionId(inner) => inner.resolver(db),
570 GenericDefId::AdtId(adt) => adt.resolver(db), 567 GenericDefId::AdtId(adt) => adt.resolver(db),
@@ -578,7 +575,7 @@ impl HasResolver for GenericDefId {
578} 575}
579 576
580impl HasResolver for ImplId { 577impl HasResolver for ImplId {
581 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 578 fn resolver(self, db: &impl DefDatabase) -> Resolver {
582 self.module(db) 579 self.module(db)
583 .resolver(db) 580 .resolver(db)
584 .push_generic_params_scope(db, self.into()) 581 .push_generic_params_scope(db, self.into())
diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs
index 8ee8e40d0..439e8a412 100644
--- a/crates/ra_hir_def/src/test_db.rs
+++ b/crates/ra_hir_def/src/test_db.rs
@@ -12,7 +12,7 @@ use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath
12 ra_db::SourceDatabaseStorage, 12 ra_db::SourceDatabaseStorage,
13 hir_expand::db::AstDatabaseStorage, 13 hir_expand::db::AstDatabaseStorage,
14 crate::db::InternDatabaseStorage, 14 crate::db::InternDatabaseStorage,
15 crate::db::DefDatabase2Storage 15 crate::db::DefDatabaseStorage
16)] 16)]
17#[derive(Debug, Default)] 17#[derive(Debug, Default)]
18pub struct TestDB { 18pub struct TestDB {
diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs
new file mode 100644
index 000000000..fc26f5a48
--- /dev/null
+++ b/crates/ra_hir_def/src/trace.rs
@@ -0,0 +1,49 @@
1//! Trace is a pretty niche data structure which is used when lowering a CST
2//! into HIR.
3//!
4//! Lowering process calculates two bits of information:
5//! * the lowered syntax itself
6//! * a mapping between lowered syntax and original syntax
7//!
8//! Due to the way salsa works, the mapping is usually hot lava, as it contains
9//! absolute offsets. The `Trace` structure (inspired, at least in name, by
10//! Kotlin's `BindingTrace`) allows use the same code to compute both
11//! projections.
12use ra_arena::{map::ArenaMap, Arena, ArenaId, RawId};
13
14pub(crate) struct Trace<ID: ArenaId, T, V> {
15 for_arena: bool,
16 arena: Arena<ID, T>,
17 map: ArenaMap<ID, V>,
18 len: u32,
19}
20
21impl<ID: ra_arena::ArenaId, T, V> Trace<ID, T, V> {
22 pub(crate) fn new_for_arena() -> Trace<ID, T, V> {
23 Trace { for_arena: true, arena: Arena::default(), map: ArenaMap::default(), len: 0 }
24 }
25
26 pub(crate) fn new_for_map() -> Trace<ID, T, V> {
27 Trace { for_arena: false, arena: Arena::default(), map: ArenaMap::default(), len: 0 }
28 }
29
30 pub(crate) fn alloc(&mut self, value: impl Fn() -> V, data: impl Fn() -> T) {
31 if self.for_arena {
32 self.arena.alloc(data());
33 } else {
34 let id = ID::from_raw(RawId::from(self.len));
35 self.len += 1;
36 self.map.insert(id, value());
37 }
38 }
39
40 pub(crate) fn into_arena(self) -> Arena<ID, T> {
41 assert!(self.for_arena);
42 self.arena
43 }
44
45 pub(crate) fn into_map(self) -> ArenaMap<ID, V> {
46 assert!(!self.for_arena);
47 self.map
48 }
49}