diff options
author | Seivan Heidari <[email protected]> | 2019-10-31 08:43:20 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-10-31 08:43:20 +0000 |
commit | 8edda0e7b164009d6c03bb3d4be603fb38ad2e2a (patch) | |
tree | 744cf81075d394e2f9c06afb07642a2601800dda /crates/ra_hir/src | |
parent | 49562d36b97ddde34cf7585a8c2e8f232519b657 (diff) | |
parent | d067afb064a7fa67b172abf561b7d80740cd6f18 (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir/src')
42 files changed, 426 insertions, 2451 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index 3e9cd3c63..4fa2062bd 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -3,13 +3,14 @@ | |||
3 | 3 | ||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use hir_def::{type_ref::TypeRef, LocalEnumVariantId}; | ||
7 | use hir_expand::name::AsName; | ||
6 | use ra_arena::{impl_arena_id, Arena, RawId}; | 8 | use ra_arena::{impl_arena_id, Arena, RawId}; |
7 | use ra_syntax::ast::{self, NameOwner, StructKind, TypeAscriptionOwner}; | 9 | use ra_syntax::ast::{self, NameOwner, StructKind, TypeAscriptionOwner}; |
8 | 10 | ||
9 | use crate::{ | 11 | use crate::{ |
10 | db::{AstDatabase, DefDatabase, HirDatabase}, | 12 | db::{AstDatabase, DefDatabase, HirDatabase}, |
11 | type_ref::TypeRef, | 13 | Enum, EnumVariant, FieldSource, HasSource, Module, Name, Source, Struct, StructField, |
12 | AsName, Enum, EnumVariant, FieldSource, HasSource, Module, Name, Source, Struct, StructField, | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | impl Struct { | 16 | impl Struct { |
@@ -67,7 +68,7 @@ impl EnumVariant { | |||
67 | #[derive(Debug, Clone, PartialEq, Eq)] | 68 | #[derive(Debug, Clone, PartialEq, Eq)] |
68 | pub struct EnumData { | 69 | pub struct EnumData { |
69 | pub(crate) name: Option<Name>, | 70 | pub(crate) name: Option<Name>, |
70 | pub(crate) variants: Arena<EnumVariantId, EnumVariantData>, | 71 | pub(crate) variants: Arena<LocalEnumVariantId, EnumVariantData>, |
71 | } | 72 | } |
72 | 73 | ||
73 | impl EnumData { | 74 | impl EnumData { |
@@ -84,10 +85,6 @@ impl EnumData { | |||
84 | } | 85 | } |
85 | } | 86 | } |
86 | 87 | ||
87 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
88 | pub(crate) struct EnumVariantId(RawId); | ||
89 | impl_arena_id!(EnumVariantId); | ||
90 | |||
91 | #[derive(Debug, Clone, PartialEq, Eq)] | 88 | #[derive(Debug, Clone, PartialEq, Eq)] |
92 | pub(crate) struct EnumVariantData { | 89 | pub(crate) struct EnumVariantData { |
93 | pub(crate) name: Option<Name>, | 90 | pub(crate) name: Option<Name>, |
diff --git a/crates/ra_hir/src/attr.rs b/crates/ra_hir/src/attr.rs deleted file mode 100644 index bd159a566..000000000 --- a/crates/ra_hir/src/attr.rs +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
1 | //! A higher level attributes based on TokenTree, with also some shortcuts. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use mbe::ast_to_token_tree; | ||
6 | use ra_cfg::CfgOptions; | ||
7 | use ra_syntax::{ | ||
8 | ast::{self, AstNode, AttrsOwner}, | ||
9 | SmolStr, | ||
10 | }; | ||
11 | use tt::Subtree; | ||
12 | |||
13 | use crate::{db::AstDatabase, path::Path, HirFileId, Source}; | ||
14 | |||
15 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
16 | pub(crate) struct Attr { | ||
17 | pub(crate) path: Path, | ||
18 | pub(crate) input: Option<AttrInput>, | ||
19 | } | ||
20 | |||
21 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
22 | pub enum AttrInput { | ||
23 | Literal(SmolStr), | ||
24 | TokenTree(Subtree), | ||
25 | } | ||
26 | |||
27 | impl Attr { | ||
28 | pub(crate) fn from_src( | ||
29 | Source { file_id, ast }: Source<ast::Attr>, | ||
30 | db: &impl AstDatabase, | ||
31 | ) -> Option<Attr> { | ||
32 | let path = Path::from_src(Source { file_id, ast: ast.path()? }, db)?; | ||
33 | let input = match ast.input() { | ||
34 | None => None, | ||
35 | Some(ast::AttrInput::Literal(lit)) => { | ||
36 | // FIXME: escape? raw string? | ||
37 | let value = lit.syntax().first_token()?.text().trim_matches('"').into(); | ||
38 | Some(AttrInput::Literal(value)) | ||
39 | } | ||
40 | Some(ast::AttrInput::TokenTree(tt)) => { | ||
41 | Some(AttrInput::TokenTree(ast_to_token_tree(&tt)?.0)) | ||
42 | } | ||
43 | }; | ||
44 | |||
45 | Some(Attr { path, input }) | ||
46 | } | ||
47 | |||
48 | pub(crate) fn from_attrs_owner( | ||
49 | file_id: HirFileId, | ||
50 | owner: &dyn AttrsOwner, | ||
51 | db: &impl AstDatabase, | ||
52 | ) -> Option<Arc<[Attr]>> { | ||
53 | let mut attrs = owner.attrs().peekable(); | ||
54 | if attrs.peek().is_none() { | ||
55 | // Avoid heap allocation | ||
56 | return None; | ||
57 | } | ||
58 | Some(attrs.flat_map(|ast| Attr::from_src(Source { file_id, ast }, db)).collect()) | ||
59 | } | ||
60 | |||
61 | pub(crate) fn is_simple_atom(&self, name: &str) -> bool { | ||
62 | // FIXME: Avoid cloning | ||
63 | self.path.as_ident().map_or(false, |s| s.to_string() == name) | ||
64 | } | ||
65 | |||
66 | // FIXME: handle cfg_attr :-) | ||
67 | pub(crate) fn as_cfg(&self) -> Option<&Subtree> { | ||
68 | if !self.is_simple_atom("cfg") { | ||
69 | return None; | ||
70 | } | ||
71 | match &self.input { | ||
72 | Some(AttrInput::TokenTree(subtree)) => Some(subtree), | ||
73 | _ => None, | ||
74 | } | ||
75 | } | ||
76 | |||
77 | pub(crate) fn as_path(&self) -> Option<&SmolStr> { | ||
78 | if !self.is_simple_atom("path") { | ||
79 | return None; | ||
80 | } | ||
81 | match &self.input { | ||
82 | Some(AttrInput::Literal(it)) => Some(it), | ||
83 | _ => None, | ||
84 | } | ||
85 | } | ||
86 | |||
87 | pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option<bool> { | ||
88 | cfg_options.is_cfg_enabled(self.as_cfg()?) | ||
89 | } | ||
90 | } | ||
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 8eb3c577d..b32aa145e 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -5,11 +5,17 @@ pub(crate) mod docs; | |||
5 | 5 | ||
6 | use std::sync::Arc; | 6 | use std::sync::Arc; |
7 | 7 | ||
8 | use ra_db::{CrateId, Edition, FileId}; | 8 | use hir_def::{ |
9 | builtin_type::BuiltinType, | ||
10 | type_ref::{Mutability, TypeRef}, | ||
11 | CrateModuleId, LocalEnumVariantId, ModuleId, | ||
12 | }; | ||
13 | use hir_expand::name::{self, AsName}; | ||
14 | use ra_db::{CrateId, Edition}; | ||
9 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | 15 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; |
10 | 16 | ||
11 | use crate::{ | 17 | use crate::{ |
12 | adt::{EnumVariantId, StructFieldId, VariantDef}, | 18 | adt::{StructFieldId, VariantDef}, |
13 | db::{AstDatabase, DefDatabase, HirDatabase}, | 19 | db::{AstDatabase, DefDatabase, HirDatabase}, |
14 | diagnostics::DiagnosticSink, | 20 | diagnostics::DiagnosticSink, |
15 | expr::{validation::ExprValidator, Body, BodySourceMap}, | 21 | expr::{validation::ExprValidator, Body, BodySourceMap}, |
@@ -19,20 +25,11 @@ use crate::{ | |||
19 | TypeAliasId, | 25 | TypeAliasId, |
20 | }, | 26 | }, |
21 | impl_block::ImplBlock, | 27 | impl_block::ImplBlock, |
22 | name::{ | 28 | nameres::{ImportId, ModuleScope, Namespace}, |
23 | BOOL, CHAR, F32, F64, I128, I16, I32, I64, I8, ISIZE, SELF_TYPE, STR, U128, U16, U32, U64, | ||
24 | U8, USIZE, | ||
25 | }, | ||
26 | nameres::{CrateModuleId, ImportId, ModuleScope, Namespace}, | ||
27 | resolve::{Resolver, Scope, TypeNs}, | 29 | resolve::{Resolver, Scope, TypeNs}, |
28 | traits::TraitData, | 30 | traits::TraitData, |
29 | ty::{ | 31 | ty::{InferenceResult, TraitRef}, |
30 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, | 32 | Either, HasSource, Name, Ty, |
31 | InferenceResult, TraitRef, | ||
32 | }, | ||
33 | type_ref::Mutability, | ||
34 | type_ref::TypeRef, | ||
35 | AsName, AstId, Either, HasSource, Name, Ty, | ||
36 | }; | 33 | }; |
37 | 34 | ||
38 | /// hir::Crate describes a single crate. It's the main interface with which | 35 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -67,8 +64,7 @@ impl Crate { | |||
67 | 64 | ||
68 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { | 65 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { |
69 | let module_id = db.crate_def_map(self).root(); | 66 | let module_id = db.crate_def_map(self).root(); |
70 | let module = Module { krate: self, module_id }; | 67 | Some(Module::new(self, module_id)) |
71 | Some(module) | ||
72 | } | 68 | } |
73 | 69 | ||
74 | pub fn edition(self, db: &impl DefDatabase) -> Edition { | 70 | pub fn edition(self, db: &impl DefDatabase) -> Edition { |
@@ -83,43 +79,7 @@ impl Crate { | |||
83 | 79 | ||
84 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 80 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
85 | pub struct Module { | 81 | pub struct Module { |
86 | pub(crate) krate: Crate, | 82 | pub(crate) id: ModuleId, |
87 | pub(crate) module_id: CrateModuleId, | ||
88 | } | ||
89 | |||
90 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
91 | pub enum BuiltinType { | ||
92 | Char, | ||
93 | Bool, | ||
94 | Str, | ||
95 | Int(IntTy), | ||
96 | Float(FloatTy), | ||
97 | } | ||
98 | |||
99 | impl BuiltinType { | ||
100 | #[rustfmt::skip] | ||
101 | pub(crate) const ALL: &'static [(Name, BuiltinType)] = &[ | ||
102 | (CHAR, BuiltinType::Char), | ||
103 | (BOOL, BuiltinType::Bool), | ||
104 | (STR, BuiltinType::Str), | ||
105 | |||
106 | (ISIZE, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize })), | ||
107 | (I8, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 })), | ||
108 | (I16, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 })), | ||
109 | (I32, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 })), | ||
110 | (I64, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 })), | ||
111 | (I128, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 })), | ||
112 | |||
113 | (USIZE, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize })), | ||
114 | (U8, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 })), | ||
115 | (U16, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 })), | ||
116 | (U32, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 })), | ||
117 | (U64, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 })), | ||
118 | (U128, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 })), | ||
119 | |||
120 | (F32, BuiltinType::Float(FloatTy { bitness: FloatBitness::X32 })), | ||
121 | (F64, BuiltinType::Float(FloatTy { bitness: FloatBitness::X64 })), | ||
122 | ]; | ||
123 | } | 83 | } |
124 | 84 | ||
125 | /// The defs which can be visible in the module. | 85 | /// The defs which can be visible in the module. |
@@ -148,39 +108,19 @@ impl_froms!( | |||
148 | BuiltinType | 108 | BuiltinType |
149 | ); | 109 | ); |
150 | 110 | ||
151 | pub enum ModuleSource { | 111 | pub use hir_def::ModuleSource; |
152 | SourceFile(ast::SourceFile), | ||
153 | Module(ast::Module), | ||
154 | } | ||
155 | 112 | ||
156 | impl ModuleSource { | 113 | impl Module { |
157 | pub(crate) fn new( | 114 | pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { |
158 | db: &(impl DefDatabase + AstDatabase), | 115 | Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } |
159 | file_id: Option<FileId>, | ||
160 | decl_id: Option<AstId<ast::Module>>, | ||
161 | ) -> ModuleSource { | ||
162 | match (file_id, decl_id) { | ||
163 | (Some(file_id), _) => { | ||
164 | let source_file = db.parse(file_id).tree(); | ||
165 | ModuleSource::SourceFile(source_file) | ||
166 | } | ||
167 | (None, Some(item_id)) => { | ||
168 | let module = item_id.to_node(db); | ||
169 | assert!(module.item_list().is_some(), "expected inline module"); | ||
170 | ModuleSource::Module(module) | ||
171 | } | ||
172 | (None, None) => panic!(), | ||
173 | } | ||
174 | } | 116 | } |
175 | } | ||
176 | 117 | ||
177 | impl Module { | ||
178 | /// Name of this module. | 118 | /// Name of this module. |
179 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 119 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
180 | let def_map = db.crate_def_map(self.krate); | 120 | let def_map = db.crate_def_map(self.krate()); |
181 | let parent = def_map[self.module_id].parent?; | 121 | let parent = def_map[self.id.module_id].parent?; |
182 | def_map[parent].children.iter().find_map(|(name, module_id)| { | 122 | def_map[parent].children.iter().find_map(|(name, module_id)| { |
183 | if *module_id == self.module_id { | 123 | if *module_id == self.id.module_id { |
184 | Some(name.clone()) | 124 | Some(name.clone()) |
185 | } else { | 125 | } else { |
186 | None | 126 | None |
@@ -200,29 +140,29 @@ impl Module { | |||
200 | } | 140 | } |
201 | 141 | ||
202 | /// Returns the crate this module is part of. | 142 | /// Returns the crate this module is part of. |
203 | pub fn krate(self, _db: &impl DefDatabase) -> Option<Crate> { | 143 | pub fn krate(self) -> Crate { |
204 | Some(self.krate) | 144 | Crate { crate_id: self.id.krate } |
205 | } | 145 | } |
206 | 146 | ||
207 | /// Topmost parent of this module. Every module has a `crate_root`, but some | 147 | /// Topmost parent of this module. Every module has a `crate_root`, but some |
208 | /// might be missing `krate`. This can happen if a module's file is not included | 148 | /// might be missing `krate`. This can happen if a module's file is not included |
209 | /// in the module tree of any target in `Cargo.toml`. | 149 | /// in the module tree of any target in `Cargo.toml`. |
210 | pub fn crate_root(self, db: &impl DefDatabase) -> Module { | 150 | pub fn crate_root(self, db: &impl DefDatabase) -> Module { |
211 | let def_map = db.crate_def_map(self.krate); | 151 | let def_map = db.crate_def_map(self.krate()); |
212 | self.with_module_id(def_map.root()) | 152 | self.with_module_id(def_map.root()) |
213 | } | 153 | } |
214 | 154 | ||
215 | /// Finds a child module with the specified name. | 155 | /// Finds a child module with the specified name. |
216 | pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> { | 156 | pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> { |
217 | let def_map = db.crate_def_map(self.krate); | 157 | let def_map = db.crate_def_map(self.krate()); |
218 | let child_id = def_map[self.module_id].children.get(name)?; | 158 | let child_id = def_map[self.id.module_id].children.get(name)?; |
219 | Some(self.with_module_id(*child_id)) | 159 | Some(self.with_module_id(*child_id)) |
220 | } | 160 | } |
221 | 161 | ||
222 | /// Iterates over all child modules. | 162 | /// Iterates over all child modules. |
223 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { | 163 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { |
224 | let def_map = db.crate_def_map(self.krate); | 164 | let def_map = db.crate_def_map(self.krate()); |
225 | let children = def_map[self.module_id] | 165 | let children = def_map[self.id.module_id] |
226 | .children | 166 | .children |
227 | .iter() | 167 | .iter() |
228 | .map(|(_, module_id)| self.with_module_id(*module_id)) | 168 | .map(|(_, module_id)| self.with_module_id(*module_id)) |
@@ -232,8 +172,8 @@ impl Module { | |||
232 | 172 | ||
233 | /// Finds a parent module. | 173 | /// Finds a parent module. |
234 | pub fn parent(self, db: &impl DefDatabase) -> Option<Module> { | 174 | pub fn parent(self, db: &impl DefDatabase) -> Option<Module> { |
235 | let def_map = db.crate_def_map(self.krate); | 175 | let def_map = db.crate_def_map(self.krate()); |
236 | let parent_id = def_map[self.module_id].parent?; | 176 | let parent_id = def_map[self.id.module_id].parent?; |
237 | Some(self.with_module_id(parent_id)) | 177 | Some(self.with_module_id(parent_id)) |
238 | } | 178 | } |
239 | 179 | ||
@@ -249,11 +189,11 @@ impl Module { | |||
249 | 189 | ||
250 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 190 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
251 | pub fn scope(self, db: &impl HirDatabase) -> ModuleScope { | 191 | pub fn scope(self, db: &impl HirDatabase) -> ModuleScope { |
252 | db.crate_def_map(self.krate)[self.module_id].scope.clone() | 192 | db.crate_def_map(self.krate())[self.id.module_id].scope.clone() |
253 | } | 193 | } |
254 | 194 | ||
255 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 195 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
256 | db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); | 196 | db.crate_def_map(self.krate()).add_diagnostics(db, self.id.module_id, sink); |
257 | for decl in self.declarations(db) { | 197 | for decl in self.declarations(db) { |
258 | match decl { | 198 | match decl { |
259 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), | 199 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), |
@@ -277,13 +217,13 @@ impl Module { | |||
277 | } | 217 | } |
278 | 218 | ||
279 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { | 219 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { |
280 | let def_map = db.crate_def_map(self.krate); | 220 | let def_map = db.crate_def_map(self.krate()); |
281 | Resolver::default().push_module_scope(def_map, self.module_id) | 221 | Resolver::default().push_module_scope(def_map, self.id.module_id) |
282 | } | 222 | } |
283 | 223 | ||
284 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { | 224 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { |
285 | let def_map = db.crate_def_map(self.krate); | 225 | let def_map = db.crate_def_map(self.krate()); |
286 | def_map[self.module_id] | 226 | def_map[self.id.module_id] |
287 | .scope | 227 | .scope |
288 | .entries() | 228 | .entries() |
289 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) | 229 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) |
@@ -303,7 +243,7 @@ impl Module { | |||
303 | } | 243 | } |
304 | 244 | ||
305 | fn with_module_id(self, module_id: CrateModuleId) -> Module { | 245 | fn with_module_id(self, module_id: CrateModuleId) -> Module { |
306 | Module { module_id, krate: self.krate } | 246 | Module::new(self.krate(), module_id) |
307 | } | 247 | } |
308 | } | 248 | } |
309 | 249 | ||
@@ -340,11 +280,11 @@ pub struct Struct { | |||
340 | 280 | ||
341 | impl Struct { | 281 | impl Struct { |
342 | pub fn module(self, db: &impl DefDatabase) -> Module { | 282 | pub fn module(self, db: &impl DefDatabase) -> Module { |
343 | self.id.module(db) | 283 | Module { id: self.id.module(db) } |
344 | } | 284 | } |
345 | 285 | ||
346 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 286 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
347 | self.module(db).krate(db) | 287 | Some(self.module(db).krate()) |
348 | } | 288 | } |
349 | 289 | ||
350 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 290 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
@@ -402,7 +342,7 @@ impl Union { | |||
402 | } | 342 | } |
403 | 343 | ||
404 | pub fn module(self, db: &impl HirDatabase) -> Module { | 344 | pub fn module(self, db: &impl HirDatabase) -> Module { |
405 | self.id.module(db) | 345 | Module { id: self.id.module(db) } |
406 | } | 346 | } |
407 | 347 | ||
408 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 348 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
@@ -428,11 +368,11 @@ pub struct Enum { | |||
428 | 368 | ||
429 | impl Enum { | 369 | impl Enum { |
430 | pub fn module(self, db: &impl DefDatabase) -> Module { | 370 | pub fn module(self, db: &impl DefDatabase) -> Module { |
431 | self.id.module(db) | 371 | Module { id: self.id.module(db) } |
432 | } | 372 | } |
433 | 373 | ||
434 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 374 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
435 | self.module(db).krate(db) | 375 | Some(self.module(db).krate()) |
436 | } | 376 | } |
437 | 377 | ||
438 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 378 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
@@ -470,7 +410,7 @@ impl Enum { | |||
470 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 410 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
471 | pub struct EnumVariant { | 411 | pub struct EnumVariant { |
472 | pub(crate) parent: Enum, | 412 | pub(crate) parent: Enum, |
473 | pub(crate) id: EnumVariantId, | 413 | pub(crate) id: LocalEnumVariantId, |
474 | } | 414 | } |
475 | 415 | ||
476 | impl EnumVariant { | 416 | impl EnumVariant { |
@@ -523,12 +463,14 @@ impl Adt { | |||
523 | } | 463 | } |
524 | 464 | ||
525 | pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { | 465 | pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { |
526 | match self { | 466 | Some( |
527 | Adt::Struct(s) => s.module(db), | 467 | match self { |
528 | Adt::Union(s) => s.module(db), | 468 | Adt::Struct(s) => s.module(db), |
529 | Adt::Enum(e) => e.module(db), | 469 | Adt::Union(s) => s.module(db), |
530 | } | 470 | Adt::Enum(e) => e.module(db), |
531 | .krate(db) | 471 | } |
472 | .krate(), | ||
473 | ) | ||
532 | } | 474 | } |
533 | 475 | ||
534 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | 476 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { |
@@ -643,7 +585,7 @@ impl FnData { | |||
643 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { | 585 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { |
644 | TypeRef::from_ast(type_ref) | 586 | TypeRef::from_ast(type_ref) |
645 | } else { | 587 | } else { |
646 | let self_type = TypeRef::Path(SELF_TYPE.into()); | 588 | let self_type = TypeRef::Path(name::SELF_TYPE.into()); |
647 | match self_param.kind() { | 589 | match self_param.kind() { |
648 | ast::SelfParamKind::Owned => self_type, | 590 | ast::SelfParamKind::Owned => self_type, |
649 | ast::SelfParamKind::Ref => { | 591 | ast::SelfParamKind::Ref => { |
@@ -692,11 +634,11 @@ impl FnData { | |||
692 | 634 | ||
693 | impl Function { | 635 | impl Function { |
694 | pub fn module(self, db: &impl DefDatabase) -> Module { | 636 | pub fn module(self, db: &impl DefDatabase) -> Module { |
695 | self.id.module(db) | 637 | Module { id: self.id.module(db) } |
696 | } | 638 | } |
697 | 639 | ||
698 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 640 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
699 | self.module(db).krate(db) | 641 | Some(self.module(db).krate()) |
700 | } | 642 | } |
701 | 643 | ||
702 | pub fn name(self, db: &impl HirDatabase) -> Name { | 644 | pub fn name(self, db: &impl HirDatabase) -> Name { |
@@ -770,11 +712,11 @@ pub struct Const { | |||
770 | 712 | ||
771 | impl Const { | 713 | impl Const { |
772 | pub fn module(self, db: &impl DefDatabase) -> Module { | 714 | pub fn module(self, db: &impl DefDatabase) -> Module { |
773 | self.id.module(db) | 715 | Module { id: self.id.module(db) } |
774 | } | 716 | } |
775 | 717 | ||
776 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 718 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
777 | self.module(db).krate(db) | 719 | Some(self.module(db).krate()) |
778 | } | 720 | } |
779 | 721 | ||
780 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { | 722 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { |
@@ -867,11 +809,11 @@ pub struct Static { | |||
867 | 809 | ||
868 | impl Static { | 810 | impl Static { |
869 | pub fn module(self, db: &impl DefDatabase) -> Module { | 811 | pub fn module(self, db: &impl DefDatabase) -> Module { |
870 | self.id.module(db) | 812 | Module { id: self.id.module(db) } |
871 | } | 813 | } |
872 | 814 | ||
873 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 815 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
874 | self.module(db).krate(db) | 816 | Some(self.module(db).krate()) |
875 | } | 817 | } |
876 | 818 | ||
877 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { | 819 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { |
@@ -896,7 +838,7 @@ pub struct Trait { | |||
896 | 838 | ||
897 | impl Trait { | 839 | impl Trait { |
898 | pub fn module(self, db: &impl DefDatabase) -> Module { | 840 | pub fn module(self, db: &impl DefDatabase) -> Module { |
899 | self.id.module(db) | 841 | Module { id: self.id.module(db) } |
900 | } | 842 | } |
901 | 843 | ||
902 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 844 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
@@ -917,9 +859,7 @@ impl Trait { | |||
917 | .where_predicates | 859 | .where_predicates |
918 | .iter() | 860 | .iter() |
919 | .filter_map(|pred| match &pred.type_ref { | 861 | .filter_map(|pred| match &pred.type_ref { |
920 | TypeRef::Path(p) if p.as_ident() == Some(&crate::name::SELF_TYPE) => { | 862 | TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(), |
921 | pred.bound.as_path() | ||
922 | } | ||
923 | _ => None, | 863 | _ => None, |
924 | }) | 864 | }) |
925 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { | 865 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { |
@@ -998,11 +938,11 @@ pub struct TypeAlias { | |||
998 | 938 | ||
999 | impl TypeAlias { | 939 | impl TypeAlias { |
1000 | pub fn module(self, db: &impl DefDatabase) -> Module { | 940 | pub fn module(self, db: &impl DefDatabase) -> Module { |
1001 | self.id.module(db) | 941 | Module { id: self.id.module(db) } |
1002 | } | 942 | } |
1003 | 943 | ||
1004 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 944 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
1005 | self.module(db).krate(db) | 945 | Some(self.module(db).krate()) |
1006 | } | 946 | } |
1007 | 947 | ||
1008 | /// The containing impl block, if this is a method. | 948 | /// The containing impl block, if this is a method. |
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index fdae26906..5c7f61eef 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,9 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::ast::{self, AstNode}; |
4 | ast::{self, AstNode}, | ||
5 | SyntaxNode, | ||
6 | }; | ||
7 | 4 | ||
8 | use crate::{ | 5 | use crate::{ |
9 | db::{AstDatabase, DefDatabase, HirDatabase}, | 6 | db::{AstDatabase, DefDatabase, HirDatabase}, |
@@ -12,34 +9,21 @@ use crate::{ | |||
12 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | 9 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, |
13 | }; | 10 | }; |
14 | 11 | ||
15 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 12 | pub use hir_def::Source; |
16 | pub struct Source<T> { | ||
17 | pub file_id: HirFileId, | ||
18 | pub ast: T, | ||
19 | } | ||
20 | 13 | ||
21 | pub trait HasSource { | 14 | pub trait HasSource { |
22 | type Ast; | 15 | type Ast; |
23 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; | 16 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; |
24 | } | 17 | } |
25 | 18 | ||
26 | impl<T> Source<T> { | ||
27 | pub(crate) fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { | ||
28 | Source { file_id: self.file_id, ast: f(self.ast) } | ||
29 | } | ||
30 | pub(crate) fn file_syntax(&self, db: &impl AstDatabase) -> SyntaxNode { | ||
31 | db.parse_or_expand(self.file_id).expect("source created from invalid file") | ||
32 | } | ||
33 | } | ||
34 | |||
35 | /// NB: Module is !HasSource, because it has two source nodes at the same time: | 19 | /// NB: Module is !HasSource, because it has two source nodes at the same time: |
36 | /// definition and declaration. | 20 | /// definition and declaration. |
37 | impl Module { | 21 | impl Module { |
38 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | 22 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. |
39 | pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { | 23 | pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { |
40 | let def_map = db.crate_def_map(self.krate); | 24 | let def_map = db.crate_def_map(self.krate()); |
41 | let decl_id = def_map[self.module_id].declaration; | 25 | let decl_id = def_map[self.id.module_id].declaration; |
42 | let file_id = def_map[self.module_id].definition; | 26 | let file_id = def_map[self.id.module_id].definition; |
43 | let ast = ModuleSource::new(db, file_id, decl_id); | 27 | let ast = ModuleSource::new(db, file_id, decl_id); |
44 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); | 28 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); |
45 | Source { file_id, ast } | 29 | Source { file_id, ast } |
@@ -51,8 +35,8 @@ impl Module { | |||
51 | self, | 35 | self, |
52 | db: &(impl DefDatabase + AstDatabase), | 36 | db: &(impl DefDatabase + AstDatabase), |
53 | ) -> Option<Source<ast::Module>> { | 37 | ) -> Option<Source<ast::Module>> { |
54 | let def_map = db.crate_def_map(self.krate); | 38 | let def_map = db.crate_def_map(self.krate()); |
55 | let decl = def_map[self.module_id].declaration?; | 39 | let decl = def_map[self.id.module_id].declaration?; |
56 | let ast = decl.to_node(db); | 40 | let ast = decl.to_node(db); |
57 | Some(Source { file_id: decl.file_id(), ast }) | 41 | Some(Source { file_id: decl.file_id(), ast }) |
58 | } | 42 | } |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 489a3b19c..ebfd970eb 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -2,8 +2,8 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_db::{salsa, SourceDatabase}; | 5 | use ra_db::salsa; |
6 | use ra_syntax::{ast, Parse, SmolStr, SyntaxNode}; | 6 | use ra_syntax::SmolStr; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | 9 | adt::{EnumData, StructData}, |
@@ -12,81 +12,30 @@ use crate::{ | |||
12 | ids, | 12 | ids, |
13 | impl_block::{ImplBlock, ImplSourceMap, ModuleImplBlocks}, | 13 | impl_block::{ImplBlock, ImplSourceMap, ModuleImplBlocks}, |
14 | lang_item::{LangItemTarget, LangItems}, | 14 | lang_item::{LangItemTarget, LangItems}, |
15 | nameres::{CrateDefMap, ImportSourceMap, Namespace, RawItems}, | 15 | nameres::{CrateDefMap, Namespace}, |
16 | traits::TraitData, | 16 | traits::TraitData, |
17 | ty::{ | 17 | ty::{ |
18 | method_resolution::CrateImplBlocks, traits::Impl, CallableDef, FnSig, GenericPredicate, | 18 | method_resolution::CrateImplBlocks, traits::Impl, CallableDef, FnSig, GenericPredicate, |
19 | InferenceResult, Substs, Ty, TypableDef, TypeCtor, | 19 | InferenceResult, Substs, Ty, TypableDef, TypeCtor, |
20 | }, | 20 | }, |
21 | type_alias::TypeAliasData, | 21 | type_alias::TypeAliasData, |
22 | AstIdMap, Const, ConstData, Crate, DefWithBody, Enum, ErasedFileAstId, ExprScopes, FnData, | 22 | Const, ConstData, Crate, DefWithBody, Enum, ExprScopes, FnData, Function, Module, Static, |
23 | Function, HirFileId, MacroCallLoc, MacroDefId, Module, Static, Struct, StructField, Trait, | 23 | Struct, StructField, Trait, TypeAlias, |
24 | TypeAlias, | ||
25 | }; | 24 | }; |
26 | 25 | ||
27 | /// We store all interned things in the single QueryGroup. | 26 | pub use hir_def::db::{ |
28 | /// | 27 | DefDatabase2, DefDatabase2Storage, InternDatabase, InternDatabaseStorage, RawItemsQuery, |
29 | /// This is done mainly to allow both "volatile" `AstDatabase` and "stable" | 28 | RawItemsWithSourceMapQuery, |
30 | /// `DefDatabase` to access macros, without adding hard dependencies between the | 29 | }; |
31 | /// two. | 30 | pub use hir_expand::db::{ |
32 | #[salsa::query_group(InternDatabaseStorage)] | 31 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
33 | pub trait InternDatabase: SourceDatabase { | 32 | ParseMacroQuery, |
34 | #[salsa::interned] | 33 | }; |
35 | fn intern_macro(&self, macro_call: MacroCallLoc) -> ids::MacroCallId; | ||
36 | #[salsa::interned] | ||
37 | fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId; | ||
38 | #[salsa::interned] | ||
39 | fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId; | ||
40 | #[salsa::interned] | ||
41 | fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId; | ||
42 | #[salsa::interned] | ||
43 | fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId; | ||
44 | #[salsa::interned] | ||
45 | fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId; | ||
46 | #[salsa::interned] | ||
47 | fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId; | ||
48 | #[salsa::interned] | ||
49 | fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId; | ||
50 | |||
51 | // Interned IDs for Chalk integration | ||
52 | #[salsa::interned] | ||
53 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId; | ||
54 | #[salsa::interned] | ||
55 | fn intern_impl(&self, impl_: Impl) -> ids::GlobalImplId; | ||
56 | } | ||
57 | |||
58 | /// This database has access to source code, so queries here are not really | ||
59 | /// incremental. | ||
60 | #[salsa::query_group(AstDatabaseStorage)] | ||
61 | pub trait AstDatabase: InternDatabase { | ||
62 | #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)] | ||
63 | fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; | ||
64 | |||
65 | #[salsa::transparent] | ||
66 | #[salsa::invoke(crate::source_id::AstIdMap::file_item_query)] | ||
67 | fn ast_id_to_node(&self, file_id: HirFileId, ast_id: ErasedFileAstId) -> SyntaxNode; | ||
68 | |||
69 | #[salsa::transparent] | ||
70 | #[salsa::invoke(crate::ids::HirFileId::parse_or_expand_query)] | ||
71 | fn parse_or_expand(&self, file_id: HirFileId) -> Option<SyntaxNode>; | ||
72 | |||
73 | #[salsa::invoke(crate::ids::HirFileId::parse_macro_query)] | ||
74 | fn parse_macro(&self, macro_file: ids::MacroFile) -> Option<Parse<SyntaxNode>>; | ||
75 | |||
76 | #[salsa::invoke(crate::ids::macro_def_query)] | ||
77 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; | ||
78 | |||
79 | #[salsa::invoke(crate::ids::macro_arg_query)] | ||
80 | fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option<Arc<tt::Subtree>>; | ||
81 | |||
82 | #[salsa::invoke(crate::ids::macro_expand_query)] | ||
83 | fn macro_expand(&self, macro_call: ids::MacroCallId) -> Result<Arc<tt::Subtree>, String>; | ||
84 | } | ||
85 | 34 | ||
86 | // This database uses `AstDatabase` internally, | 35 | // This database uses `AstDatabase` internally, |
87 | #[salsa::query_group(DefDatabaseStorage)] | 36 | #[salsa::query_group(DefDatabaseStorage)] |
88 | #[salsa::requires(AstDatabase)] | 37 | #[salsa::requires(AstDatabase)] |
89 | pub trait DefDatabase: InternDatabase + HirDebugDatabase { | 38 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { |
90 | #[salsa::invoke(crate::adt::StructData::struct_data_query)] | 39 | #[salsa::invoke(crate::adt::StructData::struct_data_query)] |
91 | fn struct_data(&self, s: Struct) -> Arc<StructData>; | 40 | fn struct_data(&self, s: Struct) -> Arc<StructData>; |
92 | 41 | ||
@@ -99,15 +48,6 @@ pub trait DefDatabase: InternDatabase + HirDebugDatabase { | |||
99 | #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] | 48 | #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] |
100 | fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; | 49 | fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; |
101 | 50 | ||
102 | #[salsa::invoke(RawItems::raw_items_with_source_map_query)] | ||
103 | fn raw_items_with_source_map( | ||
104 | &self, | ||
105 | file_id: HirFileId, | ||
106 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>); | ||
107 | |||
108 | #[salsa::invoke(RawItems::raw_items_query)] | ||
109 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; | ||
110 | |||
111 | #[salsa::invoke(CrateDefMap::crate_def_map_query)] | 51 | #[salsa::invoke(CrateDefMap::crate_def_map_query)] |
112 | fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>; | 52 | fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>; |
113 | 53 | ||
@@ -202,6 +142,12 @@ pub trait HirDatabase: DefDatabase + AstDatabase { | |||
202 | #[salsa::invoke(crate::ty::traits::trait_solver_query)] | 142 | #[salsa::invoke(crate::ty::traits::trait_solver_query)] |
203 | fn trait_solver(&self, krate: Crate) -> crate::ty::traits::TraitSolver; | 143 | fn trait_solver(&self, krate: Crate) -> crate::ty::traits::TraitSolver; |
204 | 144 | ||
145 | // Interned IDs for Chalk integration | ||
146 | #[salsa::interned] | ||
147 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId; | ||
148 | #[salsa::interned] | ||
149 | fn intern_impl(&self, impl_: Impl) -> ids::GlobalImplId; | ||
150 | |||
205 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] | 151 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] |
206 | fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>; | 152 | fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>; |
207 | 153 | ||
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs index 48b69000b..4f3e922c3 100644 --- a/crates/ra_hir/src/debug.rs +++ b/crates/ra_hir/src/debug.rs | |||
@@ -36,12 +36,6 @@ impl Module { | |||
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | impl HirFileId { | ||
40 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | ||
41 | debug_fn(move |fmt| db.debug_hir_file_id(self, fmt)) | ||
42 | } | ||
43 | } | ||
44 | |||
45 | pub trait HirDebugHelper: HirDatabase { | 39 | pub trait HirDebugHelper: HirDatabase { |
46 | fn crate_name(&self, _krate: CrateId) -> Option<String> { | 40 | fn crate_name(&self, _krate: CrateId) -> Option<String> { |
47 | None | 41 | None |
diff --git a/crates/ra_hir/src/either.rs b/crates/ra_hir/src/either.rs deleted file mode 100644 index 83583ef8b..000000000 --- a/crates/ra_hir/src/either.rs +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
4 | pub enum Either<A, B> { | ||
5 | A(A), | ||
6 | B(B), | ||
7 | } | ||
8 | |||
9 | impl<A, B> Either<A, B> { | ||
10 | pub fn either<R, F1, F2>(self, f1: F1, f2: F2) -> R | ||
11 | where | ||
12 | F1: FnOnce(A) -> R, | ||
13 | F2: FnOnce(B) -> R, | ||
14 | { | ||
15 | match self { | ||
16 | Either::A(a) => f1(a), | ||
17 | Either::B(b) => f2(b), | ||
18 | } | ||
19 | } | ||
20 | pub fn map<U, V, F1, F2>(self, f1: F1, f2: F2) -> Either<U, V> | ||
21 | where | ||
22 | F1: FnOnce(A) -> U, | ||
23 | F2: FnOnce(B) -> V, | ||
24 | { | ||
25 | match self { | ||
26 | Either::A(a) => Either::A(f1(a)), | ||
27 | Either::B(b) => Either::B(f2(b)), | ||
28 | } | ||
29 | } | ||
30 | pub fn map_a<U, F>(self, f: F) -> Either<U, B> | ||
31 | where | ||
32 | F: FnOnce(A) -> U, | ||
33 | { | ||
34 | self.map(f, |it| it) | ||
35 | } | ||
36 | pub fn a(self) -> Option<A> { | ||
37 | match self { | ||
38 | Either::A(it) => Some(it), | ||
39 | Either::B(_) => None, | ||
40 | } | ||
41 | } | ||
42 | pub fn b(self) -> Option<B> { | ||
43 | match self { | ||
44 | Either::A(_) => None, | ||
45 | Either::B(it) => Some(it), | ||
46 | } | ||
47 | } | ||
48 | pub fn as_ref(&self) -> Either<&A, &B> { | ||
49 | match self { | ||
50 | Either::A(it) => Either::A(it), | ||
51 | Either::B(it) => Either::B(it), | ||
52 | } | ||
53 | } | ||
54 | } | ||
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index d238741ba..6e23197a4 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -6,15 +6,17 @@ pub(crate) mod validation; | |||
6 | 6 | ||
7 | use std::{ops::Index, sync::Arc}; | 7 | use std::{ops::Index, sync::Arc}; |
8 | 8 | ||
9 | use hir_def::{ | ||
10 | path::GenericArgs, | ||
11 | type_ref::{Mutability, TypeRef}, | ||
12 | }; | ||
9 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | 13 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
10 | use ra_syntax::{ast, AstPtr}; | 14 | use ra_syntax::{ast, AstPtr}; |
11 | use rustc_hash::FxHashMap; | 15 | use rustc_hash::FxHashMap; |
12 | 16 | ||
13 | use crate::{ | 17 | use crate::{ |
14 | db::HirDatabase, | 18 | db::HirDatabase, |
15 | path::GenericArgs, | ||
16 | ty::primitive::{UncertainFloatTy, UncertainIntTy}, | 19 | ty::primitive::{UncertainFloatTy, UncertainIntTy}, |
17 | type_ref::{Mutability, TypeRef}, | ||
18 | DefWithBody, Either, HasSource, Name, Path, Resolver, Source, | 20 | DefWithBody, Either, HasSource, Name, Path, Resolver, Source, |
19 | }; | 21 | }; |
20 | 22 | ||
diff --git a/crates/ra_hir/src/expr/lower.rs b/crates/ra_hir/src/expr/lower.rs index 50ea429ea..6463dd65e 100644 --- a/crates/ra_hir/src/expr/lower.rs +++ b/crates/ra_hir/src/expr/lower.rs | |||
@@ -1,5 +1,10 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{path::GenericArgs, type_ref::TypeRef}; | ||
4 | use hir_expand::{ | ||
5 | hygiene::Hygiene, | ||
6 | name::{self, AsName, Name}, | ||
7 | }; | ||
3 | use ra_arena::Arena; | 8 | use ra_arena::Arena; |
4 | use ra_syntax::{ | 9 | use ra_syntax::{ |
5 | ast::{ | 10 | ast::{ |
@@ -12,11 +17,8 @@ use test_utils::tested_by; | |||
12 | 17 | ||
13 | use crate::{ | 18 | use crate::{ |
14 | db::HirDatabase, | 19 | db::HirDatabase, |
15 | name::{AsName, Name, SELF_PARAM}, | ||
16 | path::GenericArgs, | ||
17 | ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, | 20 | ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, |
18 | type_ref::TypeRef, | 21 | AstId, DefWithBody, Either, HirFileId, MacroCallLoc, MacroFileKind, Mutability, Path, Resolver, |
19 | DefWithBody, Either, HirFileId, MacroCallLoc, MacroFileKind, Mutability, Path, Resolver, | ||
20 | Source, | 22 | Source, |
21 | }; | 23 | }; |
22 | 24 | ||
@@ -78,7 +80,7 @@ where | |||
78 | let ptr = AstPtr::new(&self_param); | 80 | let ptr = AstPtr::new(&self_param); |
79 | let param_pat = self.alloc_pat( | 81 | let param_pat = self.alloc_pat( |
80 | Pat::Bind { | 82 | Pat::Bind { |
81 | name: SELF_PARAM, | 83 | name: name::SELF_PARAM, |
82 | mode: BindingAnnotation::Unannotated, | 84 | mode: BindingAnnotation::Unannotated, |
83 | subpat: None, | 85 | subpat: None, |
84 | }, | 86 | }, |
@@ -458,15 +460,14 @@ where | |||
458 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 460 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
459 | ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 461 | ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
460 | ast::Expr::MacroCall(e) => { | 462 | ast::Expr::MacroCall(e) => { |
461 | let ast_id = self | 463 | let ast_id = AstId::new( |
462 | .db | 464 | self.current_file_id, |
463 | .ast_id_map(self.current_file_id) | 465 | self.db.ast_id_map(self.current_file_id).ast_id(&e), |
464 | .ast_id(&e) | 466 | ); |
465 | .with_file_id(self.current_file_id); | ||
466 | 467 | ||
467 | if let Some(path) = e.path().and_then(|path| self.parse_path(path)) { | 468 | if let Some(path) = e.path().and_then(|path| self.parse_path(path)) { |
468 | if let Some(def) = self.resolver.resolve_path_as_macro(self.db, &path) { | 469 | if let Some(def) = self.resolver.resolve_path_as_macro(self.db, &path) { |
469 | let call_id = MacroCallLoc { def: def.id, ast_id }.id(self.db); | 470 | let call_id = self.db.intern_macro(MacroCallLoc { def: def.id, ast_id }); |
470 | let file_id = call_id.as_file(MacroFileKind::Expr); | 471 | let file_id = call_id.as_file(MacroFileKind::Expr); |
471 | if let Some(node) = self.db.parse_or_expand(file_id) { | 472 | if let Some(node) = self.db.parse_or_expand(file_id) { |
472 | if let Some(expr) = ast::Expr::cast(node) { | 473 | if let Some(expr) = ast::Expr::cast(node) { |
@@ -596,7 +597,8 @@ where | |||
596 | } | 597 | } |
597 | 598 | ||
598 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 599 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { |
599 | Path::from_src(Source { ast: path, file_id: self.current_file_id }, self.db) | 600 | let hygiene = Hygiene::new(self.db, self.current_file_id); |
601 | Path::from_src(path, &hygiene) | ||
600 | } | 602 | } |
601 | } | 603 | } |
602 | 604 | ||
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs index 1aa853c3e..c685edda1 100644 --- a/crates/ra_hir/src/expr/validation.rs +++ b/crates/ra_hir/src/expr/validation.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::path::known; | ||
5 | use ra_syntax::ast; | 6 | use ra_syntax::ast; |
6 | use rustc_hash::FxHashSet; | 7 | use rustc_hash::FxHashSet; |
7 | 8 | ||
@@ -9,7 +10,6 @@ use crate::{ | |||
9 | db::HirDatabase, | 10 | db::HirDatabase, |
10 | diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr}, | 11 | diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr}, |
11 | expr::AstPtr, | 12 | expr::AstPtr, |
12 | path::known, | ||
13 | ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, | 13 | ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, |
14 | Adt, Function, Name, Path, | 14 | Adt, Function, Name, Path, |
15 | }; | 15 | }; |
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index f80d8eb5f..a9de01455 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -1,17 +1,12 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use ra_db::{FileId, FilePosition}; | 3 | use hir_expand::name::AsName; |
4 | use ra_syntax::{ | 4 | use ra_syntax::ast::{self, AstNode, NameOwner}; |
5 | algo::find_node_at_offset, | ||
6 | ast::{self, AstNode, NameOwner}, | ||
7 | SyntaxNode, | ||
8 | }; | ||
9 | 5 | ||
10 | use crate::{ | 6 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 7 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | ids::{AstItemDef, LocationCtx}, | 8 | ids::{AstItemDef, LocationCtx}, |
13 | name::AsName, | 9 | AstId, Const, Crate, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, Module, |
14 | Const, Crate, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, Module, | ||
15 | ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, | 10 | ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, |
16 | }; | 11 | }; |
17 | 12 | ||
@@ -129,41 +124,6 @@ impl FromSource for StructField { | |||
129 | } | 124 | } |
130 | } | 125 | } |
131 | 126 | ||
132 | // FIXME: simplify it | ||
133 | impl ModuleSource { | ||
134 | pub fn from_position( | ||
135 | db: &(impl DefDatabase + AstDatabase), | ||
136 | position: FilePosition, | ||
137 | ) -> ModuleSource { | ||
138 | let parse = db.parse(position.file_id); | ||
139 | match &find_node_at_offset::<ast::Module>(parse.tree().syntax(), position.offset) { | ||
140 | Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()), | ||
141 | _ => { | ||
142 | let source_file = parse.tree(); | ||
143 | ModuleSource::SourceFile(source_file) | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
148 | pub fn from_child_node( | ||
149 | db: &(impl DefDatabase + AstDatabase), | ||
150 | file_id: FileId, | ||
151 | child: &SyntaxNode, | ||
152 | ) -> ModuleSource { | ||
153 | if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { | ||
154 | ModuleSource::Module(m) | ||
155 | } else { | ||
156 | let source_file = db.parse(file_id).tree(); | ||
157 | ModuleSource::SourceFile(source_file) | ||
158 | } | ||
159 | } | ||
160 | |||
161 | pub fn from_file_id(db: &(impl DefDatabase + AstDatabase), file_id: FileId) -> ModuleSource { | ||
162 | let source_file = db.parse(file_id).tree(); | ||
163 | ModuleSource::SourceFile(source_file) | ||
164 | } | ||
165 | } | ||
166 | |||
167 | impl Module { | 127 | impl Module { |
168 | pub fn from_declaration(db: &impl HirDatabase, src: Source<ast::Module>) -> Option<Self> { | 128 | pub fn from_declaration(db: &impl HirDatabase, src: Source<ast::Module>) -> Option<Self> { |
169 | let src_parent = Source { | 129 | let src_parent = Source { |
@@ -183,7 +143,7 @@ impl Module { | |||
183 | ModuleSource::Module(ref module) => { | 143 | ModuleSource::Module(ref module) => { |
184 | assert!(!module.has_semi()); | 144 | assert!(!module.has_semi()); |
185 | let ast_id_map = db.ast_id_map(src.file_id); | 145 | let ast_id_map = db.ast_id_map(src.file_id); |
186 | let item_id = ast_id_map.ast_id(module).with_file_id(src.file_id); | 146 | let item_id = AstId::new(src.file_id, ast_id_map.ast_id(module)); |
187 | Some(item_id) | 147 | Some(item_id) |
188 | } | 148 | } |
189 | ModuleSource::SourceFile(_) => None, | 149 | ModuleSource::SourceFile(_) => None, |
@@ -195,7 +155,7 @@ impl Module { | |||
195 | .find_map(|krate| { | 155 | .find_map(|krate| { |
196 | let def_map = db.crate_def_map(krate); | 156 | let def_map = db.crate_def_map(krate); |
197 | let module_id = def_map.find_module_by_source(src.file_id, decl_id)?; | 157 | let module_id = def_map.find_module_by_source(src.file_id, decl_id)?; |
198 | Some(Module { krate, module_id }) | 158 | Some(Module::new(krate, module_id)) |
199 | }) | 159 | }) |
200 | } | 160 | } |
201 | } | 161 | } |
@@ -208,6 +168,6 @@ where | |||
208 | let module_src = | 168 | let module_src = |
209 | crate::ModuleSource::from_child_node(db, src.file_id.original_file(db), &src.ast.syntax()); | 169 | crate::ModuleSource::from_child_node(db, src.file_id.original_file(db), &src.ast.syntax()); |
210 | let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?; | 170 | let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?; |
211 | let ctx = LocationCtx::new(db, module, src.file_id); | 171 | let ctx = LocationCtx::new(db, module.id, src.file_id); |
212 | Some(DEF::from_ast(ctx, &src.ast)) | 172 | Some(DEF::from_ast(ctx, &src.ast)) |
213 | } | 173 | } |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 4ce7551c3..52e1fbf29 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -5,15 +5,17 @@ | |||
5 | 5 | ||
6 | use std::sync::Arc; | 6 | use std::sync::Arc; |
7 | 7 | ||
8 | use hir_def::{ | ||
9 | path::Path, | ||
10 | type_ref::{TypeBound, TypeRef}, | ||
11 | }; | ||
12 | use hir_expand::name::{self, AsName}; | ||
8 | use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner}; | 13 | use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner}; |
9 | 14 | ||
10 | use crate::{ | 15 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 16 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | name::SELF_TYPE, | 17 | Adt, Const, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, Trait, |
13 | path::Path, | 18 | TypeAlias, Union, |
14 | type_ref::{TypeBound, TypeRef}, | ||
15 | Adt, AsName, Const, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, | ||
16 | Trait, TypeAlias, Union, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | /// Data about a generic parameter (to a function, struct, impl, ...). | 21 | /// Data about a generic parameter (to a function, struct, impl, ...). |
@@ -94,11 +96,15 @@ impl GenericParams { | |||
94 | GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).ast, start), | 96 | GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).ast, start), |
95 | GenericDef::Trait(it) => { | 97 | GenericDef::Trait(it) => { |
96 | // traits get the Self type as an implicit first type parameter | 98 | // traits get the Self type as an implicit first type parameter |
97 | generics.params.push(GenericParam { idx: start, name: SELF_TYPE, default: None }); | 99 | generics.params.push(GenericParam { |
100 | idx: start, | ||
101 | name: name::SELF_TYPE, | ||
102 | default: None, | ||
103 | }); | ||
98 | generics.fill(&it.source(db).ast, start + 1); | 104 | generics.fill(&it.source(db).ast, start + 1); |
99 | // add super traits as bounds on Self | 105 | // add super traits as bounds on Self |
100 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar | 106 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar |
101 | let self_param = TypeRef::Path(SELF_TYPE.into()); | 107 | let self_param = TypeRef::Path(name::SELF_TYPE.into()); |
102 | generics.fill_bounds(&it.source(db).ast, self_param); | 108 | generics.fill_bounds(&it.source(db).ast, self_param); |
103 | } | 109 | } |
104 | GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), | 110 | GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 499dcafea..fe083c0c6 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,168 +1,17 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! hir makes heavy use of ids: integer (u32) handlers to various things. You |
2 | 2 | //! can think of id as a pointer (but without a lifetime) or a file descriptor | |
3 | use std::{ | 3 | //! (but for hir objects). |
4 | hash::{Hash, Hasher}, | 4 | //! |
5 | sync::Arc, | 5 | //! This module defines a bunch of ids we are using. The most important ones are |
6 | }; | 6 | //! probably `HirFileId` and `DefId`. |
7 | 7 | ||
8 | use mbe::MacroRules; | 8 | use ra_db::salsa; |
9 | use ra_db::{salsa, FileId}; | 9 | |
10 | use ra_prof::profile; | 10 | pub use hir_def::{ |
11 | use ra_syntax::{ast, AstNode, Parse, SyntaxNode}; | 11 | AstItemDef, ConstId, EnumId, FunctionId, ItemLoc, LocationCtx, StaticId, StructId, TraitId, |
12 | 12 | TypeAliasId, | |
13 | use crate::{ | ||
14 | db::{AstDatabase, DefDatabase, InternDatabase}, | ||
15 | AstId, Crate, FileAstId, Module, Source, | ||
16 | }; | 13 | }; |
17 | 14 | pub use hir_expand::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, MacroFileKind}; | |
18 | /// hir makes heavy use of ids: integer (u32) handlers to various things. You | ||
19 | /// can think of id as a pointer (but without a lifetime) or a file descriptor | ||
20 | /// (but for hir objects). | ||
21 | /// | ||
22 | /// This module defines a bunch of ids we are using. The most important ones are | ||
23 | /// probably `HirFileId` and `DefId`. | ||
24 | |||
25 | /// Input to the analyzer is a set of files, where each file is identified by | ||
26 | /// `FileId` and contains source code. However, another source of source code in | ||
27 | /// Rust are macros: each macro can be thought of as producing a "temporary | ||
28 | /// file". To assign an id to such a file, we use the id of the macro call that | ||
29 | /// produced the file. So, a `HirFileId` is either a `FileId` (source code | ||
30 | /// written by user), or a `MacroCallId` (source code produced by macro). | ||
31 | /// | ||
32 | /// What is a `MacroCallId`? Simplifying, it's a `HirFileId` of a file | ||
33 | /// containing the call plus the offset of the macro call in the file. Note that | ||
34 | /// this is a recursive definition! However, the size_of of `HirFileId` is | ||
35 | /// finite (because everything bottoms out at the real `FileId`) and small | ||
36 | /// (`MacroCallId` uses the location interner). | ||
37 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
38 | pub struct HirFileId(HirFileIdRepr); | ||
39 | |||
40 | impl HirFileId { | ||
41 | /// For macro-expansion files, returns the file original source file the | ||
42 | /// expansion originated from. | ||
43 | pub fn original_file(self, db: &impl InternDatabase) -> FileId { | ||
44 | match self.0 { | ||
45 | HirFileIdRepr::File(file_id) => file_id, | ||
46 | HirFileIdRepr::Macro(macro_file) => { | ||
47 | let loc = macro_file.macro_call_id.loc(db); | ||
48 | loc.ast_id.file_id().original_file(db) | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | |||
53 | /// Get the crate which the macro lives in, if it is a macro file. | ||
54 | pub(crate) fn macro_crate(self, db: &impl AstDatabase) -> Option<Crate> { | ||
55 | match self.0 { | ||
56 | HirFileIdRepr::File(_) => None, | ||
57 | HirFileIdRepr::Macro(macro_file) => { | ||
58 | let loc = macro_file.macro_call_id.loc(db); | ||
59 | Some(loc.def.krate) | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | |||
64 | pub(crate) fn parse_or_expand_query( | ||
65 | db: &impl AstDatabase, | ||
66 | file_id: HirFileId, | ||
67 | ) -> Option<SyntaxNode> { | ||
68 | match file_id.0 { | ||
69 | HirFileIdRepr::File(file_id) => Some(db.parse(file_id).tree().syntax().clone()), | ||
70 | HirFileIdRepr::Macro(macro_file) => { | ||
71 | db.parse_macro(macro_file).map(|it| it.syntax_node()) | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | |||
76 | pub(crate) fn parse_macro_query( | ||
77 | db: &impl AstDatabase, | ||
78 | macro_file: MacroFile, | ||
79 | ) -> Option<Parse<SyntaxNode>> { | ||
80 | let _p = profile("parse_macro_query"); | ||
81 | let macro_call_id = macro_file.macro_call_id; | ||
82 | let tt = db | ||
83 | .macro_expand(macro_call_id) | ||
84 | .map_err(|err| { | ||
85 | // Note: | ||
86 | // The final goal we would like to make all parse_macro success, | ||
87 | // such that the following log will not call anyway. | ||
88 | log::warn!("fail on macro_parse: (reason: {})", err,); | ||
89 | }) | ||
90 | .ok()?; | ||
91 | match macro_file.macro_file_kind { | ||
92 | MacroFileKind::Items => mbe::token_tree_to_items(&tt).ok().map(Parse::to_syntax), | ||
93 | MacroFileKind::Expr => mbe::token_tree_to_expr(&tt).ok().map(Parse::to_syntax), | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
99 | enum HirFileIdRepr { | ||
100 | File(FileId), | ||
101 | Macro(MacroFile), | ||
102 | } | ||
103 | |||
104 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
105 | pub struct MacroFile { | ||
106 | macro_call_id: MacroCallId, | ||
107 | macro_file_kind: MacroFileKind, | ||
108 | } | ||
109 | |||
110 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
111 | pub(crate) enum MacroFileKind { | ||
112 | Items, | ||
113 | Expr, | ||
114 | } | ||
115 | |||
116 | impl From<FileId> for HirFileId { | ||
117 | fn from(file_id: FileId) -> HirFileId { | ||
118 | HirFileId(HirFileIdRepr::File(file_id)) | ||
119 | } | ||
120 | } | ||
121 | |||
122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
123 | pub struct MacroDefId { | ||
124 | pub(crate) ast_id: AstId<ast::MacroCall>, | ||
125 | pub(crate) krate: Crate, | ||
126 | } | ||
127 | |||
128 | pub(crate) fn macro_def_query(db: &impl AstDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { | ||
129 | let macro_call = id.ast_id.to_node(db); | ||
130 | let arg = macro_call.token_tree()?; | ||
131 | let (tt, _) = mbe::ast_to_token_tree(&arg).or_else(|| { | ||
132 | log::warn!("fail on macro_def to token tree: {:#?}", arg); | ||
133 | None | ||
134 | })?; | ||
135 | let rules = MacroRules::parse(&tt).ok().or_else(|| { | ||
136 | log::warn!("fail on macro_def parse: {:#?}", tt); | ||
137 | None | ||
138 | })?; | ||
139 | Some(Arc::new(rules)) | ||
140 | } | ||
141 | |||
142 | pub(crate) fn macro_arg_query(db: &impl AstDatabase, id: MacroCallId) -> Option<Arc<tt::Subtree>> { | ||
143 | let loc = id.loc(db); | ||
144 | let macro_call = loc.ast_id.to_node(db); | ||
145 | let arg = macro_call.token_tree()?; | ||
146 | let (tt, _) = mbe::ast_to_token_tree(&arg)?; | ||
147 | Some(Arc::new(tt)) | ||
148 | } | ||
149 | |||
150 | pub(crate) fn macro_expand_query( | ||
151 | db: &impl AstDatabase, | ||
152 | id: MacroCallId, | ||
153 | ) -> Result<Arc<tt::Subtree>, String> { | ||
154 | let loc = id.loc(db); | ||
155 | let macro_arg = db.macro_arg(id).ok_or("Fail to args in to tt::TokenTree")?; | ||
156 | |||
157 | let macro_rules = db.macro_def(loc.def).ok_or("Fail to find macro definition")?; | ||
158 | let tt = macro_rules.expand(¯o_arg).map_err(|err| format!("{:?}", err))?; | ||
159 | // Set a hard limit for the expanded tt | ||
160 | let count = tt.count(); | ||
161 | if count > 65536 { | ||
162 | return Err(format!("Total tokens count exceed limit : count = {}", count)); | ||
163 | } | ||
164 | Ok(Arc::new(tt)) | ||
165 | } | ||
166 | 15 | ||
167 | macro_rules! impl_intern_key { | 16 | macro_rules! impl_intern_key { |
168 | ($name:ident) => { | 17 | ($name:ident) => { |
@@ -177,192 +26,6 @@ macro_rules! impl_intern_key { | |||
177 | }; | 26 | }; |
178 | } | 27 | } |
179 | 28 | ||
180 | /// `MacroCallId` identifies a particular macro invocation, like | ||
181 | /// `println!("Hello, {}", world)`. | ||
182 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
183 | pub struct MacroCallId(salsa::InternId); | ||
184 | impl_intern_key!(MacroCallId); | ||
185 | |||
186 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
187 | pub struct MacroCallLoc { | ||
188 | pub(crate) def: MacroDefId, | ||
189 | pub(crate) ast_id: AstId<ast::MacroCall>, | ||
190 | } | ||
191 | |||
192 | impl MacroCallId { | ||
193 | pub(crate) fn loc(self, db: &impl InternDatabase) -> MacroCallLoc { | ||
194 | db.lookup_intern_macro(self) | ||
195 | } | ||
196 | |||
197 | pub(crate) fn as_file(self, kind: MacroFileKind) -> HirFileId { | ||
198 | let macro_file = MacroFile { macro_call_id: self, macro_file_kind: kind }; | ||
199 | HirFileId(HirFileIdRepr::Macro(macro_file)) | ||
200 | } | ||
201 | } | ||
202 | |||
203 | impl MacroCallLoc { | ||
204 | pub(crate) fn id(self, db: &impl InternDatabase) -> MacroCallId { | ||
205 | db.intern_macro(self) | ||
206 | } | ||
207 | } | ||
208 | |||
209 | #[derive(Debug)] | ||
210 | pub struct ItemLoc<N: AstNode> { | ||
211 | pub(crate) module: Module, | ||
212 | ast_id: AstId<N>, | ||
213 | } | ||
214 | |||
215 | impl<N: AstNode> PartialEq for ItemLoc<N> { | ||
216 | fn eq(&self, other: &Self) -> bool { | ||
217 | self.module == other.module && self.ast_id == other.ast_id | ||
218 | } | ||
219 | } | ||
220 | impl<N: AstNode> Eq for ItemLoc<N> {} | ||
221 | impl<N: AstNode> Hash for ItemLoc<N> { | ||
222 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
223 | self.module.hash(hasher); | ||
224 | self.ast_id.hash(hasher); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | impl<N: AstNode> Clone for ItemLoc<N> { | ||
229 | fn clone(&self) -> ItemLoc<N> { | ||
230 | ItemLoc { module: self.module, ast_id: self.ast_id } | ||
231 | } | ||
232 | } | ||
233 | |||
234 | #[derive(Clone, Copy)] | ||
235 | pub(crate) struct LocationCtx<DB> { | ||
236 | db: DB, | ||
237 | module: Module, | ||
238 | file_id: HirFileId, | ||
239 | } | ||
240 | |||
241 | impl<'a, DB: DefDatabase> LocationCtx<&'a DB> { | ||
242 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { | ||
243 | LocationCtx { db, module, file_id } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | impl<'a, DB: DefDatabase + AstDatabase> LocationCtx<&'a DB> { | ||
248 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF | ||
249 | where | ||
250 | N: AstNode, | ||
251 | DEF: AstItemDef<N>, | ||
252 | { | ||
253 | DEF::from_ast(self, ast) | ||
254 | } | ||
255 | } | ||
256 | |||
257 | pub(crate) trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | ||
258 | fn intern(db: &impl DefDatabase, loc: ItemLoc<N>) -> Self; | ||
259 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<N>; | ||
260 | |||
261 | fn from_ast(ctx: LocationCtx<&(impl AstDatabase + DefDatabase)>, ast: &N) -> Self { | ||
262 | let items = ctx.db.ast_id_map(ctx.file_id); | ||
263 | let item_id = items.ast_id(ast); | ||
264 | Self::from_ast_id(ctx, item_id) | ||
265 | } | ||
266 | fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self { | ||
267 | let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; | ||
268 | Self::intern(ctx.db, loc) | ||
269 | } | ||
270 | fn source(self, db: &(impl AstDatabase + DefDatabase)) -> Source<N> { | ||
271 | let loc = self.lookup_intern(db); | ||
272 | let ast = loc.ast_id.to_node(db); | ||
273 | Source { file_id: loc.ast_id.file_id(), ast } | ||
274 | } | ||
275 | fn module(self, db: &impl DefDatabase) -> Module { | ||
276 | let loc = self.lookup_intern(db); | ||
277 | loc.module | ||
278 | } | ||
279 | } | ||
280 | |||
281 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
282 | pub struct FunctionId(salsa::InternId); | ||
283 | impl_intern_key!(FunctionId); | ||
284 | |||
285 | impl AstItemDef<ast::FnDef> for FunctionId { | ||
286 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::FnDef>) -> Self { | ||
287 | db.intern_function(loc) | ||
288 | } | ||
289 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::FnDef> { | ||
290 | db.lookup_intern_function(self) | ||
291 | } | ||
292 | } | ||
293 | |||
294 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
295 | pub struct StructId(salsa::InternId); | ||
296 | impl_intern_key!(StructId); | ||
297 | impl AstItemDef<ast::StructDef> for StructId { | ||
298 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::StructDef>) -> Self { | ||
299 | db.intern_struct(loc) | ||
300 | } | ||
301 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::StructDef> { | ||
302 | db.lookup_intern_struct(self) | ||
303 | } | ||
304 | } | ||
305 | |||
306 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
307 | pub struct EnumId(salsa::InternId); | ||
308 | impl_intern_key!(EnumId); | ||
309 | impl AstItemDef<ast::EnumDef> for EnumId { | ||
310 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::EnumDef>) -> Self { | ||
311 | db.intern_enum(loc) | ||
312 | } | ||
313 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::EnumDef> { | ||
314 | db.lookup_intern_enum(self) | ||
315 | } | ||
316 | } | ||
317 | |||
318 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
319 | pub struct ConstId(salsa::InternId); | ||
320 | impl_intern_key!(ConstId); | ||
321 | impl AstItemDef<ast::ConstDef> for ConstId { | ||
322 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::ConstDef>) -> Self { | ||
323 | db.intern_const(loc) | ||
324 | } | ||
325 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::ConstDef> { | ||
326 | db.lookup_intern_const(self) | ||
327 | } | ||
328 | } | ||
329 | |||
330 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
331 | pub struct StaticId(salsa::InternId); | ||
332 | impl_intern_key!(StaticId); | ||
333 | impl AstItemDef<ast::StaticDef> for StaticId { | ||
334 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::StaticDef>) -> Self { | ||
335 | db.intern_static(loc) | ||
336 | } | ||
337 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::StaticDef> { | ||
338 | db.lookup_intern_static(self) | ||
339 | } | ||
340 | } | ||
341 | |||
342 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
343 | pub struct TraitId(salsa::InternId); | ||
344 | impl_intern_key!(TraitId); | ||
345 | impl AstItemDef<ast::TraitDef> for TraitId { | ||
346 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::TraitDef>) -> Self { | ||
347 | db.intern_trait(loc) | ||
348 | } | ||
349 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::TraitDef> { | ||
350 | db.lookup_intern_trait(self) | ||
351 | } | ||
352 | } | ||
353 | |||
354 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
355 | pub struct TypeAliasId(salsa::InternId); | ||
356 | impl_intern_key!(TypeAliasId); | ||
357 | impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { | ||
358 | fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self { | ||
359 | db.intern_type_alias(loc) | ||
360 | } | ||
361 | fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::TypeAliasDef> { | ||
362 | db.lookup_intern_type_alias(self) | ||
363 | } | ||
364 | } | ||
365 | |||
366 | /// This exists just for Chalk, because Chalk just has a single `StructId` where | 29 | /// This exists just for Chalk, because Chalk just has a single `StructId` where |
367 | /// we have different kinds of ADTs, primitive types and special type | 30 | /// we have different kinds of ADTs, primitive types and special type |
368 | /// constructors like tuples and function pointers. | 31 | /// constructors like tuples and function pointers. |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 33ef87563..b1a014074 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -3,6 +3,8 @@ | |||
3 | use rustc_hash::FxHashMap; | 3 | use rustc_hash::FxHashMap; |
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use hir_def::{attr::Attr, type_ref::TypeRef}; | ||
7 | use hir_expand::hygiene::Hygiene; | ||
6 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | 8 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
7 | use ra_cfg::CfgOptions; | 9 | use ra_cfg::CfgOptions; |
8 | use ra_syntax::{ | 10 | use ra_syntax::{ |
@@ -11,7 +13,6 @@ use ra_syntax::{ | |||
11 | }; | 13 | }; |
12 | 14 | ||
13 | use crate::{ | 15 | use crate::{ |
14 | attr::Attr, | ||
15 | code_model::{Module, ModuleSource}, | 16 | code_model::{Module, ModuleSource}, |
16 | db::{AstDatabase, DefDatabase, HirDatabase}, | 17 | db::{AstDatabase, DefDatabase, HirDatabase}, |
17 | generics::HasGenericParams, | 18 | generics::HasGenericParams, |
@@ -19,8 +20,7 @@ use crate::{ | |||
19 | ids::MacroCallLoc, | 20 | ids::MacroCallLoc, |
20 | resolve::Resolver, | 21 | resolve::Resolver, |
21 | ty::Ty, | 22 | ty::Ty, |
22 | type_ref::TypeRef, | 23 | AssocItem, AstId, Const, Function, HasSource, HirFileId, MacroFileKind, Path, Source, TraitRef, |
23 | AssocItem, Const, Function, HasSource, HirFileId, MacroFileKind, Path, Source, TraitRef, | ||
24 | TypeAlias, | 24 | TypeAlias, |
25 | }; | 25 | }; |
26 | 26 | ||
@@ -129,7 +129,7 @@ impl ImplData { | |||
129 | ) -> Self { | 129 | ) -> Self { |
130 | let target_trait = node.target_trait().map(TypeRef::from_ast); | 130 | let target_trait = node.target_trait().map(TypeRef::from_ast); |
131 | let target_type = TypeRef::from_ast_opt(node.target_type()); | 131 | let target_type = TypeRef::from_ast_opt(node.target_type()); |
132 | let ctx = LocationCtx::new(db, module, file_id); | 132 | let ctx = LocationCtx::new(db, module.id, file_id); |
133 | let negative = node.is_negative(); | 133 | let negative = node.is_negative(); |
134 | let items = if let Some(item_list) = node.item_list() { | 134 | let items = if let Some(item_list) = node.item_list() { |
135 | item_list | 135 | item_list |
@@ -182,7 +182,7 @@ impl ModuleImplBlocks { | |||
182 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { | 182 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { |
183 | let mut source_map = ImplSourceMap::default(); | 183 | let mut source_map = ImplSourceMap::default(); |
184 | let crate_graph = db.crate_graph(); | 184 | let crate_graph = db.crate_graph(); |
185 | let cfg_options = crate_graph.cfg_options(module.krate.crate_id()); | 185 | let cfg_options = crate_graph.cfg_options(module.id.krate); |
186 | 186 | ||
187 | let result = ModuleImplBlocks::collect(db, cfg_options, module, &mut source_map); | 187 | let result = ModuleImplBlocks::collect(db, cfg_options, module, &mut source_map); |
188 | (Arc::new(result), Arc::new(source_map)) | 188 | (Arc::new(result), Arc::new(source_map)) |
@@ -228,10 +228,11 @@ impl ModuleImplBlocks { | |||
228 | owner: &dyn ast::ModuleItemOwner, | 228 | owner: &dyn ast::ModuleItemOwner, |
229 | file_id: HirFileId, | 229 | file_id: HirFileId, |
230 | ) { | 230 | ) { |
231 | let hygiene = Hygiene::new(db, file_id); | ||
231 | for item in owner.items_with_macros() { | 232 | for item in owner.items_with_macros() { |
232 | match item { | 233 | match item { |
233 | ast::ItemOrMacro::Item(ast::ModuleItem::ImplBlock(impl_block_ast)) => { | 234 | ast::ItemOrMacro::Item(ast::ModuleItem::ImplBlock(impl_block_ast)) => { |
234 | let attrs = Attr::from_attrs_owner(file_id, &impl_block_ast, db); | 235 | let attrs = Attr::from_attrs_owner(&impl_block_ast, &hygiene); |
235 | if attrs.map_or(false, |attrs| { | 236 | if attrs.map_or(false, |attrs| { |
236 | attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) | 237 | attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) |
237 | }) { | 238 | }) { |
@@ -248,7 +249,7 @@ impl ModuleImplBlocks { | |||
248 | } | 249 | } |
249 | ast::ItemOrMacro::Item(_) => (), | 250 | ast::ItemOrMacro::Item(_) => (), |
250 | ast::ItemOrMacro::Macro(macro_call) => { | 251 | ast::ItemOrMacro::Macro(macro_call) => { |
251 | let attrs = Attr::from_attrs_owner(file_id, ¯o_call, db); | 252 | let attrs = Attr::from_attrs_owner(¯o_call, &hygiene); |
252 | if attrs.map_or(false, |attrs| { | 253 | if attrs.map_or(false, |attrs| { |
253 | attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) | 254 | attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) |
254 | }) { | 255 | }) { |
@@ -256,14 +257,13 @@ impl ModuleImplBlocks { | |||
256 | } | 257 | } |
257 | 258 | ||
258 | //FIXME: we should really cut down on the boilerplate required to process a macro | 259 | //FIXME: we should really cut down on the boilerplate required to process a macro |
259 | let ast_id = db.ast_id_map(file_id).ast_id(¯o_call).with_file_id(file_id); | 260 | let ast_id = AstId::new(file_id, db.ast_id_map(file_id).ast_id(¯o_call)); |
260 | if let Some(path) = macro_call | 261 | if let Some(path) = |
261 | .path() | 262 | macro_call.path().and_then(|path| Path::from_src(path, &hygiene)) |
262 | .and_then(|path| Path::from_src(Source { ast: path, file_id }, db)) | ||
263 | { | 263 | { |
264 | if let Some(def) = self.module.resolver(db).resolve_path_as_macro(db, &path) | 264 | if let Some(def) = self.module.resolver(db).resolve_path_as_macro(db, &path) |
265 | { | 265 | { |
266 | let call_id = MacroCallLoc { def: def.id, ast_id }.id(db); | 266 | let call_id = db.intern_macro(MacroCallLoc { def: def.id, ast_id }); |
267 | let file_id = call_id.as_file(MacroFileKind::Items); | 267 | let file_id = call_id.as_file(MacroFileKind::Items); |
268 | if let Some(item_list) = | 268 | if let Some(item_list) = |
269 | db.parse_or_expand(file_id).and_then(ast::MacroItems::cast) | 269 | db.parse_or_expand(file_id).and_then(ast::MacroItems::cast) |
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs index 6c4e8ffbd..e1780ed38 100644 --- a/crates/ra_hir/src/lang_item.rs +++ b/crates/ra_hir/src/lang_item.rs | |||
@@ -22,14 +22,14 @@ pub enum LangItemTarget { | |||
22 | 22 | ||
23 | impl LangItemTarget { | 23 | impl LangItemTarget { |
24 | pub(crate) fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { | 24 | pub(crate) fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { |
25 | match self { | 25 | Some(match self { |
26 | LangItemTarget::Enum(e) => e.module(db).krate(db), | 26 | LangItemTarget::Enum(e) => e.module(db).krate(), |
27 | LangItemTarget::Function(f) => f.module(db).krate(db), | 27 | LangItemTarget::Function(f) => f.module(db).krate(), |
28 | LangItemTarget::ImplBlock(i) => i.module().krate(db), | 28 | LangItemTarget::ImplBlock(i) => i.module().krate(), |
29 | LangItemTarget::Static(s) => s.module(db).krate(db), | 29 | LangItemTarget::Static(s) => s.module(db).krate(), |
30 | LangItemTarget::Struct(s) => s.module(db).krate(db), | 30 | LangItemTarget::Struct(s) => s.module(db).krate(), |
31 | LangItemTarget::Trait(t) => t.module(db).krate(db), | 31 | LangItemTarget::Trait(t) => t.module(db).krate(), |
32 | } | 32 | }) |
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index ca261e8f5..40f5562b4 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -26,25 +26,19 @@ macro_rules! impl_froms { | |||
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
29 | mod either; | ||
30 | pub mod debug; | 29 | pub mod debug; |
31 | 30 | ||
32 | pub mod db; | 31 | pub mod db; |
33 | #[macro_use] | 32 | #[macro_use] |
34 | pub mod mock; | 33 | pub mod mock; |
35 | mod path; | ||
36 | pub mod source_binder; | 34 | pub mod source_binder; |
37 | 35 | ||
38 | mod source_id; | ||
39 | mod ids; | 36 | mod ids; |
40 | mod name; | ||
41 | mod nameres; | 37 | mod nameres; |
42 | mod adt; | 38 | mod adt; |
43 | mod traits; | 39 | mod traits; |
44 | mod type_alias; | 40 | mod type_alias; |
45 | mod type_ref; | ||
46 | mod ty; | 41 | mod ty; |
47 | mod attr; | ||
48 | mod impl_block; | 42 | mod impl_block; |
49 | mod expr; | 43 | mod expr; |
50 | mod lang_item; | 44 | mod lang_item; |
@@ -60,37 +54,35 @@ pub mod from_source; | |||
60 | #[cfg(test)] | 54 | #[cfg(test)] |
61 | mod marks; | 55 | mod marks; |
62 | 56 | ||
63 | use crate::{ | 57 | use hir_expand::AstId; |
64 | ids::MacroFileKind, | 58 | |
65 | name::AsName, | 59 | use crate::{ids::MacroFileKind, resolve::Resolver}; |
66 | resolve::Resolver, | ||
67 | source_id::{AstId, FileAstId}, | ||
68 | }; | ||
69 | 60 | ||
70 | pub use self::{ | 61 | pub use crate::{ |
71 | adt::VariantDef, | 62 | adt::VariantDef, |
72 | either::Either, | 63 | code_model::{ |
64 | docs::{DocDef, Docs, Documentation}, | ||
65 | src::{HasBodySource, HasSource, Source}, | ||
66 | Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, | ||
67 | EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef, | ||
68 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | ||
69 | }, | ||
73 | expr::ExprScopes, | 70 | expr::ExprScopes, |
74 | from_source::FromSource, | 71 | from_source::FromSource, |
75 | generics::{GenericDef, GenericParam, GenericParams, HasGenericParams}, | 72 | generics::{GenericDef, GenericParam, GenericParams, HasGenericParams}, |
76 | ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, | 73 | ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, |
77 | impl_block::ImplBlock, | 74 | impl_block::ImplBlock, |
78 | name::Name, | ||
79 | nameres::{ImportId, Namespace, PerNs}, | 75 | nameres::{ImportId, Namespace, PerNs}, |
80 | path::{Path, PathKind}, | ||
81 | resolve::ScopeDef, | 76 | resolve::ScopeDef, |
82 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 77 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
83 | source_id::{AstIdMap, ErasedFileAstId}, | ||
84 | ty::{ | 78 | ty::{ |
85 | display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | 79 | display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, |
86 | }, | 80 | }, |
87 | type_ref::Mutability, | ||
88 | }; | 81 | }; |
89 | 82 | ||
90 | pub use self::code_model::{ | 83 | pub use hir_def::{ |
91 | docs::{DocDef, Docs, Documentation}, | 84 | builtin_type::BuiltinType, |
92 | src::{HasBodySource, HasSource, Source}, | 85 | path::{Path, PathKind}, |
93 | Adt, AssocItem, BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, | 86 | type_ref::Mutability, |
94 | Enum, EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef, | ||
95 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | ||
96 | }; | 87 | }; |
88 | pub use hir_expand::{either::Either, name::Name}; | ||
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs index 79af24b20..b423489a1 100644 --- a/crates/ra_hir/src/marks.rs +++ b/crates/ra_hir/src/marks.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | test_utils::marks!( | 3 | test_utils::marks!( |
4 | bogus_paths | 4 | bogus_paths |
5 | // FIXME: restore this mark once hir is split | ||
5 | name_res_works_for_broken_modules | 6 | name_res_works_for_broken_modules |
6 | can_import_enum_variant | 7 | can_import_enum_variant |
7 | type_var_cycles_resolve_completely | 8 | type_var_cycles_resolve_completely |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 0b278deb3..35dfaf3ba 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -22,6 +22,7 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0); | |||
22 | db::InternDatabaseStorage, | 22 | db::InternDatabaseStorage, |
23 | db::AstDatabaseStorage, | 23 | db::AstDatabaseStorage, |
24 | db::DefDatabaseStorage, | 24 | db::DefDatabaseStorage, |
25 | db::DefDatabase2Storage, | ||
25 | db::HirDatabaseStorage | 26 | db::HirDatabaseStorage |
26 | )] | 27 | )] |
27 | #[derive(Debug)] | 28 | #[derive(Debug)] |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs deleted file mode 100644 index 1e0b8c350..000000000 --- a/crates/ra_hir/src/name.rs +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use std::fmt; | ||
4 | |||
5 | use ra_syntax::{ast, SmolStr}; | ||
6 | |||
7 | /// `Name` is a wrapper around string, which is used in hir for both references | ||
8 | /// and declarations. In theory, names should also carry hygiene info, but we are | ||
9 | /// not there yet! | ||
10 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
11 | pub struct Name(Repr); | ||
12 | |||
13 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
14 | enum Repr { | ||
15 | Text(SmolStr), | ||
16 | TupleField(usize), | ||
17 | } | ||
18 | |||
19 | impl fmt::Display for Name { | ||
20 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
21 | match &self.0 { | ||
22 | Repr::Text(text) => fmt::Display::fmt(&text, f), | ||
23 | Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), | ||
24 | } | ||
25 | } | ||
26 | } | ||
27 | |||
28 | impl Name { | ||
29 | /// Note: this is private to make creating name from random string hard. | ||
30 | /// Hopefully, this should allow us to integrate hygiene cleaner in the | ||
31 | /// future, and to switch to interned representation of names. | ||
32 | const fn new_text(text: SmolStr) -> Name { | ||
33 | Name(Repr::Text(text)) | ||
34 | } | ||
35 | |||
36 | pub(crate) fn new_tuple_field(idx: usize) -> Name { | ||
37 | Name(Repr::TupleField(idx)) | ||
38 | } | ||
39 | |||
40 | /// Shortcut to create inline plain text name | ||
41 | const fn new_inline_ascii(len: usize, text: &[u8]) -> Name { | ||
42 | Name::new_text(SmolStr::new_inline_from_ascii(len, text)) | ||
43 | } | ||
44 | |||
45 | /// Resolve a name from the text of token. | ||
46 | fn resolve(raw_text: &SmolStr) -> Name { | ||
47 | let raw_start = "r#"; | ||
48 | if raw_text.as_str().starts_with(raw_start) { | ||
49 | Name::new_text(SmolStr::new(&raw_text[raw_start.len()..])) | ||
50 | } else { | ||
51 | Name::new_text(raw_text.clone()) | ||
52 | } | ||
53 | } | ||
54 | |||
55 | pub(crate) fn missing() -> Name { | ||
56 | Name::new_text("[missing name]".into()) | ||
57 | } | ||
58 | |||
59 | pub(crate) fn as_tuple_index(&self) -> Option<usize> { | ||
60 | match self.0 { | ||
61 | Repr::TupleField(idx) => Some(idx), | ||
62 | _ => None, | ||
63 | } | ||
64 | } | ||
65 | } | ||
66 | |||
67 | pub(crate) trait AsName { | ||
68 | fn as_name(&self) -> Name; | ||
69 | } | ||
70 | |||
71 | impl AsName for ast::NameRef { | ||
72 | fn as_name(&self) -> Name { | ||
73 | match self.as_tuple_field() { | ||
74 | Some(idx) => Name::new_tuple_field(idx), | ||
75 | None => Name::resolve(self.text()), | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | impl AsName for ast::Name { | ||
81 | fn as_name(&self) -> Name { | ||
82 | Name::resolve(self.text()) | ||
83 | } | ||
84 | } | ||
85 | |||
86 | impl AsName for ast::FieldKind { | ||
87 | fn as_name(&self) -> Name { | ||
88 | match self { | ||
89 | ast::FieldKind::Name(nr) => nr.as_name(), | ||
90 | ast::FieldKind::Index(idx) => Name::new_tuple_field(idx.text().parse().unwrap()), | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | impl AsName for ra_db::Dependency { | ||
96 | fn as_name(&self) -> Name { | ||
97 | Name::new_text(self.name.clone()) | ||
98 | } | ||
99 | } | ||
100 | |||
101 | // Primitives | ||
102 | pub(crate) const ISIZE: Name = Name::new_inline_ascii(5, b"isize"); | ||
103 | pub(crate) const I8: Name = Name::new_inline_ascii(2, b"i8"); | ||
104 | pub(crate) const I16: Name = Name::new_inline_ascii(3, b"i16"); | ||
105 | pub(crate) const I32: Name = Name::new_inline_ascii(3, b"i32"); | ||
106 | pub(crate) const I64: Name = Name::new_inline_ascii(3, b"i64"); | ||
107 | pub(crate) const I128: Name = Name::new_inline_ascii(4, b"i128"); | ||
108 | pub(crate) const USIZE: Name = Name::new_inline_ascii(5, b"usize"); | ||
109 | pub(crate) const U8: Name = Name::new_inline_ascii(2, b"u8"); | ||
110 | pub(crate) const U16: Name = Name::new_inline_ascii(3, b"u16"); | ||
111 | pub(crate) const U32: Name = Name::new_inline_ascii(3, b"u32"); | ||
112 | pub(crate) const U64: Name = Name::new_inline_ascii(3, b"u64"); | ||
113 | pub(crate) const U128: Name = Name::new_inline_ascii(4, b"u128"); | ||
114 | pub(crate) const F32: Name = Name::new_inline_ascii(3, b"f32"); | ||
115 | pub(crate) const F64: Name = Name::new_inline_ascii(3, b"f64"); | ||
116 | pub(crate) const BOOL: Name = Name::new_inline_ascii(4, b"bool"); | ||
117 | pub(crate) const CHAR: Name = Name::new_inline_ascii(4, b"char"); | ||
118 | pub(crate) const STR: Name = Name::new_inline_ascii(3, b"str"); | ||
119 | |||
120 | // Special names | ||
121 | pub(crate) const SELF_PARAM: Name = Name::new_inline_ascii(4, b"self"); | ||
122 | pub(crate) const SELF_TYPE: Name = Name::new_inline_ascii(4, b"Self"); | ||
123 | pub(crate) const MACRO_RULES: Name = Name::new_inline_ascii(11, b"macro_rules"); | ||
124 | |||
125 | // Components of known path (value or mod name) | ||
126 | pub(crate) const STD: Name = Name::new_inline_ascii(3, b"std"); | ||
127 | pub(crate) const ITER: Name = Name::new_inline_ascii(4, b"iter"); | ||
128 | pub(crate) const OPS: Name = Name::new_inline_ascii(3, b"ops"); | ||
129 | pub(crate) const FUTURE: Name = Name::new_inline_ascii(6, b"future"); | ||
130 | pub(crate) const RESULT: Name = Name::new_inline_ascii(6, b"result"); | ||
131 | pub(crate) const BOXED: Name = Name::new_inline_ascii(5, b"boxed"); | ||
132 | |||
133 | // Components of known path (type name) | ||
134 | pub(crate) const INTO_ITERATOR_TYPE: Name = Name::new_inline_ascii(12, b"IntoIterator"); | ||
135 | pub(crate) const ITEM_TYPE: Name = Name::new_inline_ascii(4, b"Item"); | ||
136 | pub(crate) const TRY_TYPE: Name = Name::new_inline_ascii(3, b"Try"); | ||
137 | pub(crate) const OK_TYPE: Name = Name::new_inline_ascii(2, b"Ok"); | ||
138 | pub(crate) const FUTURE_TYPE: Name = Name::new_inline_ascii(6, b"Future"); | ||
139 | pub(crate) const RESULT_TYPE: Name = Name::new_inline_ascii(6, b"Result"); | ||
140 | pub(crate) const OUTPUT_TYPE: Name = Name::new_inline_ascii(6, b"Output"); | ||
141 | pub(crate) const TARGET_TYPE: Name = Name::new_inline_ascii(6, b"Target"); | ||
142 | pub(crate) const BOX_TYPE: Name = Name::new_inline_ascii(3, b"Box"); | ||
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 67adcfa28..7ba031827 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -48,16 +48,15 @@ | |||
48 | //! on the result | 48 | //! on the result |
49 | 49 | ||
50 | mod per_ns; | 50 | mod per_ns; |
51 | mod raw; | ||
52 | mod collector; | 51 | mod collector; |
53 | mod mod_resolution; | ||
54 | #[cfg(test)] | 52 | #[cfg(test)] |
55 | mod tests; | 53 | mod tests; |
56 | 54 | ||
57 | use std::sync::Arc; | 55 | use std::sync::Arc; |
58 | 56 | ||
57 | use hir_def::{builtin_type::BuiltinType, CrateModuleId}; | ||
59 | use once_cell::sync::Lazy; | 58 | use once_cell::sync::Lazy; |
60 | use ra_arena::{impl_arena_id, Arena, RawId}; | 59 | use ra_arena::Arena; |
61 | use ra_db::{Edition, FileId}; | 60 | use ra_db::{Edition, FileId}; |
62 | use ra_prof::profile; | 61 | use ra_prof::profile; |
63 | use ra_syntax::ast; | 62 | use ra_syntax::ast; |
@@ -69,16 +68,12 @@ use crate::{ | |||
69 | diagnostics::DiagnosticSink, | 68 | diagnostics::DiagnosticSink, |
70 | ids::MacroDefId, | 69 | ids::MacroDefId, |
71 | nameres::diagnostics::DefDiagnostic, | 70 | nameres::diagnostics::DefDiagnostic, |
72 | Adt, AstId, BuiltinType, Crate, HirFileId, MacroDef, Module, ModuleDef, Name, Path, PathKind, | 71 | Adt, AstId, Crate, HirFileId, MacroDef, Module, ModuleDef, Name, Path, PathKind, Trait, |
73 | Trait, | ||
74 | }; | 72 | }; |
75 | 73 | ||
76 | pub(crate) use self::raw::{ImportSourceMap, RawItems}; | 74 | pub use self::per_ns::{Namespace, PerNs}; |
77 | 75 | ||
78 | pub use self::{ | 76 | pub use hir_def::nameres::raw::ImportId; |
79 | per_ns::{Namespace, PerNs}, | ||
80 | raw::ImportId, | ||
81 | }; | ||
82 | 77 | ||
83 | /// Contains all top-level defs from a macro-expanded crate | 78 | /// Contains all top-level defs from a macro-expanded crate |
84 | #[derive(Debug, PartialEq, Eq)] | 79 | #[derive(Debug, PartialEq, Eq)] |
@@ -115,13 +110,8 @@ impl std::ops::Index<CrateModuleId> for CrateDefMap { | |||
115 | } | 110 | } |
116 | } | 111 | } |
117 | 112 | ||
118 | /// An ID of a module, **local** to a specific crate | ||
119 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
120 | pub(crate) struct CrateModuleId(RawId); | ||
121 | impl_arena_id!(CrateModuleId); | ||
122 | |||
123 | #[derive(Default, Debug, PartialEq, Eq)] | 113 | #[derive(Default, Debug, PartialEq, Eq)] |
124 | pub(crate) struct ModuleData { | 114 | pub struct ModuleData { |
125 | pub(crate) parent: Option<CrateModuleId>, | 115 | pub(crate) parent: Option<CrateModuleId>, |
126 | pub(crate) children: FxHashMap<Name, CrateModuleId>, | 116 | pub(crate) children: FxHashMap<Name, CrateModuleId>, |
127 | pub(crate) scope: ModuleScope, | 117 | pub(crate) scope: ModuleScope, |
@@ -332,10 +322,11 @@ impl CrateDefMap { | |||
332 | ) -> ResolvePathResult { | 322 | ) -> ResolvePathResult { |
333 | let mut segments = path.segments.iter().enumerate(); | 323 | let mut segments = path.segments.iter().enumerate(); |
334 | let mut curr_per_ns: PerNs = match path.kind { | 324 | let mut curr_per_ns: PerNs = match path.kind { |
335 | PathKind::DollarCrate(krate) => { | 325 | PathKind::DollarCrate(crate_id) => { |
326 | let krate = Crate { crate_id }; | ||
336 | if krate == self.krate { | 327 | if krate == self.krate { |
337 | tested_by!(macro_dollar_crate_self); | 328 | tested_by!(macro_dollar_crate_self); |
338 | PerNs::types(Module { krate: self.krate, module_id: self.root }.into()) | 329 | PerNs::types(Module::new(self.krate, self.root).into()) |
339 | } else { | 330 | } else { |
340 | match krate.root_module(db) { | 331 | match krate.root_module(db) { |
341 | Some(module) => { | 332 | Some(module) => { |
@@ -346,12 +337,8 @@ impl CrateDefMap { | |||
346 | } | 337 | } |
347 | } | 338 | } |
348 | } | 339 | } |
349 | PathKind::Crate => { | 340 | PathKind::Crate => PerNs::types(Module::new(self.krate, self.root).into()), |
350 | PerNs::types(Module { krate: self.krate, module_id: self.root }.into()) | 341 | PathKind::Self_ => PerNs::types(Module::new(self.krate, original_module).into()), |
351 | } | ||
352 | PathKind::Self_ => { | ||
353 | PerNs::types(Module { krate: self.krate, module_id: original_module }.into()) | ||
354 | } | ||
355 | // plain import or absolute path in 2015: crate-relative with | 342 | // plain import or absolute path in 2015: crate-relative with |
356 | // fallback to extern prelude (with the simplification in | 343 | // fallback to extern prelude (with the simplification in |
357 | // rust-lang/rust#57745) | 344 | // rust-lang/rust#57745) |
@@ -377,7 +364,7 @@ impl CrateDefMap { | |||
377 | } | 364 | } |
378 | PathKind::Super => { | 365 | PathKind::Super => { |
379 | if let Some(p) = self.modules[original_module].parent { | 366 | if let Some(p) = self.modules[original_module].parent { |
380 | PerNs::types(Module { krate: self.krate, module_id: p }.into()) | 367 | PerNs::types(Module::new(self.krate, p).into()) |
381 | } else { | 368 | } else { |
382 | log::debug!("super path in root module"); | 369 | log::debug!("super path in root module"); |
383 | return ResolvePathResult::empty(ReachedFixedPoint::Yes); | 370 | return ResolvePathResult::empty(ReachedFixedPoint::Yes); |
@@ -419,12 +406,12 @@ impl CrateDefMap { | |||
419 | 406 | ||
420 | curr_per_ns = match curr { | 407 | curr_per_ns = match curr { |
421 | ModuleDef::Module(module) => { | 408 | ModuleDef::Module(module) => { |
422 | if module.krate != self.krate { | 409 | if module.krate() != self.krate { |
423 | let path = | 410 | let path = |
424 | Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; | 411 | Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; |
425 | log::debug!("resolving {:?} in other crate", path); | 412 | log::debug!("resolving {:?} in other crate", path); |
426 | let defp_map = db.crate_def_map(module.krate); | 413 | let defp_map = db.crate_def_map(module.krate()); |
427 | let (def, s) = defp_map.resolve_path(db, module.module_id, &path); | 414 | let (def, s) = defp_map.resolve_path(db, module.id.module_id, &path); |
428 | return ResolvePathResult::with( | 415 | return ResolvePathResult::with( |
429 | def, | 416 | def, |
430 | ReachedFixedPoint::Yes, | 417 | ReachedFixedPoint::Yes, |
@@ -433,7 +420,7 @@ impl CrateDefMap { | |||
433 | } | 420 | } |
434 | 421 | ||
435 | // Since it is a qualified path here, it should not contains legacy macros | 422 | // Since it is a qualified path here, it should not contains legacy macros |
436 | match self[module.module_id].scope.get(&segment.name) { | 423 | match self[module.id.module_id].scope.get(&segment.name) { |
437 | Some(res) => res.def, | 424 | Some(res) => res.def, |
438 | _ => { | 425 | _ => { |
439 | log::debug!("path segment {:?} not found", segment.name); | 426 | log::debug!("path segment {:?} not found", segment.name); |
@@ -511,14 +498,14 @@ impl CrateDefMap { | |||
511 | fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { | 498 | fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { |
512 | if let Some(prelude) = self.prelude { | 499 | if let Some(prelude) = self.prelude { |
513 | let keep; | 500 | let keep; |
514 | let def_map = if prelude.krate == self.krate { | 501 | let def_map = if prelude.krate() == self.krate { |
515 | self | 502 | self |
516 | } else { | 503 | } else { |
517 | // Extend lifetime | 504 | // Extend lifetime |
518 | keep = db.crate_def_map(prelude.krate); | 505 | keep = db.crate_def_map(prelude.krate()); |
519 | &keep | 506 | &keep |
520 | }; | 507 | }; |
521 | def_map[prelude.module_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) | 508 | def_map[prelude.id.module_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) |
522 | } else { | 509 | } else { |
523 | PerNs::none() | 510 | PerNs::none() |
524 | } | 511 | } |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index b5fe16bfa..ee0a4c99f 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -1,5 +1,10 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{ | ||
4 | attr::Attr, | ||
5 | nameres::{mod_resolution::ModDir, raw}, | ||
6 | }; | ||
7 | use hir_expand::name; | ||
3 | use ra_cfg::CfgOptions; | 8 | use ra_cfg::CfgOptions; |
4 | use ra_db::FileId; | 9 | use ra_db::FileId; |
5 | use ra_syntax::{ast, SmolStr}; | 10 | use ra_syntax::{ast, SmolStr}; |
@@ -7,13 +12,11 @@ use rustc_hash::FxHashMap; | |||
7 | use test_utils::tested_by; | 12 | use test_utils::tested_by; |
8 | 13 | ||
9 | use crate::{ | 14 | use crate::{ |
10 | attr::Attr, | ||
11 | db::DefDatabase, | 15 | db::DefDatabase, |
12 | ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, | 16 | ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, |
13 | name::MACRO_RULES, | ||
14 | nameres::{ | 17 | nameres::{ |
15 | diagnostics::DefDiagnostic, mod_resolution::ModDir, raw, Crate, CrateDefMap, CrateModuleId, | 18 | diagnostics::DefDiagnostic, Crate, CrateDefMap, CrateModuleId, ModuleData, ModuleDef, |
16 | ModuleData, ModuleDef, PerNs, ReachedFixedPoint, Resolution, ResolveMode, | 19 | PerNs, ReachedFixedPoint, Resolution, ResolveMode, |
17 | }, | 20 | }, |
18 | Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, | 21 | Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, |
19 | Struct, Trait, TypeAlias, Union, | 22 | Struct, Trait, TypeAlias, Union, |
@@ -212,7 +215,7 @@ where | |||
212 | 215 | ||
213 | if let Some(ModuleDef::Module(m)) = res.take_types() { | 216 | if let Some(ModuleDef::Module(m)) = res.take_types() { |
214 | tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use); | 217 | tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use); |
215 | self.import_all_macros_exported(current_module_id, m.krate); | 218 | self.import_all_macros_exported(current_module_id, m.krate()); |
216 | } | 219 | } |
217 | } | 220 | } |
218 | 221 | ||
@@ -289,11 +292,11 @@ where | |||
289 | if import.is_prelude { | 292 | if import.is_prelude { |
290 | tested_by!(std_prelude); | 293 | tested_by!(std_prelude); |
291 | self.def_map.prelude = Some(m); | 294 | self.def_map.prelude = Some(m); |
292 | } else if m.krate != self.def_map.krate { | 295 | } else if m.krate() != self.def_map.krate { |
293 | tested_by!(glob_across_crates); | 296 | tested_by!(glob_across_crates); |
294 | // glob import from other crate => we can just import everything once | 297 | // glob import from other crate => we can just import everything once |
295 | let item_map = self.db.crate_def_map(m.krate); | 298 | let item_map = self.db.crate_def_map(m.krate()); |
296 | let scope = &item_map[m.module_id].scope; | 299 | let scope = &item_map[m.id.module_id].scope; |
297 | 300 | ||
298 | // Module scoped macros is included | 301 | // Module scoped macros is included |
299 | let items = scope | 302 | let items = scope |
@@ -307,7 +310,7 @@ where | |||
307 | // glob import from same crate => we do an initial | 310 | // glob import from same crate => we do an initial |
308 | // import, and then need to propagate any further | 311 | // import, and then need to propagate any further |
309 | // additions | 312 | // additions |
310 | let scope = &self.def_map[m.module_id].scope; | 313 | let scope = &self.def_map[m.id.module_id].scope; |
311 | 314 | ||
312 | // Module scoped macros is included | 315 | // Module scoped macros is included |
313 | let items = scope | 316 | let items = scope |
@@ -319,7 +322,7 @@ where | |||
319 | self.update(module_id, Some(import_id), &items); | 322 | self.update(module_id, Some(import_id), &items); |
320 | // record the glob import in case we add further items | 323 | // record the glob import in case we add further items |
321 | self.glob_imports | 324 | self.glob_imports |
322 | .entry(m.module_id) | 325 | .entry(m.id.module_id) |
323 | .or_default() | 326 | .or_default() |
324 | .push((module_id, import_id)); | 327 | .push((module_id, import_id)); |
325 | } | 328 | } |
@@ -448,7 +451,7 @@ where | |||
448 | ); | 451 | ); |
449 | 452 | ||
450 | if let Some(def) = resolved_res.resolved_def.get_macros() { | 453 | if let Some(def) = resolved_res.resolved_def.get_macros() { |
451 | let call_id = MacroCallLoc { def: def.id, ast_id: *ast_id }.id(self.db); | 454 | let call_id = self.db.intern_macro(MacroCallLoc { def: def.id, ast_id: *ast_id }); |
452 | resolved.push((*module_id, call_id, def.id)); | 455 | resolved.push((*module_id, call_id, def.id)); |
453 | res = ReachedFixedPoint::No; | 456 | res = ReachedFixedPoint::No; |
454 | return false; | 457 | return false; |
@@ -523,9 +526,10 @@ where | |||
523 | 526 | ||
524 | // Prelude module is always considered to be `#[macro_use]`. | 527 | // Prelude module is always considered to be `#[macro_use]`. |
525 | if let Some(prelude_module) = self.def_collector.def_map.prelude { | 528 | if let Some(prelude_module) = self.def_collector.def_map.prelude { |
526 | if prelude_module.krate != self.def_collector.def_map.krate { | 529 | if prelude_module.krate() != self.def_collector.def_map.krate { |
527 | tested_by!(prelude_is_macro_use); | 530 | tested_by!(prelude_is_macro_use); |
528 | self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate); | 531 | self.def_collector |
532 | .import_all_macros_exported(self.module_id, prelude_module.krate()); | ||
529 | } | 533 | } |
530 | } | 534 | } |
531 | 535 | ||
@@ -567,7 +571,7 @@ where | |||
567 | // inline module, just recurse | 571 | // inline module, just recurse |
568 | raw::ModuleData::Definition { name, items, ast_id } => { | 572 | raw::ModuleData::Definition { name, items, ast_id } => { |
569 | let module_id = | 573 | let module_id = |
570 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); | 574 | self.push_child_module(name.clone(), AstId::new(self.file_id, *ast_id), None); |
571 | 575 | ||
572 | ModCollector { | 576 | ModCollector { |
573 | def_collector: &mut *self.def_collector, | 577 | def_collector: &mut *self.def_collector, |
@@ -583,7 +587,7 @@ where | |||
583 | } | 587 | } |
584 | // out of line module, resolve, parse and recurse | 588 | // out of line module, resolve, parse and recurse |
585 | raw::ModuleData::Declaration { name, ast_id } => { | 589 | raw::ModuleData::Declaration { name, ast_id } => { |
586 | let ast_id = ast_id.with_file_id(self.file_id); | 590 | let ast_id = AstId::new(self.file_id, *ast_id); |
587 | match self.mod_dir.resolve_declaration( | 591 | match self.mod_dir.resolve_declaration( |
588 | self.def_collector.db, | 592 | self.def_collector.db, |
589 | self.file_id, | 593 | self.file_id, |
@@ -631,9 +635,7 @@ where | |||
631 | modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); | 635 | modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); |
632 | modules[self.module_id].children.insert(name.clone(), res); | 636 | modules[self.module_id].children.insert(name.clone(), res); |
633 | let resolution = Resolution { | 637 | let resolution = Resolution { |
634 | def: PerNs::types( | 638 | def: PerNs::types(Module::new(self.def_collector.def_map.krate, res).into()), |
635 | Module { krate: self.def_collector.def_map.krate, module_id: res }.into(), | ||
636 | ), | ||
637 | import: None, | 639 | import: None, |
638 | }; | 640 | }; |
639 | self.def_collector.update(self.module_id, None, &[(name, resolution)]); | 641 | self.def_collector.update(self.module_id, None, &[(name, resolution)]); |
@@ -641,8 +643,8 @@ where | |||
641 | } | 643 | } |
642 | 644 | ||
643 | fn define_def(&mut self, def: &raw::DefData) { | 645 | fn define_def(&mut self, def: &raw::DefData) { |
644 | let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; | 646 | let module = Module::new(self.def_collector.def_map.krate, self.module_id); |
645 | let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); | 647 | let ctx = LocationCtx::new(self.def_collector.db, module.id, self.file_id); |
646 | 648 | ||
647 | macro_rules! def { | 649 | macro_rules! def { |
648 | ($kind:ident, $ast_id:ident) => { | 650 | ($kind:ident, $ast_id:ident) => { |
@@ -671,28 +673,26 @@ where | |||
671 | } | 673 | } |
672 | 674 | ||
673 | fn collect_macro(&mut self, mac: &raw::MacroData) { | 675 | fn collect_macro(&mut self, mac: &raw::MacroData) { |
676 | let ast_id = AstId::new(self.file_id, mac.ast_id); | ||
677 | |||
674 | // Case 1: macro rules, define a macro in crate-global mutable scope | 678 | // Case 1: macro rules, define a macro in crate-global mutable scope |
675 | if is_macro_rules(&mac.path) { | 679 | if is_macro_rules(&mac.path) { |
676 | if let Some(name) = &mac.name { | 680 | if let Some(name) = &mac.name { |
677 | let macro_id = MacroDefId { | 681 | let macro_id = |
678 | ast_id: mac.ast_id.with_file_id(self.file_id), | 682 | MacroDefId { ast_id, krate: self.def_collector.def_map.krate.crate_id }; |
679 | krate: self.def_collector.def_map.krate, | ||
680 | }; | ||
681 | let macro_ = MacroDef { id: macro_id }; | 683 | let macro_ = MacroDef { id: macro_id }; |
682 | self.def_collector.define_macro(self.module_id, name.clone(), macro_, mac.export); | 684 | self.def_collector.define_macro(self.module_id, name.clone(), macro_, mac.export); |
683 | } | 685 | } |
684 | return; | 686 | return; |
685 | } | 687 | } |
686 | 688 | ||
687 | let ast_id = mac.ast_id.with_file_id(self.file_id); | ||
688 | |||
689 | // Case 2: try to resolve in legacy scope and expand macro_rules, triggering | 689 | // Case 2: try to resolve in legacy scope and expand macro_rules, triggering |
690 | // recursive item collection. | 690 | // recursive item collection. |
691 | if let Some(macro_def) = mac.path.as_ident().and_then(|name| { | 691 | if let Some(macro_def) = mac.path.as_ident().and_then(|name| { |
692 | self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) | 692 | self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) |
693 | }) { | 693 | }) { |
694 | let def = macro_def.id; | 694 | let def = macro_def.id; |
695 | let macro_call_id = MacroCallLoc { def, ast_id }.id(self.def_collector.db); | 695 | let macro_call_id = self.def_collector.db.intern_macro(MacroCallLoc { def, ast_id }); |
696 | 696 | ||
697 | self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, def); | 697 | self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, def); |
698 | return; | 698 | return; |
@@ -728,7 +728,7 @@ where | |||
728 | } | 728 | } |
729 | 729 | ||
730 | fn is_macro_rules(path: &Path) -> bool { | 730 | fn is_macro_rules(path: &Path) -> bool { |
731 | path.as_ident() == Some(&MACRO_RULES) | 731 | path.as_ident() == Some(&name::MACRO_RULES) |
732 | } | 732 | } |
733 | 733 | ||
734 | #[cfg(test)] | 734 | #[cfg(test)] |
diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs deleted file mode 100644 index e8b808514..000000000 --- a/crates/ra_hir/src/nameres/mod_resolution.rs +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | //! This module resolves `mod foo;` declaration to file. | ||
2 | use ra_db::FileId; | ||
3 | use ra_syntax::SmolStr; | ||
4 | use relative_path::RelativePathBuf; | ||
5 | |||
6 | use crate::{db::DefDatabase, HirFileId, Name}; | ||
7 | |||
8 | #[derive(Clone, Debug)] | ||
9 | pub(super) struct ModDir { | ||
10 | /// `.` for `mod.rs`, `lib.rs` | ||
11 | /// `./foo` for `foo.rs` | ||
12 | /// `./foo/bar` for `mod bar { mod x; }` nested in `foo.rs` | ||
13 | path: RelativePathBuf, | ||
14 | /// inside `./foo.rs`, mods with `#[path]` should *not* be relative to `./foo/` | ||
15 | root_non_dir_owner: bool, | ||
16 | } | ||
17 | |||
18 | impl ModDir { | ||
19 | pub(super) fn root() -> ModDir { | ||
20 | ModDir { path: RelativePathBuf::default(), root_non_dir_owner: false } | ||
21 | } | ||
22 | |||
23 | pub(super) fn descend_into_definition( | ||
24 | &self, | ||
25 | name: &Name, | ||
26 | attr_path: Option<&SmolStr>, | ||
27 | ) -> ModDir { | ||
28 | let mut path = self.path.clone(); | ||
29 | match attr_to_path(attr_path) { | ||
30 | None => path.push(&name.to_string()), | ||
31 | Some(attr_path) => { | ||
32 | if self.root_non_dir_owner { | ||
33 | // Workaround for relative path API: turn `lib.rs` into ``. | ||
34 | if !path.pop() { | ||
35 | path = RelativePathBuf::default(); | ||
36 | } | ||
37 | } | ||
38 | path.push(attr_path); | ||
39 | } | ||
40 | } | ||
41 | ModDir { path, root_non_dir_owner: false } | ||
42 | } | ||
43 | |||
44 | pub(super) fn resolve_declaration( | ||
45 | &self, | ||
46 | db: &impl DefDatabase, | ||
47 | file_id: HirFileId, | ||
48 | name: &Name, | ||
49 | attr_path: Option<&SmolStr>, | ||
50 | ) -> Result<(FileId, ModDir), RelativePathBuf> { | ||
51 | let empty_path = RelativePathBuf::default(); | ||
52 | let file_id = file_id.original_file(db); | ||
53 | |||
54 | let mut candidate_files = Vec::new(); | ||
55 | match attr_to_path(attr_path) { | ||
56 | Some(attr_path) => { | ||
57 | let base = if self.root_non_dir_owner { | ||
58 | self.path.parent().unwrap_or(&empty_path) | ||
59 | } else { | ||
60 | &self.path | ||
61 | }; | ||
62 | candidate_files.push(base.join(attr_path)) | ||
63 | } | ||
64 | None => { | ||
65 | candidate_files.push(self.path.join(&format!("{}.rs", name))); | ||
66 | candidate_files.push(self.path.join(&format!("{}/mod.rs", name))); | ||
67 | } | ||
68 | }; | ||
69 | |||
70 | for candidate in candidate_files.iter() { | ||
71 | if let Some(file_id) = db.resolve_relative_path(file_id, candidate) { | ||
72 | let mut root_non_dir_owner = false; | ||
73 | let mut mod_path = RelativePathBuf::new(); | ||
74 | if !(candidate.ends_with("mod.rs") || attr_path.is_some()) { | ||
75 | root_non_dir_owner = true; | ||
76 | mod_path.push(&name.to_string()); | ||
77 | } | ||
78 | return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner })); | ||
79 | } | ||
80 | } | ||
81 | Err(candidate_files.remove(0)) | ||
82 | } | ||
83 | } | ||
84 | |||
85 | fn attr_to_path(attr: Option<&SmolStr>) -> Option<RelativePathBuf> { | ||
86 | attr.and_then(|it| RelativePathBuf::from_path(&it.replace("\\", "/")).ok()) | ||
87 | } | ||
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs deleted file mode 100644 index 57f2929c3..000000000 --- a/crates/ra_hir/src/nameres/raw.rs +++ /dev/null | |||
@@ -1,403 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use std::{ops::Index, sync::Arc}; | ||
4 | |||
5 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | ||
6 | use ra_syntax::{ | ||
7 | ast::{self, AttrsOwner, NameOwner}, | ||
8 | AstNode, AstPtr, SourceFile, | ||
9 | }; | ||
10 | use test_utils::tested_by; | ||
11 | |||
12 | use crate::{ | ||
13 | attr::Attr, | ||
14 | db::{AstDatabase, DefDatabase}, | ||
15 | AsName, AstIdMap, Either, FileAstId, HirFileId, ModuleSource, Name, Path, Source, | ||
16 | }; | ||
17 | |||
18 | /// `RawItems` is a set of top-level items in a file (except for impls). | ||
19 | /// | ||
20 | /// It is the input to name resolution algorithm. `RawItems` are not invalidated | ||
21 | /// on most edits. | ||
22 | #[derive(Debug, Default, PartialEq, Eq)] | ||
23 | pub struct RawItems { | ||
24 | modules: Arena<Module, ModuleData>, | ||
25 | imports: Arena<ImportId, ImportData>, | ||
26 | defs: Arena<Def, DefData>, | ||
27 | macros: Arena<Macro, MacroData>, | ||
28 | /// items for top-level module | ||
29 | items: Vec<RawItem>, | ||
30 | } | ||
31 | |||
32 | #[derive(Debug, Default, PartialEq, Eq)] | ||
33 | pub struct ImportSourceMap { | ||
34 | map: ArenaMap<ImportId, ImportSourcePtr>, | ||
35 | } | ||
36 | |||
37 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; | ||
38 | type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>; | ||
39 | |||
40 | impl ImportSourcePtr { | ||
41 | fn to_node(self, file: &SourceFile) -> ImportSource { | ||
42 | self.map(|ptr| ptr.to_node(file.syntax()), |ptr| ptr.to_node(file.syntax())) | ||
43 | } | ||
44 | } | ||
45 | |||
46 | impl ImportSourceMap { | ||
47 | fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { | ||
48 | self.map.insert(import, ptr) | ||
49 | } | ||
50 | |||
51 | pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> ImportSource { | ||
52 | let file = match source { | ||
53 | ModuleSource::SourceFile(file) => file.clone(), | ||
54 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), | ||
55 | }; | ||
56 | |||
57 | self.map[import].to_node(&file) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | impl RawItems { | ||
62 | pub(crate) fn raw_items_query( | ||
63 | db: &(impl DefDatabase + AstDatabase), | ||
64 | file_id: HirFileId, | ||
65 | ) -> Arc<RawItems> { | ||
66 | db.raw_items_with_source_map(file_id).0 | ||
67 | } | ||
68 | |||
69 | pub(crate) fn raw_items_with_source_map_query( | ||
70 | db: &(impl DefDatabase + AstDatabase), | ||
71 | file_id: HirFileId, | ||
72 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { | ||
73 | let mut collector = RawItemsCollector { | ||
74 | raw_items: RawItems::default(), | ||
75 | source_ast_id_map: db.ast_id_map(file_id), | ||
76 | source_map: ImportSourceMap::default(), | ||
77 | file_id, | ||
78 | db, | ||
79 | }; | ||
80 | if let Some(node) = db.parse_or_expand(file_id) { | ||
81 | if let Some(source_file) = ast::SourceFile::cast(node.clone()) { | ||
82 | collector.process_module(None, source_file); | ||
83 | } else if let Some(item_list) = ast::MacroItems::cast(node) { | ||
84 | collector.process_module(None, item_list); | ||
85 | } | ||
86 | } | ||
87 | (Arc::new(collector.raw_items), Arc::new(collector.source_map)) | ||
88 | } | ||
89 | |||
90 | pub(super) fn items(&self) -> &[RawItem] { | ||
91 | &self.items | ||
92 | } | ||
93 | } | ||
94 | |||
95 | impl Index<Module> for RawItems { | ||
96 | type Output = ModuleData; | ||
97 | fn index(&self, idx: Module) -> &ModuleData { | ||
98 | &self.modules[idx] | ||
99 | } | ||
100 | } | ||
101 | |||
102 | impl Index<ImportId> for RawItems { | ||
103 | type Output = ImportData; | ||
104 | fn index(&self, idx: ImportId) -> &ImportData { | ||
105 | &self.imports[idx] | ||
106 | } | ||
107 | } | ||
108 | |||
109 | impl Index<Def> for RawItems { | ||
110 | type Output = DefData; | ||
111 | fn index(&self, idx: Def) -> &DefData { | ||
112 | &self.defs[idx] | ||
113 | } | ||
114 | } | ||
115 | |||
116 | impl Index<Macro> for RawItems { | ||
117 | type Output = MacroData; | ||
118 | fn index(&self, idx: Macro) -> &MacroData { | ||
119 | &self.macros[idx] | ||
120 | } | ||
121 | } | ||
122 | |||
123 | // Avoid heap allocation on items without attributes. | ||
124 | type Attrs = Option<Arc<[Attr]>>; | ||
125 | |||
126 | #[derive(Debug, PartialEq, Eq, Clone)] | ||
127 | pub(super) struct RawItem { | ||
128 | attrs: Attrs, | ||
129 | pub(super) kind: RawItemKind, | ||
130 | } | ||
131 | |||
132 | impl RawItem { | ||
133 | pub(super) fn attrs(&self) -> &[Attr] { | ||
134 | self.attrs.as_ref().map_or(&[], |it| &*it) | ||
135 | } | ||
136 | } | ||
137 | |||
138 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
139 | pub(super) enum RawItemKind { | ||
140 | Module(Module), | ||
141 | Import(ImportId), | ||
142 | Def(Def), | ||
143 | Macro(Macro), | ||
144 | } | ||
145 | |||
146 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
147 | pub(super) struct Module(RawId); | ||
148 | impl_arena_id!(Module); | ||
149 | |||
150 | #[derive(Debug, PartialEq, Eq)] | ||
151 | pub(super) enum ModuleData { | ||
152 | Declaration { name: Name, ast_id: FileAstId<ast::Module> }, | ||
153 | Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, | ||
154 | } | ||
155 | |||
156 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
157 | pub struct ImportId(RawId); | ||
158 | impl_arena_id!(ImportId); | ||
159 | |||
160 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
161 | pub struct ImportData { | ||
162 | pub(super) path: Path, | ||
163 | pub(super) alias: Option<Name>, | ||
164 | pub(super) is_glob: bool, | ||
165 | pub(super) is_prelude: bool, | ||
166 | pub(super) is_extern_crate: bool, | ||
167 | pub(super) is_macro_use: bool, | ||
168 | } | ||
169 | |||
170 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
171 | pub(super) struct Def(RawId); | ||
172 | impl_arena_id!(Def); | ||
173 | |||
174 | #[derive(Debug, PartialEq, Eq)] | ||
175 | pub(super) struct DefData { | ||
176 | pub(super) name: Name, | ||
177 | pub(super) kind: DefKind, | ||
178 | } | ||
179 | |||
180 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
181 | pub(super) enum DefKind { | ||
182 | Function(FileAstId<ast::FnDef>), | ||
183 | Struct(FileAstId<ast::StructDef>), | ||
184 | Union(FileAstId<ast::StructDef>), | ||
185 | Enum(FileAstId<ast::EnumDef>), | ||
186 | Const(FileAstId<ast::ConstDef>), | ||
187 | Static(FileAstId<ast::StaticDef>), | ||
188 | Trait(FileAstId<ast::TraitDef>), | ||
189 | TypeAlias(FileAstId<ast::TypeAliasDef>), | ||
190 | } | ||
191 | |||
192 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
193 | pub(super) struct Macro(RawId); | ||
194 | impl_arena_id!(Macro); | ||
195 | |||
196 | #[derive(Debug, PartialEq, Eq)] | ||
197 | pub(super) struct MacroData { | ||
198 | pub(super) ast_id: FileAstId<ast::MacroCall>, | ||
199 | pub(super) path: Path, | ||
200 | pub(super) name: Option<Name>, | ||
201 | pub(super) export: bool, | ||
202 | } | ||
203 | |||
204 | struct RawItemsCollector<DB> { | ||
205 | raw_items: RawItems, | ||
206 | source_ast_id_map: Arc<AstIdMap>, | ||
207 | source_map: ImportSourceMap, | ||
208 | file_id: HirFileId, | ||
209 | db: DB, | ||
210 | } | ||
211 | |||
212 | impl<DB: AstDatabase> RawItemsCollector<&DB> { | ||
213 | fn process_module(&mut self, current_module: Option<Module>, body: impl ast::ModuleItemOwner) { | ||
214 | for item_or_macro in body.items_with_macros() { | ||
215 | match item_or_macro { | ||
216 | ast::ItemOrMacro::Macro(m) => self.add_macro(current_module, m), | ||
217 | ast::ItemOrMacro::Item(item) => self.add_item(current_module, item), | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
222 | fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) { | ||
223 | let attrs = self.parse_attrs(&item); | ||
224 | let (kind, name) = match item { | ||
225 | ast::ModuleItem::Module(module) => { | ||
226 | self.add_module(current_module, module); | ||
227 | return; | ||
228 | } | ||
229 | ast::ModuleItem::UseItem(use_item) => { | ||
230 | self.add_use_item(current_module, use_item); | ||
231 | return; | ||
232 | } | ||
233 | ast::ModuleItem::ExternCrateItem(extern_crate) => { | ||
234 | self.add_extern_crate_item(current_module, extern_crate); | ||
235 | return; | ||
236 | } | ||
237 | ast::ModuleItem::ImplBlock(_) => { | ||
238 | // impls don't participate in name resolution | ||
239 | return; | ||
240 | } | ||
241 | ast::ModuleItem::StructDef(it) => { | ||
242 | let id = self.source_ast_id_map.ast_id(&it); | ||
243 | let name = it.name(); | ||
244 | if it.is_union() { | ||
245 | (DefKind::Union(id), name) | ||
246 | } else { | ||
247 | (DefKind::Struct(id), name) | ||
248 | } | ||
249 | } | ||
250 | ast::ModuleItem::EnumDef(it) => { | ||
251 | (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name()) | ||
252 | } | ||
253 | ast::ModuleItem::FnDef(it) => { | ||
254 | (DefKind::Function(self.source_ast_id_map.ast_id(&it)), it.name()) | ||
255 | } | ||
256 | ast::ModuleItem::TraitDef(it) => { | ||
257 | (DefKind::Trait(self.source_ast_id_map.ast_id(&it)), it.name()) | ||
258 | } | ||
259 | ast::ModuleItem::TypeAliasDef(it) => { | ||
260 | (DefKind::TypeAlias(self.source_ast_id_map.ast_id(&it)), it.name()) | ||
261 | } | ||
262 | ast::ModuleItem::ConstDef(it) => { | ||
263 | (DefKind::Const(self.source_ast_id_map.ast_id(&it)), it.name()) | ||
264 | } | ||
265 | ast::ModuleItem::StaticDef(it) => { | ||
266 | (DefKind::Static(self.source_ast_id_map.ast_id(&it)), it.name()) | ||
267 | } | ||
268 | }; | ||
269 | if let Some(name) = name { | ||
270 | let name = name.as_name(); | ||
271 | let def = self.raw_items.defs.alloc(DefData { name, kind }); | ||
272 | self.push_item(current_module, attrs, RawItemKind::Def(def)); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | fn add_module(&mut self, current_module: Option<Module>, module: ast::Module) { | ||
277 | let name = match module.name() { | ||
278 | Some(it) => it.as_name(), | ||
279 | None => return, | ||
280 | }; | ||
281 | let attrs = self.parse_attrs(&module); | ||
282 | |||
283 | let ast_id = self.source_ast_id_map.ast_id(&module); | ||
284 | if module.has_semi() { | ||
285 | let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); | ||
286 | self.push_item(current_module, attrs, RawItemKind::Module(item)); | ||
287 | return; | ||
288 | } | ||
289 | |||
290 | if let Some(item_list) = module.item_list() { | ||
291 | let item = self.raw_items.modules.alloc(ModuleData::Definition { | ||
292 | name, | ||
293 | ast_id, | ||
294 | items: Vec::new(), | ||
295 | }); | ||
296 | self.process_module(Some(item), item_list); | ||
297 | self.push_item(current_module, attrs, RawItemKind::Module(item)); | ||
298 | return; | ||
299 | } | ||
300 | tested_by!(name_res_works_for_broken_modules); | ||
301 | } | ||
302 | |||
303 | fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseItem) { | ||
304 | // FIXME: cfg_attr | ||
305 | let is_prelude = use_item.has_atom_attr("prelude_import"); | ||
306 | let attrs = self.parse_attrs(&use_item); | ||
307 | |||
308 | Path::expand_use_item( | ||
309 | Source { ast: use_item, file_id: self.file_id }, | ||
310 | self.db, | ||
311 | |path, use_tree, is_glob, alias| { | ||
312 | let import_data = ImportData { | ||
313 | path, | ||
314 | alias, | ||
315 | is_glob, | ||
316 | is_prelude, | ||
317 | is_extern_crate: false, | ||
318 | is_macro_use: false, | ||
319 | }; | ||
320 | self.push_import( | ||
321 | current_module, | ||
322 | attrs.clone(), | ||
323 | import_data, | ||
324 | Either::A(AstPtr::new(use_tree)), | ||
325 | ); | ||
326 | }, | ||
327 | ) | ||
328 | } | ||
329 | |||
330 | fn add_extern_crate_item( | ||
331 | &mut self, | ||
332 | current_module: Option<Module>, | ||
333 | extern_crate: ast::ExternCrateItem, | ||
334 | ) { | ||
335 | if let Some(name_ref) = extern_crate.name_ref() { | ||
336 | let path = Path::from_name_ref(&name_ref); | ||
337 | let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); | ||
338 | let attrs = self.parse_attrs(&extern_crate); | ||
339 | // FIXME: cfg_attr | ||
340 | let is_macro_use = extern_crate.has_atom_attr("macro_use"); | ||
341 | let import_data = ImportData { | ||
342 | path, | ||
343 | alias, | ||
344 | is_glob: false, | ||
345 | is_prelude: false, | ||
346 | is_extern_crate: true, | ||
347 | is_macro_use, | ||
348 | }; | ||
349 | self.push_import( | ||
350 | current_module, | ||
351 | attrs, | ||
352 | import_data, | ||
353 | Either::B(AstPtr::new(&extern_crate)), | ||
354 | ); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) { | ||
359 | let attrs = self.parse_attrs(&m); | ||
360 | let path = match m | ||
361 | .path() | ||
362 | .and_then(|path| Path::from_src(Source { ast: path, file_id: self.file_id }, self.db)) | ||
363 | { | ||
364 | Some(it) => it, | ||
365 | _ => return, | ||
366 | }; | ||
367 | |||
368 | let name = m.name().map(|it| it.as_name()); | ||
369 | let ast_id = self.source_ast_id_map.ast_id(&m); | ||
370 | // FIXME: cfg_attr | ||
371 | let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export"); | ||
372 | |||
373 | let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); | ||
374 | self.push_item(current_module, attrs, RawItemKind::Macro(m)); | ||
375 | } | ||
376 | |||
377 | fn push_import( | ||
378 | &mut self, | ||
379 | current_module: Option<Module>, | ||
380 | attrs: Attrs, | ||
381 | data: ImportData, | ||
382 | source: ImportSourcePtr, | ||
383 | ) { | ||
384 | let import = self.raw_items.imports.alloc(data); | ||
385 | self.source_map.insert(import, source); | ||
386 | self.push_item(current_module, attrs, RawItemKind::Import(import)) | ||
387 | } | ||
388 | |||
389 | fn push_item(&mut self, current_module: Option<Module>, attrs: Attrs, kind: RawItemKind) { | ||
390 | match current_module { | ||
391 | Some(module) => match &mut self.raw_items.modules[module] { | ||
392 | ModuleData::Definition { items, .. } => items, | ||
393 | ModuleData::Declaration { .. } => unreachable!(), | ||
394 | }, | ||
395 | None => &mut self.raw_items.items, | ||
396 | } | ||
397 | .push(RawItem { attrs, kind }) | ||
398 | } | ||
399 | |||
400 | fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { | ||
401 | Attr::from_attrs_owner(self.file_id, item, self.db) | ||
402 | } | ||
403 | } | ||
diff --git a/crates/ra_hir/src/nameres/tests/mod_resolution.rs b/crates/ra_hir/src/nameres/tests/mod_resolution.rs index f569aacdc..abfe8b1c3 100644 --- a/crates/ra_hir/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir/src/nameres/tests/mod_resolution.rs | |||
@@ -2,7 +2,7 @@ use super::*; | |||
2 | 2 | ||
3 | #[test] | 3 | #[test] |
4 | fn name_res_works_for_broken_modules() { | 4 | fn name_res_works_for_broken_modules() { |
5 | covers!(name_res_works_for_broken_modules); | 5 | // covers!(name_res_works_for_broken_modules); |
6 | let map = def_map( | 6 | let map = def_map( |
7 | " | 7 | " |
8 | //- /lib.rs | 8 | //- /lib.rs |
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs deleted file mode 100644 index 394617e1a..000000000 --- a/crates/ra_hir/src/path.rs +++ /dev/null | |||
@@ -1,417 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use std::{iter, sync::Arc}; | ||
4 | |||
5 | use ra_syntax::{ | ||
6 | ast::{self, NameOwner, TypeAscriptionOwner}, | ||
7 | AstNode, | ||
8 | }; | ||
9 | |||
10 | use crate::{db::AstDatabase, name, type_ref::TypeRef, AsName, Crate, Name, Source}; | ||
11 | |||
12 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
13 | pub struct Path { | ||
14 | pub kind: PathKind, | ||
15 | pub segments: Vec<PathSegment>, | ||
16 | } | ||
17 | |||
18 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
19 | pub struct PathSegment { | ||
20 | pub name: Name, | ||
21 | pub args_and_bindings: Option<Arc<GenericArgs>>, | ||
22 | } | ||
23 | |||
24 | /// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This | ||
25 | /// can (in the future) also include bindings of associated types, like in | ||
26 | /// `Iterator<Item = Foo>`. | ||
27 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
28 | pub struct GenericArgs { | ||
29 | pub args: Vec<GenericArg>, | ||
30 | /// This specifies whether the args contain a Self type as the first | ||
31 | /// element. This is the case for path segments like `<T as Trait>`, where | ||
32 | /// `T` is actually a type parameter for the path `Trait` specifying the | ||
33 | /// Self type. Otherwise, when we have a path `Trait<X, Y>`, the Self type | ||
34 | /// is left out. | ||
35 | pub has_self_type: bool, | ||
36 | /// Associated type bindings like in `Iterator<Item = T>`. | ||
37 | pub bindings: Vec<(Name, TypeRef)>, | ||
38 | } | ||
39 | |||
40 | /// A single generic argument. | ||
41 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
42 | pub enum GenericArg { | ||
43 | Type(TypeRef), | ||
44 | // or lifetime... | ||
45 | } | ||
46 | |||
47 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
48 | pub enum PathKind { | ||
49 | Plain, | ||
50 | Self_, | ||
51 | Super, | ||
52 | Crate, | ||
53 | // Absolute path | ||
54 | Abs, | ||
55 | // Type based path like `<T>::foo` | ||
56 | Type(Box<TypeRef>), | ||
57 | // `$crate` from macro expansion | ||
58 | DollarCrate(Crate), | ||
59 | } | ||
60 | |||
61 | impl Path { | ||
62 | /// Calls `cb` with all paths, represented by this use item. | ||
63 | pub fn expand_use_item( | ||
64 | item_src: Source<ast::UseItem>, | ||
65 | db: &impl AstDatabase, | ||
66 | mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), | ||
67 | ) { | ||
68 | if let Some(tree) = item_src.ast.use_tree() { | ||
69 | expand_use_tree(None, tree, &|| item_src.file_id.macro_crate(db), &mut cb); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | pub fn from_simple_segments(kind: PathKind, segments: impl IntoIterator<Item = Name>) -> Path { | ||
74 | Path { | ||
75 | kind, | ||
76 | segments: segments | ||
77 | .into_iter() | ||
78 | .map(|name| PathSegment { name, args_and_bindings: None }) | ||
79 | .collect(), | ||
80 | } | ||
81 | } | ||
82 | |||
83 | /// Converts an `ast::Path` to `Path`. Works with use trees. | ||
84 | /// DEPRECATED: It does not handle `$crate` from macro call. | ||
85 | pub fn from_ast(path: ast::Path) -> Option<Path> { | ||
86 | Path::parse(path, &|| None) | ||
87 | } | ||
88 | |||
89 | /// Converts an `ast::Path` to `Path`. Works with use trees. | ||
90 | /// It correctly handles `$crate` based path from macro call. | ||
91 | pub fn from_src(source: Source<ast::Path>, db: &impl AstDatabase) -> Option<Path> { | ||
92 | let file_id = source.file_id; | ||
93 | Path::parse(source.ast, &|| file_id.macro_crate(db)) | ||
94 | } | ||
95 | |||
96 | fn parse(mut path: ast::Path, macro_crate: &impl Fn() -> Option<Crate>) -> Option<Path> { | ||
97 | let mut kind = PathKind::Plain; | ||
98 | let mut segments = Vec::new(); | ||
99 | loop { | ||
100 | let segment = path.segment()?; | ||
101 | |||
102 | if segment.has_colon_colon() { | ||
103 | kind = PathKind::Abs; | ||
104 | } | ||
105 | |||
106 | match segment.kind()? { | ||
107 | ast::PathSegmentKind::Name(name) => { | ||
108 | if name.text() == "$crate" { | ||
109 | if let Some(macro_crate) = macro_crate() { | ||
110 | kind = PathKind::DollarCrate(macro_crate); | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | let args = segment | ||
116 | .type_arg_list() | ||
117 | .and_then(GenericArgs::from_ast) | ||
118 | .or_else(|| { | ||
119 | GenericArgs::from_fn_like_path_ast( | ||
120 | segment.param_list(), | ||
121 | segment.ret_type(), | ||
122 | ) | ||
123 | }) | ||
124 | .map(Arc::new); | ||
125 | let segment = PathSegment { name: name.as_name(), args_and_bindings: args }; | ||
126 | segments.push(segment); | ||
127 | } | ||
128 | ast::PathSegmentKind::Type { type_ref, trait_ref } => { | ||
129 | assert!(path.qualifier().is_none()); // this can only occur at the first segment | ||
130 | |||
131 | let self_type = TypeRef::from_ast(type_ref?); | ||
132 | |||
133 | match trait_ref { | ||
134 | // <T>::foo | ||
135 | None => { | ||
136 | kind = PathKind::Type(Box::new(self_type)); | ||
137 | } | ||
138 | // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo | ||
139 | Some(trait_ref) => { | ||
140 | let path = Path::parse(trait_ref.path()?, macro_crate)?; | ||
141 | kind = path.kind; | ||
142 | let mut prefix_segments = path.segments; | ||
143 | prefix_segments.reverse(); | ||
144 | segments.extend(prefix_segments); | ||
145 | // Insert the type reference (T in the above example) as Self parameter for the trait | ||
146 | let mut last_segment = segments.last_mut()?; | ||
147 | if last_segment.args_and_bindings.is_none() { | ||
148 | last_segment.args_and_bindings = | ||
149 | Some(Arc::new(GenericArgs::empty())); | ||
150 | }; | ||
151 | let args = last_segment.args_and_bindings.as_mut().unwrap(); | ||
152 | let mut args_inner = Arc::make_mut(args); | ||
153 | args_inner.has_self_type = true; | ||
154 | args_inner.args.insert(0, GenericArg::Type(self_type)); | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | ast::PathSegmentKind::CrateKw => { | ||
159 | kind = PathKind::Crate; | ||
160 | break; | ||
161 | } | ||
162 | ast::PathSegmentKind::SelfKw => { | ||
163 | kind = PathKind::Self_; | ||
164 | break; | ||
165 | } | ||
166 | ast::PathSegmentKind::SuperKw => { | ||
167 | kind = PathKind::Super; | ||
168 | break; | ||
169 | } | ||
170 | } | ||
171 | path = match qualifier(&path) { | ||
172 | Some(it) => it, | ||
173 | None => break, | ||
174 | }; | ||
175 | } | ||
176 | segments.reverse(); | ||
177 | return Some(Path { kind, segments }); | ||
178 | |||
179 | fn qualifier(path: &ast::Path) -> Option<ast::Path> { | ||
180 | if let Some(q) = path.qualifier() { | ||
181 | return Some(q); | ||
182 | } | ||
183 | // FIXME: this bottom up traversal is not too precise. | ||
184 | // Should we handle do a top-down analysis, recording results? | ||
185 | let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; | ||
186 | let use_tree = use_tree_list.parent_use_tree(); | ||
187 | use_tree.path() | ||
188 | } | ||
189 | } | ||
190 | |||
191 | /// Converts an `ast::NameRef` into a single-identifier `Path`. | ||
192 | pub fn from_name_ref(name_ref: &ast::NameRef) -> Path { | ||
193 | name_ref.as_name().into() | ||
194 | } | ||
195 | |||
196 | /// `true` is this path is a single identifier, like `foo` | ||
197 | pub fn is_ident(&self) -> bool { | ||
198 | self.kind == PathKind::Plain && self.segments.len() == 1 | ||
199 | } | ||
200 | |||
201 | /// `true` if this path is just a standalone `self` | ||
202 | pub fn is_self(&self) -> bool { | ||
203 | self.kind == PathKind::Self_ && self.segments.is_empty() | ||
204 | } | ||
205 | |||
206 | /// If this path is a single identifier, like `foo`, return its name. | ||
207 | pub fn as_ident(&self) -> Option<&Name> { | ||
208 | if self.kind != PathKind::Plain || self.segments.len() > 1 { | ||
209 | return None; | ||
210 | } | ||
211 | self.segments.first().map(|s| &s.name) | ||
212 | } | ||
213 | |||
214 | pub fn expand_macro_expr(&self) -> Option<Name> { | ||
215 | self.as_ident().and_then(|name| Some(name.clone())) | ||
216 | } | ||
217 | |||
218 | pub fn is_type_relative(&self) -> bool { | ||
219 | match self.kind { | ||
220 | PathKind::Type(_) => true, | ||
221 | _ => false, | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | impl GenericArgs { | ||
227 | pub(crate) fn from_ast(node: ast::TypeArgList) -> Option<GenericArgs> { | ||
228 | let mut args = Vec::new(); | ||
229 | for type_arg in node.type_args() { | ||
230 | let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); | ||
231 | args.push(GenericArg::Type(type_ref)); | ||
232 | } | ||
233 | // lifetimes ignored for now | ||
234 | let mut bindings = Vec::new(); | ||
235 | for assoc_type_arg in node.assoc_type_args() { | ||
236 | if let Some(name_ref) = assoc_type_arg.name_ref() { | ||
237 | let name = name_ref.as_name(); | ||
238 | let type_ref = TypeRef::from_ast_opt(assoc_type_arg.type_ref()); | ||
239 | bindings.push((name, type_ref)); | ||
240 | } | ||
241 | } | ||
242 | if args.is_empty() && bindings.is_empty() { | ||
243 | None | ||
244 | } else { | ||
245 | Some(GenericArgs { args, has_self_type: false, bindings }) | ||
246 | } | ||
247 | } | ||
248 | |||
249 | /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) | ||
250 | /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). | ||
251 | pub(crate) fn from_fn_like_path_ast( | ||
252 | params: Option<ast::ParamList>, | ||
253 | ret_type: Option<ast::RetType>, | ||
254 | ) -> Option<GenericArgs> { | ||
255 | let mut args = Vec::new(); | ||
256 | let mut bindings = Vec::new(); | ||
257 | if let Some(params) = params { | ||
258 | let mut param_types = Vec::new(); | ||
259 | for param in params.params() { | ||
260 | let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); | ||
261 | param_types.push(type_ref); | ||
262 | } | ||
263 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); | ||
264 | args.push(arg); | ||
265 | } | ||
266 | if let Some(ret_type) = ret_type { | ||
267 | let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); | ||
268 | bindings.push((name::OUTPUT_TYPE, type_ref)) | ||
269 | } | ||
270 | if args.is_empty() && bindings.is_empty() { | ||
271 | None | ||
272 | } else { | ||
273 | Some(GenericArgs { args, has_self_type: false, bindings }) | ||
274 | } | ||
275 | } | ||
276 | |||
277 | pub(crate) fn empty() -> GenericArgs { | ||
278 | GenericArgs { args: Vec::new(), has_self_type: false, bindings: Vec::new() } | ||
279 | } | ||
280 | } | ||
281 | |||
282 | impl From<Name> for Path { | ||
283 | fn from(name: Name) -> Path { | ||
284 | Path::from_simple_segments(PathKind::Plain, iter::once(name)) | ||
285 | } | ||
286 | } | ||
287 | |||
288 | fn expand_use_tree( | ||
289 | prefix: Option<Path>, | ||
290 | tree: ast::UseTree, | ||
291 | macro_crate: &impl Fn() -> Option<Crate>, | ||
292 | cb: &mut impl FnMut(Path, &ast::UseTree, bool, Option<Name>), | ||
293 | ) { | ||
294 | if let Some(use_tree_list) = tree.use_tree_list() { | ||
295 | let prefix = match tree.path() { | ||
296 | // E.g. use something::{{{inner}}}; | ||
297 | None => prefix, | ||
298 | // E.g. `use something::{inner}` (prefix is `None`, path is `something`) | ||
299 | // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) | ||
300 | Some(path) => match convert_path(prefix, path, macro_crate) { | ||
301 | Some(it) => Some(it), | ||
302 | None => return, // FIXME: report errors somewhere | ||
303 | }, | ||
304 | }; | ||
305 | for child_tree in use_tree_list.use_trees() { | ||
306 | expand_use_tree(prefix.clone(), child_tree, macro_crate, cb); | ||
307 | } | ||
308 | } else { | ||
309 | let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); | ||
310 | if let Some(ast_path) = tree.path() { | ||
311 | // Handle self in a path. | ||
312 | // E.g. `use something::{self, <...>}` | ||
313 | if ast_path.qualifier().is_none() { | ||
314 | if let Some(segment) = ast_path.segment() { | ||
315 | if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { | ||
316 | if let Some(prefix) = prefix { | ||
317 | cb(prefix, &tree, false, alias); | ||
318 | return; | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | if let Some(path) = convert_path(prefix, ast_path, macro_crate) { | ||
324 | let is_glob = tree.has_star(); | ||
325 | cb(path, &tree, is_glob, alias) | ||
326 | } | ||
327 | // FIXME: report errors somewhere | ||
328 | // We get here if we do | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | |||
333 | fn convert_path( | ||
334 | prefix: Option<Path>, | ||
335 | path: ast::Path, | ||
336 | macro_crate: &impl Fn() -> Option<Crate>, | ||
337 | ) -> Option<Path> { | ||
338 | let prefix = if let Some(qual) = path.qualifier() { | ||
339 | Some(convert_path(prefix, qual, macro_crate)?) | ||
340 | } else { | ||
341 | prefix | ||
342 | }; | ||
343 | |||
344 | let segment = path.segment()?; | ||
345 | let res = match segment.kind()? { | ||
346 | ast::PathSegmentKind::Name(name) => { | ||
347 | if name.text() == "$crate" { | ||
348 | if let Some(krate) = macro_crate() { | ||
349 | return Some(Path::from_simple_segments( | ||
350 | PathKind::DollarCrate(krate), | ||
351 | iter::empty(), | ||
352 | )); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | // no type args in use | ||
357 | let mut res = prefix | ||
358 | .unwrap_or_else(|| Path { kind: PathKind::Plain, segments: Vec::with_capacity(1) }); | ||
359 | res.segments.push(PathSegment { | ||
360 | name: name.as_name(), | ||
361 | args_and_bindings: None, // no type args in use | ||
362 | }); | ||
363 | res | ||
364 | } | ||
365 | ast::PathSegmentKind::CrateKw => { | ||
366 | if prefix.is_some() { | ||
367 | return None; | ||
368 | } | ||
369 | Path::from_simple_segments(PathKind::Crate, iter::empty()) | ||
370 | } | ||
371 | ast::PathSegmentKind::SelfKw => { | ||
372 | if prefix.is_some() { | ||
373 | return None; | ||
374 | } | ||
375 | Path::from_simple_segments(PathKind::Self_, iter::empty()) | ||
376 | } | ||
377 | ast::PathSegmentKind::SuperKw => { | ||
378 | if prefix.is_some() { | ||
379 | return None; | ||
380 | } | ||
381 | Path::from_simple_segments(PathKind::Super, iter::empty()) | ||
382 | } | ||
383 | ast::PathSegmentKind::Type { .. } => { | ||
384 | // not allowed in imports | ||
385 | return None; | ||
386 | } | ||
387 | }; | ||
388 | Some(res) | ||
389 | } | ||
390 | |||
391 | pub mod known { | ||
392 | use super::{Path, PathKind}; | ||
393 | use crate::name; | ||
394 | |||
395 | pub fn std_iter_into_iterator() -> Path { | ||
396 | Path::from_simple_segments( | ||
397 | PathKind::Abs, | ||
398 | vec![name::STD, name::ITER, name::INTO_ITERATOR_TYPE], | ||
399 | ) | ||
400 | } | ||
401 | |||
402 | pub fn std_ops_try() -> Path { | ||
403 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE]) | ||
404 | } | ||
405 | |||
406 | pub fn std_result_result() -> Path { | ||
407 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) | ||
408 | } | ||
409 | |||
410 | pub fn std_future_future() -> Path { | ||
411 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::FUTURE, name::FUTURE_TYPE]) | ||
412 | } | ||
413 | |||
414 | pub fn std_boxed_box() -> Path { | ||
415 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::BOXED, name::BOX_TYPE]) | ||
416 | } | ||
417 | } | ||
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 3c797c0c3..75b24d386 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -1,6 +1,12 @@ | |||
1 | //! Name resolution. | 1 | //! Name resolution. |
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use hir_def::{ | ||
5 | builtin_type::BuiltinType, | ||
6 | path::{Path, PathKind}, | ||
7 | CrateModuleId, | ||
8 | }; | ||
9 | use hir_expand::name::{self, Name}; | ||
4 | use rustc_hash::FxHashSet; | 10 | use rustc_hash::FxHashSet; |
5 | 11 | ||
6 | use crate::{ | 12 | use crate::{ |
@@ -12,11 +18,8 @@ use crate::{ | |||
12 | }, | 18 | }, |
13 | generics::GenericParams, | 19 | generics::GenericParams, |
14 | impl_block::ImplBlock, | 20 | impl_block::ImplBlock, |
15 | name::{Name, SELF_PARAM, SELF_TYPE}, | 21 | nameres::{CrateDefMap, PerNs}, |
16 | nameres::{CrateDefMap, CrateModuleId, PerNs}, | 22 | Adt, Const, Enum, EnumVariant, Function, MacroDef, ModuleDef, Static, Struct, Trait, TypeAlias, |
17 | path::{Path, PathKind}, | ||
18 | Adt, BuiltinType, Const, Enum, EnumVariant, Function, MacroDef, ModuleDef, Static, Struct, | ||
19 | Trait, TypeAlias, | ||
20 | }; | 23 | }; |
21 | 24 | ||
22 | #[derive(Debug, Clone, Default)] | 25 | #[derive(Debug, Clone, Default)] |
@@ -149,13 +152,13 @@ impl Resolver { | |||
149 | } | 152 | } |
150 | } | 153 | } |
151 | Scope::ImplBlockScope(impl_) => { | 154 | Scope::ImplBlockScope(impl_) => { |
152 | if first_name == &SELF_TYPE { | 155 | if first_name == &name::SELF_TYPE { |
153 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 156 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
154 | return Some((TypeNs::SelfType(*impl_), idx)); | 157 | return Some((TypeNs::SelfType(*impl_), idx)); |
155 | } | 158 | } |
156 | } | 159 | } |
157 | Scope::AdtScope(adt) => { | 160 | Scope::AdtScope(adt) => { |
158 | if first_name == &SELF_TYPE { | 161 | if first_name == &name::SELF_TYPE { |
159 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 162 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
160 | return Some((TypeNs::AdtSelfType(*adt), idx)); | 163 | return Some((TypeNs::AdtSelfType(*adt), idx)); |
161 | } | 164 | } |
@@ -204,7 +207,7 @@ impl Resolver { | |||
204 | return None; | 207 | return None; |
205 | } | 208 | } |
206 | let n_segments = path.segments.len(); | 209 | let n_segments = path.segments.len(); |
207 | let tmp = SELF_PARAM; | 210 | let tmp = name::SELF_PARAM; |
208 | let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; | 211 | let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; |
209 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); | 212 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); |
210 | for scope in self.scopes.iter().rev() { | 213 | for scope in self.scopes.iter().rev() { |
@@ -240,13 +243,13 @@ impl Resolver { | |||
240 | Scope::GenericParams(_) => continue, | 243 | Scope::GenericParams(_) => continue, |
241 | 244 | ||
242 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { | 245 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { |
243 | if first_name == &SELF_TYPE { | 246 | if first_name == &name::SELF_TYPE { |
244 | let ty = TypeNs::SelfType(*impl_); | 247 | let ty = TypeNs::SelfType(*impl_); |
245 | return Some(ResolveValueResult::Partial(ty, 1)); | 248 | return Some(ResolveValueResult::Partial(ty, 1)); |
246 | } | 249 | } |
247 | } | 250 | } |
248 | Scope::AdtScope(adt) if n_segments > 1 => { | 251 | Scope::AdtScope(adt) if n_segments > 1 => { |
249 | if first_name == &SELF_TYPE { | 252 | if first_name == &name::SELF_TYPE { |
250 | let ty = TypeNs::AdtSelfType(*adt); | 253 | let ty = TypeNs::AdtSelfType(*adt); |
251 | return Some(ResolveValueResult::Partial(ty, 1)); | 254 | return Some(ResolveValueResult::Partial(ty, 1)); |
252 | } | 255 | } |
@@ -330,8 +333,8 @@ impl Resolver { | |||
330 | for scope in &self.scopes { | 333 | for scope in &self.scopes { |
331 | if let Scope::ModuleScope(m) = scope { | 334 | if let Scope::ModuleScope(m) = scope { |
332 | if let Some(prelude) = m.crate_def_map.prelude() { | 335 | if let Some(prelude) = m.crate_def_map.prelude() { |
333 | let prelude_def_map = db.crate_def_map(prelude.krate); | 336 | let prelude_def_map = db.crate_def_map(prelude.krate()); |
334 | traits.extend(prelude_def_map[prelude.module_id].scope.traits()); | 337 | traits.extend(prelude_def_map[prelude.id.module_id].scope.traits()); |
335 | } | 338 | } |
336 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); | 339 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); |
337 | } | 340 | } |
@@ -444,10 +447,12 @@ impl Scope { | |||
444 | f(name.clone(), ScopeDef::ModuleDef(*def)); | 447 | f(name.clone(), ScopeDef::ModuleDef(*def)); |
445 | }); | 448 | }); |
446 | if let Some(prelude) = m.crate_def_map.prelude() { | 449 | if let Some(prelude) = m.crate_def_map.prelude() { |
447 | let prelude_def_map = db.crate_def_map(prelude.krate); | 450 | let prelude_def_map = db.crate_def_map(prelude.krate()); |
448 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { | 451 | prelude_def_map[prelude.id.module_id].scope.entries().for_each( |
449 | f(name.clone(), res.def.into()); | 452 | |(name, res)| { |
450 | }); | 453 | f(name.clone(), res.def.into()); |
454 | }, | ||
455 | ); | ||
451 | } | 456 | } |
452 | } | 457 | } |
453 | Scope::GenericParams(gp) => { | 458 | Scope::GenericParams(gp) => { |
@@ -456,10 +461,10 @@ impl Scope { | |||
456 | } | 461 | } |
457 | } | 462 | } |
458 | Scope::ImplBlockScope(i) => { | 463 | Scope::ImplBlockScope(i) => { |
459 | f(SELF_TYPE, ScopeDef::ImplSelfType(*i)); | 464 | f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i)); |
460 | } | 465 | } |
461 | Scope::AdtScope(i) => { | 466 | Scope::AdtScope(i) => { |
462 | f(SELF_TYPE, ScopeDef::AdtSelfType(*i)); | 467 | f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); |
463 | } | 468 | } |
464 | Scope::ExprScope(e) => { | 469 | Scope::ExprScope(e) => { |
465 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { | 470 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index a907d6a9f..152bc71bd 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -7,10 +7,12 @@ | |||
7 | //! purely for "IDE needs". | 7 | //! purely for "IDE needs". |
8 | use std::sync::Arc; | 8 | use std::sync::Arc; |
9 | 9 | ||
10 | use hir_def::path::known; | ||
11 | use hir_expand::name::AsName; | ||
10 | use ra_db::FileId; | 12 | use ra_db::FileId; |
11 | use ra_syntax::{ | 13 | use ra_syntax::{ |
12 | ast::{self, AstNode}, | 14 | ast::{self, AstNode}, |
13 | AstPtr, | 15 | match_ast, AstPtr, |
14 | SyntaxKind::*, | 16 | SyntaxKind::*, |
15 | SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, | 17 | SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, |
16 | }; | 18 | }; |
@@ -24,11 +26,10 @@ use crate::{ | |||
24 | BodySourceMap, | 26 | BodySourceMap, |
25 | }, | 27 | }, |
26 | ids::LocationCtx, | 28 | ids::LocationCtx, |
27 | path::known, | ||
28 | resolve::{ScopeDef, TypeNs, ValueNs}, | 29 | resolve::{ScopeDef, TypeNs, ValueNs}, |
29 | ty::method_resolution::implements_trait, | 30 | ty::method_resolution::implements_trait, |
30 | AsName, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId, MacroDef, | 31 | Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId, MacroDef, Module, |
31 | Module, Name, Path, Resolver, Static, Struct, Ty, | 32 | Name, Path, Resolver, Static, Struct, Ty, |
32 | }; | 33 | }; |
33 | 34 | ||
34 | fn try_get_resolver_for_node( | 35 | fn try_get_resolver_for_node( |
@@ -36,24 +37,34 @@ fn try_get_resolver_for_node( | |||
36 | file_id: FileId, | 37 | file_id: FileId, |
37 | node: &SyntaxNode, | 38 | node: &SyntaxNode, |
38 | ) -> Option<Resolver> { | 39 | ) -> Option<Resolver> { |
39 | if let Some(module) = ast::Module::cast(node.clone()) { | 40 | match_ast! { |
40 | let src = crate::Source { file_id: file_id.into(), ast: module }; | 41 | match node { |
41 | Some(crate::Module::from_declaration(db, src)?.resolver(db)) | 42 | ast::Module(it) => { |
42 | } else if let Some(file) = ast::SourceFile::cast(node.clone()) { | 43 | let src = crate::Source { file_id: file_id.into(), ast: it }; |
43 | let src = | 44 | Some(crate::Module::from_declaration(db, src)?.resolver(db)) |
44 | crate::Source { file_id: file_id.into(), ast: crate::ModuleSource::SourceFile(file) }; | 45 | }, |
45 | Some(crate::Module::from_definition(db, src)?.resolver(db)) | 46 | ast::SourceFile(it) => { |
46 | } else if let Some(s) = ast::StructDef::cast(node.clone()) { | 47 | let src = |
47 | let src = crate::Source { file_id: file_id.into(), ast: s }; | 48 | crate::Source { file_id: file_id.into(), ast: crate::ModuleSource::SourceFile(it) }; |
48 | Some(Struct::from_source(db, src)?.resolver(db)) | 49 | Some(crate::Module::from_definition(db, src)?.resolver(db)) |
49 | } else if let Some(e) = ast::EnumDef::cast(node.clone()) { | 50 | }, |
50 | let src = crate::Source { file_id: file_id.into(), ast: e }; | 51 | ast::StructDef(it) => { |
51 | Some(Enum::from_source(db, src)?.resolver(db)) | 52 | let src = crate::Source { file_id: file_id.into(), ast: it }; |
52 | } else if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { | 53 | Some(Struct::from_source(db, src)?.resolver(db)) |
53 | Some(def_with_body_from_child_node(db, file_id, node)?.resolver(db)) | 54 | }, |
54 | } else { | 55 | ast::EnumDef(it) => { |
55 | // FIXME add missing cases | 56 | let src = crate::Source { file_id: file_id.into(), ast: it }; |
56 | None | 57 | Some(Enum::from_source(db, src)?.resolver(db)) |
58 | }, | ||
59 | _ => { | ||
60 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { | ||
61 | Some(def_with_body_from_child_node(db, file_id, node)?.resolver(db)) | ||
62 | } else { | ||
63 | // FIXME add missing cases | ||
64 | None | ||
65 | } | ||
66 | }, | ||
67 | } | ||
57 | } | 68 | } |
58 | } | 69 | } |
59 | 70 | ||
@@ -64,19 +75,17 @@ fn def_with_body_from_child_node( | |||
64 | ) -> Option<DefWithBody> { | 75 | ) -> Option<DefWithBody> { |
65 | let src = crate::ModuleSource::from_child_node(db, file_id, node); | 76 | let src = crate::ModuleSource::from_child_node(db, file_id, node); |
66 | let module = Module::from_definition(db, crate::Source { file_id: file_id.into(), ast: src })?; | 77 | let module = Module::from_definition(db, crate::Source { file_id: file_id.into(), ast: src })?; |
67 | let ctx = LocationCtx::new(db, module, file_id.into()); | 78 | let ctx = LocationCtx::new(db, module.id, file_id.into()); |
68 | 79 | ||
69 | node.ancestors().find_map(|node| { | 80 | node.ancestors().find_map(|node| { |
70 | if let Some(def) = ast::FnDef::cast(node.clone()) { | 81 | match_ast! { |
71 | return Some(Function { id: ctx.to_def(&def) }.into()); | 82 | match node { |
72 | } | 83 | ast::FnDef(def) => { Some(Function {id: ctx.to_def(&def) }.into()) }, |
73 | if let Some(def) = ast::ConstDef::cast(node.clone()) { | 84 | ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) }, |
74 | return Some(Const { id: ctx.to_def(&def) }.into()); | 85 | ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, |
75 | } | 86 | _ => { None }, |
76 | if let Some(def) = ast::StaticDef::cast(node) { | 87 | } |
77 | return Some(Static { id: ctx.to_def(&def) }.into()); | ||
78 | } | 88 | } |
79 | None | ||
80 | }) | 89 | }) |
81 | } | 90 | } |
82 | 91 | ||
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs deleted file mode 100644 index a4dd99598..000000000 --- a/crates/ra_hir/src/source_id.rs +++ /dev/null | |||
@@ -1,161 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use std::{ | ||
4 | hash::{Hash, Hasher}, | ||
5 | marker::PhantomData, | ||
6 | sync::Arc, | ||
7 | }; | ||
8 | |||
9 | use ra_arena::{impl_arena_id, Arena, RawId}; | ||
10 | use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxNodePtr}; | ||
11 | |||
12 | use crate::{db::AstDatabase, HirFileId}; | ||
13 | |||
14 | /// `AstId` points to an AST node in any file. | ||
15 | /// | ||
16 | /// It is stable across reparses, and can be used as salsa key/value. | ||
17 | #[derive(Debug)] | ||
18 | pub(crate) struct AstId<N: AstNode> { | ||
19 | file_id: HirFileId, | ||
20 | file_ast_id: FileAstId<N>, | ||
21 | } | ||
22 | |||
23 | impl<N: AstNode> Clone for AstId<N> { | ||
24 | fn clone(&self) -> AstId<N> { | ||
25 | *self | ||
26 | } | ||
27 | } | ||
28 | impl<N: AstNode> Copy for AstId<N> {} | ||
29 | |||
30 | impl<N: AstNode> PartialEq for AstId<N> { | ||
31 | fn eq(&self, other: &Self) -> bool { | ||
32 | (self.file_id, self.file_ast_id) == (other.file_id, other.file_ast_id) | ||
33 | } | ||
34 | } | ||
35 | impl<N: AstNode> Eq for AstId<N> {} | ||
36 | impl<N: AstNode> Hash for AstId<N> { | ||
37 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
38 | (self.file_id, self.file_ast_id).hash(hasher); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | impl<N: AstNode> AstId<N> { | ||
43 | pub(crate) fn file_id(&self) -> HirFileId { | ||
44 | self.file_id | ||
45 | } | ||
46 | |||
47 | pub(crate) fn to_node(&self, db: &impl AstDatabase) -> N { | ||
48 | let syntax_node = db.ast_id_to_node(self.file_id, self.file_ast_id.raw); | ||
49 | N::cast(syntax_node).unwrap() | ||
50 | } | ||
51 | } | ||
52 | |||
53 | /// `AstId` points to an AST node in a specific file. | ||
54 | #[derive(Debug)] | ||
55 | pub(crate) struct FileAstId<N: AstNode> { | ||
56 | raw: ErasedFileAstId, | ||
57 | _ty: PhantomData<fn() -> N>, | ||
58 | } | ||
59 | |||
60 | impl<N: AstNode> Clone for FileAstId<N> { | ||
61 | fn clone(&self) -> FileAstId<N> { | ||
62 | *self | ||
63 | } | ||
64 | } | ||
65 | impl<N: AstNode> Copy for FileAstId<N> {} | ||
66 | |||
67 | impl<N: AstNode> PartialEq for FileAstId<N> { | ||
68 | fn eq(&self, other: &Self) -> bool { | ||
69 | self.raw == other.raw | ||
70 | } | ||
71 | } | ||
72 | impl<N: AstNode> Eq for FileAstId<N> {} | ||
73 | impl<N: AstNode> Hash for FileAstId<N> { | ||
74 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
75 | self.raw.hash(hasher); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | impl<N: AstNode> FileAstId<N> { | ||
80 | pub(crate) fn with_file_id(self, file_id: HirFileId) -> AstId<N> { | ||
81 | AstId { file_id, file_ast_id: self } | ||
82 | } | ||
83 | } | ||
84 | |||
85 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
86 | pub struct ErasedFileAstId(RawId); | ||
87 | impl_arena_id!(ErasedFileAstId); | ||
88 | |||
89 | /// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back. | ||
90 | #[derive(Debug, PartialEq, Eq, Default)] | ||
91 | pub struct AstIdMap { | ||
92 | arena: Arena<ErasedFileAstId, SyntaxNodePtr>, | ||
93 | } | ||
94 | |||
95 | impl AstIdMap { | ||
96 | pub(crate) fn ast_id_map_query(db: &impl AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { | ||
97 | let map = if let Some(node) = db.parse_or_expand(file_id) { | ||
98 | AstIdMap::from_source(&node) | ||
99 | } else { | ||
100 | AstIdMap::default() | ||
101 | }; | ||
102 | Arc::new(map) | ||
103 | } | ||
104 | |||
105 | pub(crate) fn file_item_query( | ||
106 | db: &impl AstDatabase, | ||
107 | file_id: HirFileId, | ||
108 | ast_id: ErasedFileAstId, | ||
109 | ) -> SyntaxNode { | ||
110 | let node = db.parse_or_expand(file_id).unwrap(); | ||
111 | db.ast_id_map(file_id).arena[ast_id].to_node(&node) | ||
112 | } | ||
113 | |||
114 | pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> { | ||
115 | let ptr = SyntaxNodePtr::new(item.syntax()); | ||
116 | let raw = match self.arena.iter().find(|(_id, i)| **i == ptr) { | ||
117 | Some((it, _)) => it, | ||
118 | None => panic!( | ||
119 | "Can't find {:?} in AstIdMap:\n{:?}", | ||
120 | item.syntax(), | ||
121 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | ||
122 | ), | ||
123 | }; | ||
124 | |||
125 | FileAstId { raw, _ty: PhantomData } | ||
126 | } | ||
127 | |||
128 | fn from_source(node: &SyntaxNode) -> AstIdMap { | ||
129 | assert!(node.parent().is_none()); | ||
130 | let mut res = AstIdMap { arena: Arena::default() }; | ||
131 | // By walking the tree in bread-first order we make sure that parents | ||
132 | // get lower ids then children. That is, adding a new child does not | ||
133 | // change parent's id. This means that, say, adding a new function to a | ||
134 | // trait does not change ids of top-level items, which helps caching. | ||
135 | bfs(node, |it| { | ||
136 | if let Some(module_item) = ast::ModuleItem::cast(it.clone()) { | ||
137 | res.alloc(module_item.syntax()); | ||
138 | } else if let Some(macro_call) = ast::MacroCall::cast(it) { | ||
139 | res.alloc(macro_call.syntax()); | ||
140 | } | ||
141 | }); | ||
142 | res | ||
143 | } | ||
144 | |||
145 | fn alloc(&mut self, item: &SyntaxNode) -> ErasedFileAstId { | ||
146 | self.arena.alloc(SyntaxNodePtr::new(item)) | ||
147 | } | ||
148 | } | ||
149 | |||
150 | /// Walks the subtree in bfs order, calling `f` for each node. | ||
151 | fn bfs(node: &SyntaxNode, mut f: impl FnMut(SyntaxNode)) { | ||
152 | let mut curr_layer = vec![node.clone()]; | ||
153 | let mut next_layer = vec![]; | ||
154 | while !curr_layer.is_empty() { | ||
155 | curr_layer.drain(..).for_each(|node| { | ||
156 | next_layer.extend(node.children()); | ||
157 | f(node); | ||
158 | }); | ||
159 | std::mem::swap(&mut curr_layer, &mut next_layer); | ||
160 | } | ||
161 | } | ||
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs index e39511518..1a45dacba 100644 --- a/crates/ra_hir/src/traits.rs +++ b/crates/ra_hir/src/traits.rs | |||
@@ -1,14 +1,15 @@ | |||
1 | //! HIR for trait definitions. | 1 | //! HIR for trait definitions. |
2 | 2 | ||
3 | use rustc_hash::FxHashMap; | ||
4 | use std::sync::Arc; | 3 | use std::sync::Arc; |
5 | 4 | ||
5 | use hir_expand::name::AsName; | ||
6 | |||
6 | use ra_syntax::ast::{self, NameOwner}; | 7 | use ra_syntax::ast::{self, NameOwner}; |
8 | use rustc_hash::FxHashMap; | ||
7 | 9 | ||
8 | use crate::{ | 10 | use crate::{ |
9 | db::{AstDatabase, DefDatabase}, | 11 | db::{AstDatabase, DefDatabase}, |
10 | ids::LocationCtx, | 12 | ids::LocationCtx, |
11 | name::AsName, | ||
12 | AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias, | 13 | AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias, |
13 | }; | 14 | }; |
14 | 15 | ||
@@ -27,7 +28,7 @@ impl TraitData { | |||
27 | let src = tr.source(db); | 28 | let src = tr.source(db); |
28 | let name = src.ast.name().map(|n| n.as_name()); | 29 | let name = src.ast.name().map(|n| n.as_name()); |
29 | let module = tr.module(db); | 30 | let module = tr.module(db); |
30 | let ctx = LocationCtx::new(db, module, src.file_id); | 31 | let ctx = LocationCtx::new(db, module.id, src.file_id); |
31 | let auto = src.ast.is_auto(); | 32 | let auto = src.ast.is_auto(); |
32 | let items = if let Some(item_list) = src.ast.item_list() { | 33 | let items = if let Some(item_list) = src.ast.item_list() { |
33 | item_list | 34 | item_list |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index cc9746f6d..d2bfcdc7d 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -17,8 +17,8 @@ use std::sync::Arc; | |||
17 | use std::{fmt, iter, mem}; | 17 | use std::{fmt, iter, mem}; |
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
20 | db::HirDatabase, expr::ExprId, type_ref::Mutability, util::make_mut_slice, Adt, Crate, | 20 | db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, GenericParams, |
21 | DefWithBody, GenericParams, HasGenericParams, Name, Trait, TypeAlias, | 21 | HasGenericParams, Mutability, Name, Trait, TypeAlias, |
22 | }; | 22 | }; |
23 | use display::{HirDisplay, HirFormatter}; | 23 | use display::{HirDisplay, HirFormatter}; |
24 | 24 | ||
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 02492ca14..3645ee831 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs | |||
@@ -5,10 +5,11 @@ | |||
5 | 5 | ||
6 | use std::iter::successors; | 6 | use std::iter::successors; |
7 | 7 | ||
8 | use hir_expand::name; | ||
8 | use log::{info, warn}; | 9 | use log::{info, warn}; |
9 | 10 | ||
10 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; | 11 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; |
11 | use crate::{db::HirDatabase, name, HasGenericParams, Resolver}; | 12 | use crate::{db::HirDatabase, HasGenericParams, Resolver}; |
12 | 13 | ||
13 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 14 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
14 | 15 | ||
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index ebaff998e..6694467a3 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -21,6 +21,11 @@ use std::sync::Arc; | |||
21 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 21 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
22 | use rustc_hash::FxHashMap; | 22 | use rustc_hash::FxHashMap; |
23 | 23 | ||
24 | use hir_def::{ | ||
25 | path::known, | ||
26 | type_ref::{Mutability, TypeRef}, | ||
27 | }; | ||
28 | use hir_expand::name; | ||
24 | use ra_arena::map::ArenaMap; | 29 | use ra_arena::map::ArenaMap; |
25 | use ra_prof::profile; | 30 | use ra_prof::profile; |
26 | use test_utils::tested_by; | 31 | use test_utils::tested_by; |
@@ -37,11 +42,8 @@ use crate::{ | |||
37 | db::HirDatabase, | 42 | db::HirDatabase, |
38 | diagnostics::DiagnosticSink, | 43 | diagnostics::DiagnosticSink, |
39 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 44 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
40 | name, | ||
41 | path::known, | ||
42 | resolve::{Resolver, TypeNs}, | 45 | resolve::{Resolver, TypeNs}, |
43 | ty::infer::diagnostics::InferenceDiagnostic, | 46 | ty::infer::diagnostics::InferenceDiagnostic, |
44 | type_ref::{Mutability, TypeRef}, | ||
45 | Adt, AssocItem, ConstData, DefWithBody, FnData, Function, HasBody, Path, StructField, | 47 | Adt, AssocItem, ConstData, DefWithBody, FnData, Function, HasBody, Path, StructField, |
46 | }; | 48 | }; |
47 | 49 | ||
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 0429a9866..6ea135126 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs | |||
@@ -14,8 +14,7 @@ use crate::{ | |||
14 | lang_item::LangItemTarget, | 14 | lang_item::LangItemTarget, |
15 | resolve::Resolver, | 15 | resolve::Resolver, |
16 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, | 16 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, |
17 | type_ref::Mutability, | 17 | Adt, Mutability, |
18 | Adt, | ||
19 | }; | 18 | }; |
20 | 19 | ||
21 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 20 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index f8807c742..fed52df39 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -3,14 +3,15 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use hir_def::path::{GenericArg, GenericArgs}; | ||
7 | use hir_expand::name; | ||
8 | |||
6 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | 9 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; |
7 | use crate::{ | 10 | use crate::{ |
8 | db::HirDatabase, | 11 | db::HirDatabase, |
9 | expr::{self, Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 12 | expr::{self, Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
10 | generics::{GenericParams, HasGenericParams}, | 13 | generics::{GenericParams, HasGenericParams}, |
11 | name, | ||
12 | nameres::Namespace, | 14 | nameres::Namespace, |
13 | path::{GenericArg, GenericArgs}, | ||
14 | ty::{ | 15 | ty::{ |
15 | autoderef, method_resolution, op, primitive, CallableDef, InferTy, Mutability, Obligation, | 16 | autoderef, method_resolution, op, primitive, CallableDef, InferTy, Mutability, Obligation, |
16 | ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | 17 | ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, |
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index db979353a..77aa35ce1 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | //! Path expression resolution. | 1 | //! Path expression resolution. |
2 | 2 | ||
3 | use hir_def::path::PathSegment; | ||
4 | |||
3 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 5 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
4 | use crate::{ | 6 | use crate::{ |
5 | db::HirDatabase, | 7 | db::HirDatabase, |
@@ -131,7 +133,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
131 | fn resolve_trait_assoc_item( | 133 | fn resolve_trait_assoc_item( |
132 | &mut self, | 134 | &mut self, |
133 | trait_ref: TraitRef, | 135 | trait_ref: TraitRef, |
134 | segment: &crate::path::PathSegment, | 136 | segment: &PathSegment, |
135 | id: ExprOrPatId, | 137 | id: ExprOrPatId, |
136 | ) -> Option<(ValueNs, Option<Substs>)> { | 138 | ) -> Option<(ValueNs, Option<Substs>)> { |
137 | let trait_ = trait_ref.trait_; | 139 | let trait_ = trait_ref.trait_; |
@@ -170,7 +172,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
170 | fn resolve_ty_assoc_item( | 172 | fn resolve_ty_assoc_item( |
171 | &mut self, | 173 | &mut self, |
172 | ty: Ty, | 174 | ty: Ty, |
173 | segment: &crate::path::PathSegment, | 175 | segment: &PathSegment, |
174 | id: ExprOrPatId, | 176 | id: ExprOrPatId, |
175 | ) -> Option<(ValueNs, Option<Substs>)> { | 177 | ) -> Option<(ValueNs, Option<Substs>)> { |
176 | if let Ty::Unknown = ty { | 178 | if let Ty::Unknown = ty { |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 366556134..dd7cd979f 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -8,6 +8,12 @@ | |||
8 | use std::iter; | 8 | use std::iter; |
9 | use std::sync::Arc; | 9 | use std::sync::Arc; |
10 | 10 | ||
11 | use hir_def::{ | ||
12 | builtin_type::BuiltinType, | ||
13 | path::{GenericArg, PathSegment}, | ||
14 | type_ref::{TypeBound, TypeRef}, | ||
15 | }; | ||
16 | |||
11 | use super::{ | 17 | use super::{ |
12 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 18 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
13 | TypeWalk, | 19 | TypeWalk, |
@@ -18,13 +24,14 @@ use crate::{ | |||
18 | generics::HasGenericParams, | 24 | generics::HasGenericParams, |
19 | generics::{GenericDef, WherePredicate}, | 25 | generics::{GenericDef, WherePredicate}, |
20 | nameres::Namespace, | 26 | nameres::Namespace, |
21 | path::{GenericArg, PathSegment}, | ||
22 | resolve::{Resolver, TypeNs}, | 27 | resolve::{Resolver, TypeNs}, |
23 | ty::Adt, | 28 | ty::{ |
24 | type_ref::{TypeBound, TypeRef}, | 29 | primitive::{FloatTy, IntTy}, |
30 | Adt, | ||
31 | }, | ||
25 | util::make_mut_slice, | 32 | util::make_mut_slice, |
26 | BuiltinType, Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, | 33 | Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, |
27 | Trait, TypeAlias, Union, | 34 | TypeAlias, Union, |
28 | }; | 35 | }; |
29 | 36 | ||
30 | impl Ty { | 37 | impl Ty { |
@@ -640,8 +647,10 @@ fn type_for_builtin(def: BuiltinType) -> Ty { | |||
640 | BuiltinType::Char => TypeCtor::Char, | 647 | BuiltinType::Char => TypeCtor::Char, |
641 | BuiltinType::Bool => TypeCtor::Bool, | 648 | BuiltinType::Bool => TypeCtor::Bool, |
642 | BuiltinType::Str => TypeCtor::Str, | 649 | BuiltinType::Str => TypeCtor::Str, |
643 | BuiltinType::Int(ty) => TypeCtor::Int(ty.into()), | 650 | BuiltinType::Int { signedness, bitness } => { |
644 | BuiltinType::Float(ty) => TypeCtor::Float(ty.into()), | 651 | TypeCtor::Int(IntTy { signedness, bitness }.into()) |
652 | } | ||
653 | BuiltinType::Float { bitness } => TypeCtor::Float(FloatTy { bitness }.into()), | ||
645 | }) | 654 | }) |
646 | } | 655 | } |
647 | 656 | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index ad2ab560d..eb69344f6 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -5,18 +5,17 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::CrateModuleId; | ||
8 | use rustc_hash::FxHashMap; | 9 | use rustc_hash::FxHashMap; |
9 | 10 | ||
10 | use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 11 | use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; |
11 | use crate::{ | 12 | use crate::{ |
12 | db::HirDatabase, | 13 | db::HirDatabase, |
13 | impl_block::{ImplBlock, ImplId}, | 14 | impl_block::{ImplBlock, ImplId}, |
14 | nameres::CrateModuleId, | ||
15 | resolve::Resolver, | 15 | resolve::Resolver, |
16 | ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy}, | 16 | ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy}, |
17 | ty::{Ty, TypeCtor}, | 17 | ty::{Ty, TypeCtor}, |
18 | type_ref::Mutability, | 18 | AssocItem, Crate, Function, Module, Mutability, Name, Trait, |
19 | AssocItem, Crate, Function, Module, Name, Trait, | ||
20 | }; | 19 | }; |
21 | 20 | ||
22 | /// This is used as a key for indexing impls. | 21 | /// This is used as a key for indexing impls. |
@@ -50,7 +49,7 @@ impl CrateImplBlocks { | |||
50 | let fingerprint = TyFingerprint::for_impl(ty); | 49 | let fingerprint = TyFingerprint::for_impl(ty); |
51 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map( | 50 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map( |
52 | move |(module_id, impl_id)| { | 51 | move |(module_id, impl_id)| { |
53 | let module = Module { krate: self.krate, module_id: *module_id }; | 52 | let module = Module::new(self.krate, *module_id); |
54 | ImplBlock::from_id(module, *impl_id) | 53 | ImplBlock::from_id(module, *impl_id) |
55 | }, | 54 | }, |
56 | ) | 55 | ) |
@@ -62,7 +61,7 @@ impl CrateImplBlocks { | |||
62 | ) -> impl Iterator<Item = ImplBlock> + 'a { | 61 | ) -> impl Iterator<Item = ImplBlock> + 'a { |
63 | self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map( | 62 | self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map( |
64 | move |(module_id, impl_id)| { | 63 | move |(module_id, impl_id)| { |
65 | let module = Module { krate: self.krate, module_id: *module_id }; | 64 | let module = Module::new(self.krate, *module_id); |
66 | ImplBlock::from_id(module, *impl_id) | 65 | ImplBlock::from_id(module, *impl_id) |
67 | }, | 66 | }, |
68 | ) | 67 | ) |
@@ -71,7 +70,7 @@ impl CrateImplBlocks { | |||
71 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { | 70 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { |
72 | self.impls.values().chain(self.impls_by_trait.values()).flat_map(|i| i.iter()).map( | 71 | self.impls.values().chain(self.impls_by_trait.values()).flat_map(|i| i.iter()).map( |
73 | move |(module_id, impl_id)| { | 72 | move |(module_id, impl_id)| { |
74 | let module = Module { krate: self.krate, module_id: *module_id }; | 73 | let module = Module::new(self.krate, *module_id); |
75 | ImplBlock::from_id(module, *impl_id) | 74 | ImplBlock::from_id(module, *impl_id) |
76 | }, | 75 | }, |
77 | ) | 76 | ) |
@@ -90,14 +89,14 @@ impl CrateImplBlocks { | |||
90 | self.impls_by_trait | 89 | self.impls_by_trait |
91 | .entry(tr.trait_) | 90 | .entry(tr.trait_) |
92 | .or_insert_with(Vec::new) | 91 | .or_insert_with(Vec::new) |
93 | .push((module.module_id, impl_id)); | 92 | .push((module.id.module_id, impl_id)); |
94 | } | 93 | } |
95 | } else { | 94 | } else { |
96 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | 95 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { |
97 | self.impls | 96 | self.impls |
98 | .entry(target_ty_fp) | 97 | .entry(target_ty_fp) |
99 | .or_insert_with(Vec::new) | 98 | .or_insert_with(Vec::new) |
100 | .push((module.module_id, impl_id)); | 99 | .push((module.id.module_id, impl_id)); |
101 | } | 100 | } |
102 | } | 101 | } |
103 | } | 102 | } |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 8966f9d1d..1749752f1 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -2,27 +2,7 @@ | |||
2 | 2 | ||
3 | use std::fmt; | 3 | use std::fmt; |
4 | 4 | ||
5 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | 5 | pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness}; |
6 | pub enum Signedness { | ||
7 | Signed, | ||
8 | Unsigned, | ||
9 | } | ||
10 | |||
11 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | ||
12 | pub enum IntBitness { | ||
13 | Xsize, | ||
14 | X8, | ||
15 | X16, | ||
16 | X32, | ||
17 | X64, | ||
18 | X128, | ||
19 | } | ||
20 | |||
21 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | ||
22 | pub enum FloatBitness { | ||
23 | X32, | ||
24 | X64, | ||
25 | } | ||
26 | 6 | ||
27 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | 7 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] |
28 | pub enum UncertainIntTy { | 8 | pub enum UncertainIntTy { |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 0cb5c3798..4f1eab150 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Trait solving using Chalk. | 1 | //! Trait solving using Chalk. |
2 | use std::sync::{Arc, Mutex}; | 2 | use std::sync::{Arc, Mutex}; |
3 | 3 | ||
4 | use chalk_ir::cast::Cast; | 4 | use chalk_ir::{cast::Cast, family::ChalkIr}; |
5 | use log::debug; | 5 | use log::debug; |
6 | use ra_db::salsa; | 6 | use ra_db::salsa; |
7 | use ra_prof::profile; | 7 | use ra_prof::profile; |
@@ -33,7 +33,7 @@ impl TraitSolver { | |||
33 | fn solve( | 33 | fn solve( |
34 | &self, | 34 | &self, |
35 | db: &impl HirDatabase, | 35 | db: &impl HirDatabase, |
36 | goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal>>, | 36 | goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<ChalkIr>>>, |
37 | ) -> Option<chalk_solve::Solution> { | 37 | ) -> Option<chalk_solve::Solution> { |
38 | let context = ChalkContext { db, krate: self.krate }; | 38 | let context = ChalkContext { db, krate: self.krate }; |
39 | debug!("solve goal: {:?}", goal); | 39 | debug!("solve goal: {:?}", goal); |
@@ -196,7 +196,7 @@ pub(crate) fn trait_solve_query( | |||
196 | } | 196 | } |
197 | 197 | ||
198 | fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { | 198 | fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { |
199 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution>| { | 199 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<ChalkIr>>| { |
200 | let value = subst | 200 | let value = subst |
201 | .value | 201 | .value |
202 | .parameters | 202 | .parameters |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 00aaf65d9..39ef92182 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -4,11 +4,13 @@ use std::sync::Arc; | |||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{ | 6 | use chalk_ir::{ |
7 | cast::Cast, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, TypeKindId, TypeName, | 7 | cast::Cast, family::ChalkIr, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, |
8 | UniverseIndex, | 8 | TypeKindId, TypeName, UniverseIndex, |
9 | }; | 9 | }; |
10 | use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; | 10 | use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; |
11 | 11 | ||
12 | use hir_expand::name; | ||
13 | |||
12 | use ra_db::salsa::{InternId, InternKey}; | 14 | use ra_db::salsa::{InternId, InternKey}; |
13 | 15 | ||
14 | use super::{Canonical, ChalkContext, Impl, Obligation}; | 16 | use super::{Canonical, ChalkContext, Impl, Obligation}; |
@@ -38,8 +40,8 @@ where | |||
38 | } | 40 | } |
39 | 41 | ||
40 | impl ToChalk for Ty { | 42 | impl ToChalk for Ty { |
41 | type Chalk = chalk_ir::Ty; | 43 | type Chalk = chalk_ir::Ty<ChalkIr>; |
42 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty { | 44 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<ChalkIr> { |
43 | match self { | 45 | match self { |
44 | Ty::Apply(apply_ty) => { | 46 | Ty::Apply(apply_ty) => { |
45 | let name = match apply_ty.ctor { | 47 | let name = match apply_ty.ctor { |
@@ -62,21 +64,19 @@ impl ToChalk for Ty { | |||
62 | chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast() | 64 | chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast() |
63 | } | 65 | } |
64 | Ty::Param { idx, .. } => { | 66 | Ty::Param { idx, .. } => { |
65 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty() | 67 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::<ChalkIr>() |
66 | } | 68 | } |
67 | Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize), | 69 | Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize), |
68 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), | 70 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), |
69 | // FIXME this is clearly incorrect, but probably not too incorrect | 71 | // FIXME use Chalk's Dyn/Opaque once the bugs with that are fixed |
70 | // and I'm not sure what to actually do with Ty::Unknown | ||
71 | // maybe an alternative would be `for<T> T`? (meaningless in rust, but expressible in chalk's Ty) | ||
72 | // | ||
73 | // FIXME also dyn and impl Trait are currently handled like Unknown because Chalk doesn't have them yet | ||
74 | Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => { | 72 | Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => { |
75 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::max_value() }.to_ty() | 73 | let parameters = Vec::new(); |
74 | let name = TypeName::Error; | ||
75 | chalk_ir::ApplicationTy { name, parameters }.cast() | ||
76 | } | 76 | } |
77 | } | 77 | } |
78 | } | 78 | } |
79 | fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { | 79 | fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<ChalkIr>) -> Self { |
80 | match chalk { | 80 | match chalk { |
81 | chalk_ir::Ty::Apply(apply_ty) => { | 81 | chalk_ir::Ty::Apply(apply_ty) => { |
82 | // FIXME this is kind of hacky due to the fact that | 82 | // FIXME this is kind of hacky due to the fact that |
@@ -92,6 +92,7 @@ impl ToChalk for Ty { | |||
92 | let parameters = from_chalk(db, apply_ty.parameters); | 92 | let parameters = from_chalk(db, apply_ty.parameters); |
93 | Ty::Apply(ApplicationTy { ctor, parameters }) | 93 | Ty::Apply(ApplicationTy { ctor, parameters }) |
94 | } | 94 | } |
95 | TypeName::Error => Ty::Unknown, | ||
95 | // FIXME handle TypeKindId::Trait/Type here | 96 | // FIXME handle TypeKindId::Trait/Type here |
96 | TypeName::TypeKindId(_) => unimplemented!(), | 97 | TypeName::TypeKindId(_) => unimplemented!(), |
97 | TypeName::Placeholder(idx) => { | 98 | TypeName::Placeholder(idx) => { |
@@ -108,18 +109,30 @@ impl ToChalk for Ty { | |||
108 | chalk_ir::Ty::ForAll(_) => unimplemented!(), | 109 | chalk_ir::Ty::ForAll(_) => unimplemented!(), |
109 | chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32), | 110 | chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32), |
110 | chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown, | 111 | chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown, |
112 | chalk_ir::Ty::Dyn(where_clauses) => { | ||
113 | assert_eq!(where_clauses.binders.len(), 1); | ||
114 | let predicates = | ||
115 | where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); | ||
116 | Ty::Dyn(predicates) | ||
117 | } | ||
118 | chalk_ir::Ty::Opaque(where_clauses) => { | ||
119 | assert_eq!(where_clauses.binders.len(), 1); | ||
120 | let predicates = | ||
121 | where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); | ||
122 | Ty::Opaque(predicates) | ||
123 | } | ||
111 | } | 124 | } |
112 | } | 125 | } |
113 | } | 126 | } |
114 | 127 | ||
115 | impl ToChalk for Substs { | 128 | impl ToChalk for Substs { |
116 | type Chalk = Vec<chalk_ir::Parameter>; | 129 | type Chalk = Vec<chalk_ir::Parameter<ChalkIr>>; |
117 | 130 | ||
118 | fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter> { | 131 | fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<ChalkIr>> { |
119 | self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() | 132 | self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() |
120 | } | 133 | } |
121 | 134 | ||
122 | fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter>) -> Substs { | 135 | fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter<ChalkIr>>) -> Substs { |
123 | let tys = parameters | 136 | let tys = parameters |
124 | .into_iter() | 137 | .into_iter() |
125 | .map(|p| match p { | 138 | .map(|p| match p { |
@@ -132,15 +145,15 @@ impl ToChalk for Substs { | |||
132 | } | 145 | } |
133 | 146 | ||
134 | impl ToChalk for TraitRef { | 147 | impl ToChalk for TraitRef { |
135 | type Chalk = chalk_ir::TraitRef; | 148 | type Chalk = chalk_ir::TraitRef<ChalkIr>; |
136 | 149 | ||
137 | fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef { | 150 | fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<ChalkIr> { |
138 | let trait_id = self.trait_.to_chalk(db); | 151 | let trait_id = self.trait_.to_chalk(db); |
139 | let parameters = self.substs.to_chalk(db); | 152 | let parameters = self.substs.to_chalk(db); |
140 | chalk_ir::TraitRef { trait_id, parameters } | 153 | chalk_ir::TraitRef { trait_id, parameters } |
141 | } | 154 | } |
142 | 155 | ||
143 | fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef) -> Self { | 156 | fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<ChalkIr>) -> Self { |
144 | let trait_ = from_chalk(db, trait_ref.trait_id); | 157 | let trait_ = from_chalk(db, trait_ref.trait_id); |
145 | let substs = from_chalk(db, trait_ref.parameters); | 158 | let substs = from_chalk(db, trait_ref.parameters); |
146 | TraitRef { trait_, substs } | 159 | TraitRef { trait_, substs } |
@@ -151,11 +164,11 @@ impl ToChalk for Trait { | |||
151 | type Chalk = chalk_ir::TraitId; | 164 | type Chalk = chalk_ir::TraitId; |
152 | 165 | ||
153 | fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { | 166 | fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { |
154 | self.id.into() | 167 | chalk_ir::TraitId(id_to_chalk(self.id)) |
155 | } | 168 | } |
156 | 169 | ||
157 | fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait { | 170 | fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait { |
158 | Trait { id: trait_id.into() } | 171 | Trait { id: id_from_chalk(trait_id.0) } |
159 | } | 172 | } |
160 | } | 173 | } |
161 | 174 | ||
@@ -187,18 +200,18 @@ impl ToChalk for TypeAlias { | |||
187 | type Chalk = chalk_ir::TypeId; | 200 | type Chalk = chalk_ir::TypeId; |
188 | 201 | ||
189 | fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { | 202 | fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { |
190 | self.id.into() | 203 | chalk_ir::TypeId(id_to_chalk(self.id)) |
191 | } | 204 | } |
192 | 205 | ||
193 | fn from_chalk(_db: &impl HirDatabase, impl_id: chalk_ir::TypeId) -> TypeAlias { | 206 | fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAlias { |
194 | TypeAlias { id: impl_id.into() } | 207 | TypeAlias { id: id_from_chalk(type_alias_id.0) } |
195 | } | 208 | } |
196 | } | 209 | } |
197 | 210 | ||
198 | impl ToChalk for GenericPredicate { | 211 | impl ToChalk for GenericPredicate { |
199 | type Chalk = chalk_ir::QuantifiedWhereClause; | 212 | type Chalk = chalk_ir::QuantifiedWhereClause<ChalkIr>; |
200 | 213 | ||
201 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause { | 214 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<ChalkIr> { |
202 | match self { | 215 | match self { |
203 | GenericPredicate::Implemented(trait_ref) => { | 216 | GenericPredicate::Implemented(trait_ref) => { |
204 | make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) | 217 | make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) |
@@ -221,25 +234,40 @@ impl ToChalk for GenericPredicate { | |||
221 | } | 234 | } |
222 | 235 | ||
223 | fn from_chalk( | 236 | fn from_chalk( |
224 | _db: &impl HirDatabase, | 237 | db: &impl HirDatabase, |
225 | _where_clause: chalk_ir::QuantifiedWhereClause, | 238 | where_clause: chalk_ir::QuantifiedWhereClause<ChalkIr>, |
226 | ) -> GenericPredicate { | 239 | ) -> GenericPredicate { |
227 | // This should never need to be called | 240 | match where_clause.value { |
228 | unimplemented!() | 241 | chalk_ir::WhereClause::Implemented(tr) => { |
242 | if tr.trait_id == UNKNOWN_TRAIT { | ||
243 | // FIXME we need an Error enum on the Chalk side to avoid this | ||
244 | return GenericPredicate::Error; | ||
245 | } | ||
246 | GenericPredicate::Implemented(from_chalk(db, tr)) | ||
247 | } | ||
248 | chalk_ir::WhereClause::ProjectionEq(projection_eq) => { | ||
249 | let projection_ty = from_chalk(db, projection_eq.projection); | ||
250 | let ty = from_chalk(db, projection_eq.ty); | ||
251 | GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty }) | ||
252 | } | ||
253 | } | ||
229 | } | 254 | } |
230 | } | 255 | } |
231 | 256 | ||
232 | impl ToChalk for ProjectionTy { | 257 | impl ToChalk for ProjectionTy { |
233 | type Chalk = chalk_ir::ProjectionTy; | 258 | type Chalk = chalk_ir::ProjectionTy<ChalkIr>; |
234 | 259 | ||
235 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { | 260 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<ChalkIr> { |
236 | chalk_ir::ProjectionTy { | 261 | chalk_ir::ProjectionTy { |
237 | associated_ty_id: self.associated_ty.to_chalk(db), | 262 | associated_ty_id: self.associated_ty.to_chalk(db), |
238 | parameters: self.parameters.to_chalk(db), | 263 | parameters: self.parameters.to_chalk(db), |
239 | } | 264 | } |
240 | } | 265 | } |
241 | 266 | ||
242 | fn from_chalk(db: &impl HirDatabase, projection_ty: chalk_ir::ProjectionTy) -> ProjectionTy { | 267 | fn from_chalk( |
268 | db: &impl HirDatabase, | ||
269 | projection_ty: chalk_ir::ProjectionTy<ChalkIr>, | ||
270 | ) -> ProjectionTy { | ||
243 | ProjectionTy { | 271 | ProjectionTy { |
244 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), | 272 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), |
245 | parameters: from_chalk(db, projection_ty.parameters), | 273 | parameters: from_chalk(db, projection_ty.parameters), |
@@ -248,31 +276,31 @@ impl ToChalk for ProjectionTy { | |||
248 | } | 276 | } |
249 | 277 | ||
250 | impl ToChalk for super::ProjectionPredicate { | 278 | impl ToChalk for super::ProjectionPredicate { |
251 | type Chalk = chalk_ir::Normalize; | 279 | type Chalk = chalk_ir::Normalize<ChalkIr>; |
252 | 280 | ||
253 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize { | 281 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<ChalkIr> { |
254 | chalk_ir::Normalize { | 282 | chalk_ir::Normalize { |
255 | projection: self.projection_ty.to_chalk(db), | 283 | projection: self.projection_ty.to_chalk(db), |
256 | ty: self.ty.to_chalk(db), | 284 | ty: self.ty.to_chalk(db), |
257 | } | 285 | } |
258 | } | 286 | } |
259 | 287 | ||
260 | fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self { | 288 | fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<ChalkIr>) -> Self { |
261 | unimplemented!() | 289 | unimplemented!() |
262 | } | 290 | } |
263 | } | 291 | } |
264 | 292 | ||
265 | impl ToChalk for Obligation { | 293 | impl ToChalk for Obligation { |
266 | type Chalk = chalk_ir::DomainGoal; | 294 | type Chalk = chalk_ir::DomainGoal<ChalkIr>; |
267 | 295 | ||
268 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal { | 296 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<ChalkIr> { |
269 | match self { | 297 | match self { |
270 | Obligation::Trait(tr) => tr.to_chalk(db).cast(), | 298 | Obligation::Trait(tr) => tr.to_chalk(db).cast(), |
271 | Obligation::Projection(pr) => pr.to_chalk(db).cast(), | 299 | Obligation::Projection(pr) => pr.to_chalk(db).cast(), |
272 | } | 300 | } |
273 | } | 301 | } |
274 | 302 | ||
275 | fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal) -> Self { | 303 | fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<ChalkIr>) -> Self { |
276 | unimplemented!() | 304 | unimplemented!() |
277 | } | 305 | } |
278 | } | 306 | } |
@@ -296,16 +324,16 @@ where | |||
296 | } | 324 | } |
297 | 325 | ||
298 | impl ToChalk for Arc<super::TraitEnvironment> { | 326 | impl ToChalk for Arc<super::TraitEnvironment> { |
299 | type Chalk = Arc<chalk_ir::Environment>; | 327 | type Chalk = chalk_ir::Environment<ChalkIr>; |
300 | 328 | ||
301 | fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment> { | 329 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<ChalkIr> { |
302 | let mut clauses = Vec::new(); | 330 | let mut clauses = Vec::new(); |
303 | for pred in &self.predicates { | 331 | for pred in &self.predicates { |
304 | if pred.is_error() { | 332 | if pred.is_error() { |
305 | // for env, we just ignore errors | 333 | // for env, we just ignore errors |
306 | continue; | 334 | continue; |
307 | } | 335 | } |
308 | let program_clause: chalk_ir::ProgramClause = pred.clone().to_chalk(db).cast(); | 336 | let program_clause: chalk_ir::ProgramClause<ChalkIr> = pred.clone().to_chalk(db).cast(); |
309 | clauses.push(program_clause.into_from_env_clause()); | 337 | clauses.push(program_clause.into_from_env_clause()); |
310 | } | 338 | } |
311 | chalk_ir::Environment::new().add_clauses(clauses) | 339 | chalk_ir::Environment::new().add_clauses(clauses) |
@@ -313,13 +341,16 @@ impl ToChalk for Arc<super::TraitEnvironment> { | |||
313 | 341 | ||
314 | fn from_chalk( | 342 | fn from_chalk( |
315 | _db: &impl HirDatabase, | 343 | _db: &impl HirDatabase, |
316 | _env: Arc<chalk_ir::Environment>, | 344 | _env: chalk_ir::Environment<ChalkIr>, |
317 | ) -> Arc<super::TraitEnvironment> { | 345 | ) -> Arc<super::TraitEnvironment> { |
318 | unimplemented!() | 346 | unimplemented!() |
319 | } | 347 | } |
320 | } | 348 | } |
321 | 349 | ||
322 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> { | 350 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> |
351 | where | ||
352 | T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = ChalkIr>, | ||
353 | { | ||
323 | type Chalk = chalk_ir::InEnvironment<T::Chalk>; | 354 | type Chalk = chalk_ir::InEnvironment<T::Chalk>; |
324 | 355 | ||
325 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { | 356 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { |
@@ -351,7 +382,7 @@ fn convert_where_clauses( | |||
351 | db: &impl HirDatabase, | 382 | db: &impl HirDatabase, |
352 | def: GenericDef, | 383 | def: GenericDef, |
353 | substs: &Substs, | 384 | substs: &Substs, |
354 | ) -> Vec<chalk_ir::QuantifiedWhereClause> { | 385 | ) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { |
355 | let generic_predicates = db.generic_predicates(def); | 386 | let generic_predicates = db.generic_predicates(def); |
356 | let mut result = Vec::with_capacity(generic_predicates.len()); | 387 | let mut result = Vec::with_capacity(generic_predicates.len()); |
357 | for pred in generic_predicates.iter() { | 388 | for pred in generic_predicates.iter() { |
@@ -384,7 +415,7 @@ where | |||
384 | fn impls_for_trait( | 415 | fn impls_for_trait( |
385 | &self, | 416 | &self, |
386 | trait_id: chalk_ir::TraitId, | 417 | trait_id: chalk_ir::TraitId, |
387 | parameters: &[Parameter], | 418 | parameters: &[Parameter<ChalkIr>], |
388 | ) -> Vec<ImplId> { | 419 | ) -> Vec<ImplId> { |
389 | debug!("impls_for_trait {:?}", trait_id); | 420 | debug!("impls_for_trait {:?}", trait_id); |
390 | if trait_id == UNKNOWN_TRAIT { | 421 | if trait_id == UNKNOWN_TRAIT { |
@@ -430,13 +461,13 @@ where | |||
430 | } | 461 | } |
431 | fn split_projection<'p>( | 462 | fn split_projection<'p>( |
432 | &self, | 463 | &self, |
433 | projection: &'p chalk_ir::ProjectionTy, | 464 | projection: &'p chalk_ir::ProjectionTy<ChalkIr>, |
434 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { | 465 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter<ChalkIr>], &'p [Parameter<ChalkIr>]) { |
435 | debug!("split_projection {:?}", projection); | 466 | debug!("split_projection {:?}", projection); |
436 | // we don't support GATs, so I think this should always be correct currently | 467 | // we don't support GATs, so I think this should always be correct currently |
437 | (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[]) | 468 | (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[]) |
438 | } | 469 | } |
439 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause> { | 470 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> { |
440 | vec![] | 471 | vec![] |
441 | } | 472 | } |
442 | fn local_impls_to_coherence_check( | 473 | fn local_impls_to_coherence_check( |
@@ -508,7 +539,7 @@ pub(crate) fn trait_datum_query( | |||
508 | let trait_ref = trait_.trait_ref(db).subst(&bound_vars).to_chalk(db); | 539 | let trait_ref = trait_.trait_ref(db).subst(&bound_vars).to_chalk(db); |
509 | let flags = chalk_rust_ir::TraitFlags { | 540 | let flags = chalk_rust_ir::TraitFlags { |
510 | auto: trait_.is_auto(db), | 541 | auto: trait_.is_auto(db), |
511 | upstream: trait_.module(db).krate(db) != Some(krate), | 542 | upstream: trait_.module(db).krate() != krate, |
512 | non_enumerable: true, | 543 | non_enumerable: true, |
513 | // FIXME set these flags correctly | 544 | // FIXME set these flags correctly |
514 | marker: false, | 545 | marker: false, |
@@ -596,7 +627,7 @@ fn impl_block_datum( | |||
596 | .target_trait_ref(db) | 627 | .target_trait_ref(db) |
597 | .expect("FIXME handle unresolved impl block trait ref") | 628 | .expect("FIXME handle unresolved impl block trait ref") |
598 | .subst(&bound_vars); | 629 | .subst(&bound_vars); |
599 | let impl_type = if impl_block.module().krate(db) == Some(krate) { | 630 | let impl_type = if impl_block.module().krate() == krate { |
600 | chalk_rust_ir::ImplType::Local | 631 | chalk_rust_ir::ImplType::Local |
601 | } else { | 632 | } else { |
602 | chalk_rust_ir::ImplType::External | 633 | chalk_rust_ir::ImplType::External |
@@ -705,7 +736,7 @@ fn closure_fn_trait_impl_datum( | |||
705 | substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), | 736 | substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), |
706 | }; | 737 | }; |
707 | 738 | ||
708 | let output_ty_id = fn_once_trait.associated_type_by_name(db, &crate::name::OUTPUT_TYPE)?; | 739 | let output_ty_id = fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?; |
709 | 740 | ||
710 | let output_ty_value = chalk_rust_ir::AssociatedTyValue { | 741 | let output_ty_value = chalk_rust_ir::AssociatedTyValue { |
711 | associated_ty_id: output_ty_id.to_chalk(db), | 742 | associated_ty_id: output_ty_id.to_chalk(db), |
@@ -746,30 +777,6 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId { | |||
746 | chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } | 777 | chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } |
747 | } | 778 | } |
748 | 779 | ||
749 | impl From<chalk_ir::TraitId> for crate::ids::TraitId { | ||
750 | fn from(trait_id: chalk_ir::TraitId) -> Self { | ||
751 | id_from_chalk(trait_id.0) | ||
752 | } | ||
753 | } | ||
754 | |||
755 | impl From<crate::ids::TraitId> for chalk_ir::TraitId { | ||
756 | fn from(trait_id: crate::ids::TraitId) -> Self { | ||
757 | chalk_ir::TraitId(id_to_chalk(trait_id)) | ||
758 | } | ||
759 | } | ||
760 | |||
761 | impl From<chalk_ir::TypeId> for crate::ids::TypeAliasId { | ||
762 | fn from(type_id: chalk_ir::TypeId) -> Self { | ||
763 | id_from_chalk(type_id.0) | ||
764 | } | ||
765 | } | ||
766 | |||
767 | impl From<crate::ids::TypeAliasId> for chalk_ir::TypeId { | ||
768 | fn from(type_id: crate::ids::TypeAliasId) -> Self { | ||
769 | chalk_ir::TypeId(id_to_chalk(type_id)) | ||
770 | } | ||
771 | } | ||
772 | |||
773 | impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { | 780 | impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { |
774 | fn from(struct_id: chalk_ir::StructId) -> Self { | 781 | fn from(struct_id: chalk_ir::StructId) -> Self { |
775 | id_from_chalk(struct_id.0) | 782 | id_from_chalk(struct_id.0) |
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs index 674a46102..078e6295e 100644 --- a/crates/ra_hir/src/type_alias.rs +++ b/crates/ra_hir/src/type_alias.rs | |||
@@ -2,12 +2,13 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::type_ref::TypeRef; | ||
6 | use hir_expand::name::{AsName, Name}; | ||
7 | |||
5 | use ra_syntax::ast::NameOwner; | 8 | use ra_syntax::ast::NameOwner; |
6 | 9 | ||
7 | use crate::{ | 10 | use crate::{ |
8 | db::{AstDatabase, DefDatabase}, | 11 | db::{AstDatabase, DefDatabase}, |
9 | name::{AsName, Name}, | ||
10 | type_ref::TypeRef, | ||
11 | HasSource, TypeAlias, | 12 | HasSource, TypeAlias, |
12 | }; | 13 | }; |
13 | 14 | ||
diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs deleted file mode 100644 index 2cf06b250..000000000 --- a/crates/ra_hir/src/type_ref.rs +++ /dev/null | |||
@@ -1,162 +0,0 @@ | |||
1 | //! HIR for references to types. Paths in these are not yet resolved. They can | ||
2 | //! be directly created from an ast::TypeRef, without further queries. | ||
3 | |||
4 | use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner}; | ||
5 | |||
6 | use crate::Path; | ||
7 | |||
8 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | ||
9 | pub enum Mutability { | ||
10 | Shared, | ||
11 | Mut, | ||
12 | } | ||
13 | |||
14 | impl Mutability { | ||
15 | pub fn from_mutable(mutable: bool) -> Mutability { | ||
16 | if mutable { | ||
17 | Mutability::Mut | ||
18 | } else { | ||
19 | Mutability::Shared | ||
20 | } | ||
21 | } | ||
22 | |||
23 | pub fn as_keyword_for_ref(self) -> &'static str { | ||
24 | match self { | ||
25 | Mutability::Shared => "", | ||
26 | Mutability::Mut => "mut ", | ||
27 | } | ||
28 | } | ||
29 | |||
30 | pub fn as_keyword_for_ptr(self) -> &'static str { | ||
31 | match self { | ||
32 | Mutability::Shared => "const ", | ||
33 | Mutability::Mut => "mut ", | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | |||
38 | /// Compare ty::Ty | ||
39 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | ||
40 | pub enum TypeRef { | ||
41 | Never, | ||
42 | Placeholder, | ||
43 | Tuple(Vec<TypeRef>), | ||
44 | Path(Path), | ||
45 | RawPtr(Box<TypeRef>, Mutability), | ||
46 | Reference(Box<TypeRef>, Mutability), | ||
47 | Array(Box<TypeRef> /*, Expr*/), | ||
48 | Slice(Box<TypeRef>), | ||
49 | /// A fn pointer. Last element of the vector is the return type. | ||
50 | Fn(Vec<TypeRef>), | ||
51 | // For | ||
52 | ImplTrait(Vec<TypeBound>), | ||
53 | DynTrait(Vec<TypeBound>), | ||
54 | Error, | ||
55 | } | ||
56 | |||
57 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | ||
58 | pub enum TypeBound { | ||
59 | Path(Path), | ||
60 | // also for<> bounds | ||
61 | // also Lifetimes | ||
62 | Error, | ||
63 | } | ||
64 | |||
65 | impl TypeRef { | ||
66 | /// Converts an `ast::TypeRef` to a `hir::TypeRef`. | ||
67 | pub(crate) fn from_ast(node: ast::TypeRef) -> Self { | ||
68 | match node { | ||
69 | ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), | ||
70 | ast::TypeRef::TupleType(inner) => { | ||
71 | TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()) | ||
72 | } | ||
73 | ast::TypeRef::NeverType(..) => TypeRef::Never, | ||
74 | ast::TypeRef::PathType(inner) => { | ||
75 | // FIXME: Use `Path::from_src` | ||
76 | inner.path().and_then(Path::from_ast).map(TypeRef::Path).unwrap_or(TypeRef::Error) | ||
77 | } | ||
78 | ast::TypeRef::PointerType(inner) => { | ||
79 | let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); | ||
80 | let mutability = Mutability::from_mutable(inner.is_mut()); | ||
81 | TypeRef::RawPtr(Box::new(inner_ty), mutability) | ||
82 | } | ||
83 | ast::TypeRef::ArrayType(inner) => { | ||
84 | TypeRef::Array(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) | ||
85 | } | ||
86 | ast::TypeRef::SliceType(inner) => { | ||
87 | TypeRef::Slice(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) | ||
88 | } | ||
89 | ast::TypeRef::ReferenceType(inner) => { | ||
90 | let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); | ||
91 | let mutability = Mutability::from_mutable(inner.is_mut()); | ||
92 | TypeRef::Reference(Box::new(inner_ty), mutability) | ||
93 | } | ||
94 | ast::TypeRef::PlaceholderType(_inner) => TypeRef::Placeholder, | ||
95 | ast::TypeRef::FnPointerType(inner) => { | ||
96 | let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref())); | ||
97 | let mut params = if let Some(pl) = inner.param_list() { | ||
98 | pl.params().map(|p| p.ascribed_type()).map(TypeRef::from_ast_opt).collect() | ||
99 | } else { | ||
100 | Vec::new() | ||
101 | }; | ||
102 | params.push(ret_ty); | ||
103 | TypeRef::Fn(params) | ||
104 | } | ||
105 | // for types are close enough for our purposes to the inner type for now... | ||
106 | ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(inner.type_ref()), | ||
107 | ast::TypeRef::ImplTraitType(inner) => { | ||
108 | TypeRef::ImplTrait(type_bounds_from_ast(inner.type_bound_list())) | ||
109 | } | ||
110 | ast::TypeRef::DynTraitType(inner) => { | ||
111 | TypeRef::DynTrait(type_bounds_from_ast(inner.type_bound_list())) | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | pub(crate) fn from_ast_opt(node: Option<ast::TypeRef>) -> Self { | ||
117 | if let Some(node) = node { | ||
118 | TypeRef::from_ast(node) | ||
119 | } else { | ||
120 | TypeRef::Error | ||
121 | } | ||
122 | } | ||
123 | |||
124 | pub fn unit() -> TypeRef { | ||
125 | TypeRef::Tuple(Vec::new()) | ||
126 | } | ||
127 | } | ||
128 | |||
129 | pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option<ast::TypeBoundList>) -> Vec<TypeBound> { | ||
130 | if let Some(type_bounds) = type_bounds_opt { | ||
131 | type_bounds.bounds().map(TypeBound::from_ast).collect() | ||
132 | } else { | ||
133 | vec![] | ||
134 | } | ||
135 | } | ||
136 | |||
137 | impl TypeBound { | ||
138 | pub(crate) fn from_ast(node: ast::TypeBound) -> Self { | ||
139 | match node.kind() { | ||
140 | ast::TypeBoundKind::PathType(path_type) => { | ||
141 | let path = match path_type.path() { | ||
142 | Some(p) => p, | ||
143 | None => return TypeBound::Error, | ||
144 | }; | ||
145 | // FIXME: Use `Path::from_src` | ||
146 | let path = match Path::from_ast(path) { | ||
147 | Some(p) => p, | ||
148 | None => return TypeBound::Error, | ||
149 | }; | ||
150 | TypeBound::Path(path) | ||
151 | } | ||
152 | ast::TypeBoundKind::ForType(_) | ast::TypeBoundKind::Lifetime(_) => TypeBound::Error, | ||
153 | } | ||
154 | } | ||
155 | |||
156 | pub fn as_path(&self) -> Option<&Path> { | ||
157 | match self { | ||
158 | TypeBound::Path(p) => Some(p), | ||
159 | _ => None, | ||
160 | } | ||
161 | } | ||
162 | } | ||