diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir/src/code_model.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 409 |
1 files changed, 109 insertions, 300 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 38d66c2a7..bcfc0d03e 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -1,36 +1,35 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | |||
3 | pub(crate) mod src; | ||
4 | |||
5 | use std::sync::Arc; | 2 | use std::sync::Arc; |
6 | 3 | ||
4 | use either::Either; | ||
7 | use hir_def::{ | 5 | use hir_def::{ |
8 | adt::VariantData, | 6 | adt::VariantData, |
9 | body::{Body, BodySourceMap}, | ||
10 | builtin_type::BuiltinType, | 7 | builtin_type::BuiltinType, |
11 | docs::Documentation, | 8 | docs::Documentation, |
12 | expr::{BindingAnnotation, Pat, PatId}, | 9 | expr::{BindingAnnotation, Pat, PatId}, |
10 | nameres::ModuleSource, | ||
13 | per_ns::PerNs, | 11 | per_ns::PerNs, |
14 | resolver::HasResolver, | 12 | resolver::HasResolver, |
15 | type_ref::{Mutability, TypeRef}, | 13 | type_ref::{Mutability, TypeRef}, |
16 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, | 14 | AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, |
17 | HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, | 15 | LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, |
18 | Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, | 16 | TypeParamId, UnionId, |
19 | }; | 17 | }; |
20 | use hir_expand::{ | 18 | use hir_expand::{ |
21 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
22 | name::{self, AsName}, | 20 | name::{name, AsName}, |
23 | AstId, MacroDefId, | 21 | MacroDefId, |
22 | }; | ||
23 | use hir_ty::{ | ||
24 | autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment, | ||
25 | TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, | ||
24 | }; | 26 | }; |
25 | use hir_ty::expr::ExprValidator; | 27 | use ra_db::{CrateId, Edition, FileId}; |
26 | use ra_db::{CrateId, Edition, FileId, FilePosition}; | 28 | use ra_syntax::ast; |
27 | use ra_syntax::{ast, AstNode, SyntaxNode}; | ||
28 | 29 | ||
29 | use crate::{ | 30 | use crate::{ |
30 | db::{DefDatabase, HirDatabase}, | 31 | db::{DefDatabase, HirDatabase}, |
31 | ty::display::HirFormatter, | 32 | CallableDef, HirDisplay, InFile, Name, |
32 | ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk}, | ||
33 | CallableDef, Either, HirDisplay, Name, Source, | ||
34 | }; | 33 | }; |
35 | 34 | ||
36 | /// 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 |
@@ -38,7 +37,7 @@ use crate::{ | |||
38 | /// root module. | 37 | /// root module. |
39 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 38 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
40 | pub struct Crate { | 39 | pub struct Crate { |
41 | pub(crate) crate_id: CrateId, | 40 | pub(crate) id: CrateId, |
42 | } | 41 | } |
43 | 42 | ||
44 | #[derive(Debug)] | 43 | #[derive(Debug)] |
@@ -48,91 +47,43 @@ pub struct CrateDependency { | |||
48 | } | 47 | } |
49 | 48 | ||
50 | impl Crate { | 49 | impl Crate { |
51 | pub fn crate_id(self) -> CrateId { | ||
52 | self.crate_id | ||
53 | } | ||
54 | |||
55 | pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> { | 50 | pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> { |
56 | db.crate_graph() | 51 | db.crate_graph() |
57 | .dependencies(self.crate_id) | 52 | .dependencies(self.id) |
58 | .map(|dep| { | 53 | .map(|dep| { |
59 | let krate = Crate { crate_id: dep.crate_id() }; | 54 | let krate = Crate { id: dep.crate_id() }; |
60 | let name = dep.as_name(); | 55 | let name = dep.as_name(); |
61 | CrateDependency { krate, name } | 56 | CrateDependency { krate, name } |
62 | }) | 57 | }) |
63 | .collect() | 58 | .collect() |
64 | } | 59 | } |
65 | 60 | ||
66 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { | 61 | // FIXME: add `transitive_reverse_dependencies`. |
67 | let module_id = db.crate_def_map(self.crate_id).root; | 62 | pub fn reverse_dependencies(self, db: &impl DefDatabase) -> Vec<Crate> { |
68 | Some(Module::new(self, module_id)) | ||
69 | } | ||
70 | |||
71 | pub fn edition(self, db: &impl DefDatabase) -> Edition { | ||
72 | let crate_graph = db.crate_graph(); | 63 | let crate_graph = db.crate_graph(); |
73 | crate_graph.edition(self.crate_id) | 64 | crate_graph |
74 | } | 65 | .iter() |
75 | 66 | .filter(|&krate| crate_graph.dependencies(krate).any(|it| it.crate_id == self.id)) | |
76 | pub fn all(db: &impl DefDatabase) -> Vec<Crate> { | 67 | .map(|id| Crate { id }) |
77 | db.crate_graph().iter().map(|crate_id| Crate { crate_id }).collect() | 68 | .collect() |
78 | } | 69 | } |
79 | } | ||
80 | |||
81 | pub enum ModuleSource { | ||
82 | SourceFile(ast::SourceFile), | ||
83 | Module(ast::Module), | ||
84 | } | ||
85 | 70 | ||
86 | impl ModuleSource { | 71 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { |
87 | pub fn new( | 72 | let module_id = db.crate_def_map(self.id).root; |
88 | db: &impl DefDatabase, | 73 | Some(Module::new(self, module_id)) |
89 | file_id: Option<FileId>, | ||
90 | decl_id: Option<AstId<ast::Module>>, | ||
91 | ) -> ModuleSource { | ||
92 | match (file_id, decl_id) { | ||
93 | (Some(file_id), _) => { | ||
94 | let source_file = db.parse(file_id).tree(); | ||
95 | ModuleSource::SourceFile(source_file) | ||
96 | } | ||
97 | (None, Some(item_id)) => { | ||
98 | let module = item_id.to_node(db); | ||
99 | assert!(module.item_list().is_some(), "expected inline module"); | ||
100 | ModuleSource::Module(module) | ||
101 | } | ||
102 | (None, None) => panic!(), | ||
103 | } | ||
104 | } | 74 | } |
105 | 75 | ||
106 | // FIXME: this methods do not belong here | 76 | pub fn root_file(self, db: &impl DefDatabase) -> FileId { |
107 | pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource { | 77 | db.crate_graph().crate_root(self.id) |
108 | let parse = db.parse(position.file_id); | ||
109 | match &ra_syntax::algo::find_node_at_offset::<ast::Module>( | ||
110 | parse.tree().syntax(), | ||
111 | position.offset, | ||
112 | ) { | ||
113 | Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()), | ||
114 | _ => { | ||
115 | let source_file = parse.tree(); | ||
116 | ModuleSource::SourceFile(source_file) | ||
117 | } | ||
118 | } | ||
119 | } | 78 | } |
120 | 79 | ||
121 | pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource { | 80 | pub fn edition(self, db: &impl DefDatabase) -> Edition { |
122 | if let Some(m) = | 81 | let crate_graph = db.crate_graph(); |
123 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | 82 | crate_graph.edition(self.id) |
124 | { | ||
125 | ModuleSource::Module(m) | ||
126 | } else { | ||
127 | let file_id = child.file_id.original_file(db); | ||
128 | let source_file = db.parse(file_id).tree(); | ||
129 | ModuleSource::SourceFile(source_file) | ||
130 | } | ||
131 | } | 83 | } |
132 | 84 | ||
133 | pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource { | 85 | pub fn all(db: &impl DefDatabase) -> Vec<Crate> { |
134 | let source_file = db.parse(file_id).tree(); | 86 | db.crate_graph().iter().map(|id| Crate { id }).collect() |
135 | ModuleSource::SourceFile(source_file) | ||
136 | } | 87 | } |
137 | } | 88 | } |
138 | 89 | ||
@@ -171,7 +122,7 @@ pub use hir_def::attr::Attrs; | |||
171 | 122 | ||
172 | impl Module { | 123 | impl Module { |
173 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 124 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
174 | Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } } | 125 | Module { id: ModuleId { krate: krate.id, local_id: crate_module_id } } |
175 | } | 126 | } |
176 | 127 | ||
177 | /// Name of this module. | 128 | /// Name of this module. |
@@ -189,7 +140,7 @@ impl Module { | |||
189 | 140 | ||
190 | /// Returns the crate this module is part of. | 141 | /// Returns the crate this module is part of. |
191 | pub fn krate(self) -> Crate { | 142 | pub fn krate(self) -> Crate { |
192 | Crate { crate_id: self.id.krate } | 143 | Crate { id: self.id.krate } |
193 | } | 144 | } |
194 | 145 | ||
195 | /// Topmost parent of this module. Every module has a `crate_root`, but some | 146 | /// Topmost parent of this module. Every module has a `crate_root`, but some |
@@ -200,13 +151,6 @@ impl Module { | |||
200 | self.with_module_id(def_map.root) | 151 | self.with_module_id(def_map.root) |
201 | } | 152 | } |
202 | 153 | ||
203 | /// Finds a child module with the specified name. | ||
204 | pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> { | ||
205 | let def_map = db.crate_def_map(self.id.krate); | ||
206 | let child_id = def_map[self.id.local_id].children.get(name)?; | ||
207 | Some(self.with_module_id(*child_id)) | ||
208 | } | ||
209 | |||
210 | /// Iterates over all child modules. | 154 | /// Iterates over all child modules. |
211 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { | 155 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { |
212 | let def_map = db.crate_def_map(self.id.krate); | 156 | let def_map = db.crate_def_map(self.id.krate); |
@@ -236,13 +180,11 @@ impl Module { | |||
236 | } | 180 | } |
237 | 181 | ||
238 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 182 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
239 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { | 183 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> { |
240 | db.crate_def_map(self.id.krate)[self.id.local_id] | 184 | db.crate_def_map(self.id.krate)[self.id.local_id] |
241 | .scope | 185 | .scope |
242 | .entries() | 186 | .entries() |
243 | .map(|(name, res)| { | 187 | .map(|(name, def)| (name.clone(), def.into())) |
244 | (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id })) | ||
245 | }) | ||
246 | .collect() | 188 | .collect() |
247 | } | 189 | } |
248 | 190 | ||
@@ -277,19 +219,14 @@ impl Module { | |||
277 | 219 | ||
278 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { | 220 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { |
279 | let def_map = db.crate_def_map(self.id.krate); | 221 | let def_map = db.crate_def_map(self.id.krate); |
280 | def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() | 222 | def_map[self.id.local_id].scope.impls().map(ImplBlock::from).collect() |
281 | } | 223 | } |
282 | 224 | ||
283 | fn with_module_id(self, module_id: LocalModuleId) -> Module { | 225 | pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { |
284 | Module::new(self.krate(), module_id) | 226 | Module::new(self.krate(), module_id) |
285 | } | 227 | } |
286 | } | 228 | } |
287 | 229 | ||
288 | pub struct Import { | ||
289 | pub(crate) parent: Module, | ||
290 | pub(crate) id: LocalImportId, | ||
291 | } | ||
292 | |||
293 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 230 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
294 | pub struct StructField { | 231 | pub struct StructField { |
295 | pub(crate) parent: VariantDef, | 232 | pub(crate) parent: VariantDef, |
@@ -307,8 +244,10 @@ impl StructField { | |||
307 | self.parent.variant_data(db).fields()[self.id].name.clone() | 244 | self.parent.variant_data(db).fields()[self.id].name.clone() |
308 | } | 245 | } |
309 | 246 | ||
310 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { | 247 | pub fn ty(&self, db: &impl HirDatabase) -> Type { |
311 | db.field_types(self.parent.into())[self.id].clone() | 248 | let var_id = self.parent.into(); |
249 | let ty = db.field_types(var_id)[self.id].clone(); | ||
250 | Type::new(db, self.parent.module(db).id.krate.into(), var_id, ty) | ||
312 | } | 251 | } |
313 | 252 | ||
314 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { | 253 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { |
@@ -323,7 +262,7 @@ pub struct Struct { | |||
323 | 262 | ||
324 | impl Struct { | 263 | impl Struct { |
325 | pub fn module(self, db: &impl DefDatabase) -> Module { | 264 | pub fn module(self, db: &impl DefDatabase) -> Module { |
326 | Module { id: self.id.module(db) } | 265 | Module { id: self.id.lookup(db).container.module(db) } |
327 | } | 266 | } |
328 | 267 | ||
329 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 268 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -343,21 +282,8 @@ impl Struct { | |||
343 | .collect() | 282 | .collect() |
344 | } | 283 | } |
345 | 284 | ||
346 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
347 | db.struct_data(self.id.into()) | ||
348 | .variant_data | ||
349 | .fields() | ||
350 | .iter() | ||
351 | .find(|(_id, data)| data.name == *name) | ||
352 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
353 | } | ||
354 | |||
355 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 285 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
356 | Type::from_def(db, self.id.module(db).krate, self.id) | 286 | Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id) |
357 | } | ||
358 | |||
359 | pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { | ||
360 | db.value_ty(self.id.into()) | ||
361 | } | 287 | } |
362 | 288 | ||
363 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 289 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
@@ -376,11 +302,11 @@ impl Union { | |||
376 | } | 302 | } |
377 | 303 | ||
378 | pub fn module(self, db: &impl DefDatabase) -> Module { | 304 | pub fn module(self, db: &impl DefDatabase) -> Module { |
379 | Module { id: self.id.module(db) } | 305 | Module { id: self.id.lookup(db).container.module(db) } |
380 | } | 306 | } |
381 | 307 | ||
382 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 308 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
383 | Type::from_def(db, self.id.module(db).krate, self.id) | 309 | Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id) |
384 | } | 310 | } |
385 | 311 | ||
386 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 312 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
@@ -392,15 +318,6 @@ impl Union { | |||
392 | .collect() | 318 | .collect() |
393 | } | 319 | } |
394 | 320 | ||
395 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
396 | db.union_data(self.id) | ||
397 | .variant_data | ||
398 | .fields() | ||
399 | .iter() | ||
400 | .find(|(_id, data)| data.name == *name) | ||
401 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
402 | } | ||
403 | |||
404 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 321 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
405 | db.union_data(self.id).variant_data.clone() | 322 | db.union_data(self.id).variant_data.clone() |
406 | } | 323 | } |
@@ -413,7 +330,7 @@ pub struct Enum { | |||
413 | 330 | ||
414 | impl Enum { | 331 | impl Enum { |
415 | pub fn module(self, db: &impl DefDatabase) -> Module { | 332 | pub fn module(self, db: &impl DefDatabase) -> Module { |
416 | Module { id: self.id.module(db) } | 333 | Module { id: self.id.lookup(db).container.module(db) } |
417 | } | 334 | } |
418 | 335 | ||
419 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 336 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -432,13 +349,8 @@ impl Enum { | |||
432 | .collect() | 349 | .collect() |
433 | } | 350 | } |
434 | 351 | ||
435 | pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { | ||
436 | let id = db.enum_data(self.id).variant(name)?; | ||
437 | Some(EnumVariant { parent: self, id }) | ||
438 | } | ||
439 | |||
440 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 352 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
441 | Type::from_def(db, self.id.module(db).krate, self.id) | 353 | Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id) |
442 | } | 354 | } |
443 | } | 355 | } |
444 | 356 | ||
@@ -468,14 +380,6 @@ impl EnumVariant { | |||
468 | .collect() | 380 | .collect() |
469 | } | 381 | } |
470 | 382 | ||
471 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
472 | self.variant_data(db) | ||
473 | .fields() | ||
474 | .iter() | ||
475 | .find(|(_id, data)| data.name == *name) | ||
476 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
477 | } | ||
478 | |||
479 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 383 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
480 | db.enum_data(self.parent.id).variants[self.id].variant_data.clone() | 384 | db.enum_data(self.parent.id).variants[self.id].variant_data.clone() |
481 | } | 385 | } |
@@ -593,48 +497,8 @@ impl Function { | |||
593 | db.function_data(self.id).params.clone() | 497 | db.function_data(self.id).params.clone() |
594 | } | 498 | } |
595 | 499 | ||
596 | pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
597 | db.body_with_source_map(self.id.into()).1 | ||
598 | } | ||
599 | |||
600 | pub fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
601 | db.body(self.id.into()) | ||
602 | } | ||
603 | |||
604 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | ||
605 | db.value_ty(self.id.into()) | ||
606 | } | ||
607 | |||
608 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
609 | db.infer(self.id.into()) | ||
610 | } | ||
611 | |||
612 | /// The containing impl block, if this is a method. | ||
613 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | ||
614 | match self.container(db) { | ||
615 | Some(Container::ImplBlock(it)) => Some(it), | ||
616 | _ => None, | ||
617 | } | ||
618 | } | ||
619 | |||
620 | /// The containing trait, if this is a trait method definition. | ||
621 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | ||
622 | match self.container(db) { | ||
623 | Some(Container::Trait(it)) => Some(it), | ||
624 | _ => None, | ||
625 | } | ||
626 | } | ||
627 | |||
628 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | ||
629 | match self.id.lookup(db).container { | ||
630 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), | ||
631 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), | ||
632 | ContainerId::ModuleId(_) => None, | ||
633 | } | ||
634 | } | ||
635 | |||
636 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 500 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
637 | let infer = self.infer(db); | 501 | let infer = db.infer(self.id.into()); |
638 | infer.add_diagnostics(db, self.id, sink); | 502 | infer.add_diagnostics(db, self.id, sink); |
639 | let mut validator = ExprValidator::new(self.id, infer, sink); | 503 | let mut validator = ExprValidator::new(self.id, infer, sink); |
640 | validator.validate_body(db); | 504 | validator.validate_body(db); |
@@ -658,34 +522,6 @@ impl Const { | |||
658 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | 522 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { |
659 | db.const_data(self.id).name.clone() | 523 | db.const_data(self.id).name.clone() |
660 | } | 524 | } |
661 | |||
662 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
663 | db.infer(self.id.into()) | ||
664 | } | ||
665 | |||
666 | /// The containing impl block, if this is a type alias. | ||
667 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | ||
668 | match self.container(db) { | ||
669 | Some(Container::ImplBlock(it)) => Some(it), | ||
670 | _ => None, | ||
671 | } | ||
672 | } | ||
673 | |||
674 | /// The containing trait, if this is a trait type alias definition. | ||
675 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | ||
676 | match self.container(db) { | ||
677 | Some(Container::Trait(it)) => Some(it), | ||
678 | _ => None, | ||
679 | } | ||
680 | } | ||
681 | |||
682 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | ||
683 | match self.id.lookup(db).container { | ||
684 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), | ||
685 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), | ||
686 | ContainerId::ModuleId(_) => None, | ||
687 | } | ||
688 | } | ||
689 | } | 525 | } |
690 | 526 | ||
691 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 527 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -701,10 +537,6 @@ impl Static { | |||
701 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 537 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
702 | Some(self.module(db).krate()) | 538 | Some(self.module(db).krate()) |
703 | } | 539 | } |
704 | |||
705 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
706 | db.infer(self.id.into()) | ||
707 | } | ||
708 | } | 540 | } |
709 | 541 | ||
710 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 542 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -714,7 +546,7 @@ pub struct Trait { | |||
714 | 546 | ||
715 | impl Trait { | 547 | impl Trait { |
716 | pub fn module(self, db: &impl DefDatabase) -> Module { | 548 | pub fn module(self, db: &impl DefDatabase) -> Module { |
717 | Module { id: self.id.module(db) } | 549 | Module { id: self.id.lookup(db).container.module(db) } |
718 | } | 550 | } |
719 | 551 | ||
720 | pub fn name(self, db: &impl DefDatabase) -> Name { | 552 | pub fn name(self, db: &impl DefDatabase) -> Name { |
@@ -749,30 +581,6 @@ impl TypeAlias { | |||
749 | Some(self.module(db).krate()) | 581 | Some(self.module(db).krate()) |
750 | } | 582 | } |
751 | 583 | ||
752 | /// The containing impl block, if this is a type alias. | ||
753 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | ||
754 | match self.container(db) { | ||
755 | Some(Container::ImplBlock(it)) => Some(it), | ||
756 | _ => None, | ||
757 | } | ||
758 | } | ||
759 | |||
760 | /// The containing trait, if this is a trait type alias definition. | ||
761 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | ||
762 | match self.container(db) { | ||
763 | Some(Container::Trait(it)) => Some(it), | ||
764 | _ => None, | ||
765 | } | ||
766 | } | ||
767 | |||
768 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | ||
769 | match self.id.lookup(db).container { | ||
770 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), | ||
771 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), | ||
772 | ContainerId::ModuleId(_) => None, | ||
773 | } | ||
774 | } | ||
775 | |||
776 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { | 584 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { |
777 | db.type_alias_data(self.id).type_ref.clone() | 585 | db.type_alias_data(self.id).type_ref.clone() |
778 | } | 586 | } |
@@ -791,14 +599,6 @@ pub struct MacroDef { | |||
791 | pub(crate) id: MacroDefId, | 599 | pub(crate) id: MacroDefId, |
792 | } | 600 | } |
793 | 601 | ||
794 | impl MacroDef {} | ||
795 | |||
796 | pub enum Container { | ||
797 | Trait(Trait), | ||
798 | ImplBlock(ImplBlock), | ||
799 | } | ||
800 | impl_froms!(Container: Trait, ImplBlock); | ||
801 | |||
802 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 602 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
803 | pub enum AssocItem { | 603 | pub enum AssocItem { |
804 | Function(Function), | 604 | Function(Function), |
@@ -819,15 +619,6 @@ impl AssocItem { | |||
819 | AssocItem::TypeAlias(t) => t.module(db), | 619 | AssocItem::TypeAlias(t) => t.module(db), |
820 | } | 620 | } |
821 | } | 621 | } |
822 | |||
823 | pub fn container(self, db: &impl DefDatabase) -> Container { | ||
824 | match self { | ||
825 | AssocItem::Function(f) => f.container(db), | ||
826 | AssocItem::Const(c) => c.container(db), | ||
827 | AssocItem::TypeAlias(t) => t.container(db), | ||
828 | } | ||
829 | .expect("AssocItem without container") | ||
830 | } | ||
831 | } | 622 | } |
832 | 623 | ||
833 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 624 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
@@ -869,7 +660,7 @@ impl Local { | |||
869 | } | 660 | } |
870 | 661 | ||
871 | pub fn is_self(self, db: &impl HirDatabase) -> bool { | 662 | pub fn is_self(self, db: &impl HirDatabase) -> bool { |
872 | self.name(db) == Some(name::SELF_PARAM) | 663 | self.name(db) == Some(name![self]) |
873 | } | 664 | } |
874 | 665 | ||
875 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { | 666 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { |
@@ -901,18 +692,30 @@ impl Local { | |||
901 | Type { krate, ty: InEnvironment { value: ty, environment } } | 692 | Type { krate, ty: InEnvironment { value: ty, environment } } |
902 | } | 693 | } |
903 | 694 | ||
904 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | 695 | pub fn source(self, db: &impl HirDatabase) -> InFile<Either<ast::BindPat, ast::SelfParam>> { |
905 | let (_body, source_map) = db.body_with_source_map(self.parent.into()); | 696 | let (_body, source_map) = db.body_with_source_map(self.parent.into()); |
906 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... | 697 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... |
907 | let root = src.file_syntax(db); | 698 | let root = src.file_syntax(db); |
908 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) | 699 | src.map(|ast| { |
700 | ast.map_left(|it| it.cast().unwrap().to_node(&root)).map_right(|it| it.to_node(&root)) | ||
701 | }) | ||
909 | } | 702 | } |
910 | } | 703 | } |
911 | 704 | ||
912 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 705 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
913 | pub struct GenericParam { | 706 | pub struct TypeParam { |
914 | pub(crate) parent: GenericDefId, | 707 | pub(crate) id: TypeParamId, |
915 | pub(crate) idx: u32, | 708 | } |
709 | |||
710 | impl TypeParam { | ||
711 | pub fn name(self, db: &impl HirDatabase) -> Name { | ||
712 | let params = db.generic_params(self.id.parent); | ||
713 | params.types[self.id.local_id].name.clone() | ||
714 | } | ||
715 | |||
716 | pub fn module(self, db: &impl HirDatabase) -> Module { | ||
717 | self.id.parent.module(db).into() | ||
718 | } | ||
916 | } | 719 | } |
917 | 720 | ||
918 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 721 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -922,11 +725,11 @@ pub struct ImplBlock { | |||
922 | 725 | ||
923 | impl ImplBlock { | 726 | impl ImplBlock { |
924 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { | 727 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { |
925 | let impls = db.impls_in_crate(krate.crate_id); | 728 | let impls = db.impls_in_crate(krate.id); |
926 | impls.all_impls().map(Self::from).collect() | 729 | impls.all_impls().map(Self::from).collect() |
927 | } | 730 | } |
928 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { | 731 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { |
929 | let impls = db.impls_in_crate(krate.crate_id); | 732 | let impls = db.impls_in_crate(krate.id); |
930 | impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() | 733 | impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() |
931 | } | 734 | } |
932 | 735 | ||
@@ -943,7 +746,10 @@ impl ImplBlock { | |||
943 | let resolver = self.id.resolver(db); | 746 | let resolver = self.id.resolver(db); |
944 | let environment = TraitEnvironment::lower(db, &resolver); | 747 | let environment = TraitEnvironment::lower(db, &resolver); |
945 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); | 748 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); |
946 | Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } } | 749 | Type { |
750 | krate: self.id.lookup(db).container.module(db).krate, | ||
751 | ty: InEnvironment { value: ty, environment }, | ||
752 | } | ||
947 | } | 753 | } |
948 | 754 | ||
949 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | 755 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { |
@@ -955,11 +761,11 @@ impl ImplBlock { | |||
955 | } | 761 | } |
956 | 762 | ||
957 | pub fn module(&self, db: &impl DefDatabase) -> Module { | 763 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
958 | self.id.module(db).into() | 764 | self.id.lookup(db).container.module(db).into() |
959 | } | 765 | } |
960 | 766 | ||
961 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | 767 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { |
962 | Crate { crate_id: self.module(db).id.krate } | 768 | Crate { id: self.module(db).id.krate } |
963 | } | 769 | } |
964 | } | 770 | } |
965 | 771 | ||
@@ -970,15 +776,19 @@ pub struct Type { | |||
970 | } | 776 | } |
971 | 777 | ||
972 | impl Type { | 778 | impl Type { |
779 | fn new(db: &impl HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { | ||
780 | let resolver = lexical_env.resolver(db); | ||
781 | let environment = TraitEnvironment::lower(db, &resolver); | ||
782 | Type { krate, ty: InEnvironment { value: ty, environment } } | ||
783 | } | ||
784 | |||
973 | fn from_def( | 785 | fn from_def( |
974 | db: &impl HirDatabase, | 786 | db: &impl HirDatabase, |
975 | krate: CrateId, | 787 | krate: CrateId, |
976 | def: impl HasResolver + Into<TyDefId>, | 788 | def: impl HasResolver + Into<TyDefId>, |
977 | ) -> Type { | 789 | ) -> Type { |
978 | let resolver = def.resolver(db); | ||
979 | let environment = TraitEnvironment::lower(db, &resolver); | ||
980 | let ty = db.ty(def.into()); | 790 | let ty = db.ty(def.into()); |
981 | Type { krate, ty: InEnvironment { value: ty, environment } } | 791 | Type::new(db, krate, def, ty) |
982 | } | 792 | } |
983 | 793 | ||
984 | pub fn is_bool(&self) -> bool { | 794 | pub fn is_bool(&self) -> bool { |
@@ -1028,7 +838,7 @@ impl Type { | |||
1028 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { | 838 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { |
1029 | if let Ty::Apply(a_ty) = &self.ty.value { | 839 | if let Ty::Apply(a_ty) = &self.ty.value { |
1030 | match a_ty.ctor { | 840 | match a_ty.ctor { |
1031 | ty::TypeCtor::Adt(AdtId::StructId(s)) => { | 841 | TypeCtor::Adt(AdtId::StructId(s)) => { |
1032 | let var_def = s.into(); | 842 | let var_def = s.into(); |
1033 | return db | 843 | return db |
1034 | .field_types(var_def) | 844 | .field_types(var_def) |
@@ -1050,7 +860,7 @@ impl Type { | |||
1050 | let mut res = Vec::new(); | 860 | let mut res = Vec::new(); |
1051 | if let Ty::Apply(a_ty) = &self.ty.value { | 861 | if let Ty::Apply(a_ty) = &self.ty.value { |
1052 | match a_ty.ctor { | 862 | match a_ty.ctor { |
1053 | ty::TypeCtor::Tuple { .. } => { | 863 | TypeCtor::Tuple { .. } => { |
1054 | for ty in a_ty.parameters.iter() { | 864 | for ty in a_ty.parameters.iter() { |
1055 | let ty = ty.clone().subst(&a_ty.parameters); | 865 | let ty = ty.clone().subst(&a_ty.parameters); |
1056 | res.push(self.derived(ty)); | 866 | res.push(self.derived(ty)); |
@@ -1069,11 +879,16 @@ impl Type { | |||
1069 | ) -> Vec<(StructField, Type)> { | 879 | ) -> Vec<(StructField, Type)> { |
1070 | // FIXME: check that ty and def match | 880 | // FIXME: check that ty and def match |
1071 | match &self.ty.value { | 881 | match &self.ty.value { |
1072 | Ty::Apply(a_ty) => def | 882 | Ty::Apply(a_ty) => { |
1073 | .fields(db) | 883 | let field_types = db.field_types(def.into()); |
1074 | .into_iter() | 884 | def.fields(db) |
1075 | .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) | 885 | .into_iter() |
1076 | .collect(), | 886 | .map(|it| { |
887 | let ty = field_types[it.id].clone().subst(&a_ty.parameters); | ||
888 | (it, self.derived(ty)) | ||
889 | }) | ||
890 | .collect() | ||
891 | } | ||
1077 | _ => Vec::new(), | 892 | _ => Vec::new(), |
1078 | } | 893 | } |
1079 | } | 894 | } |
@@ -1081,10 +896,10 @@ impl Type { | |||
1081 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { | 896 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { |
1082 | // There should be no inference vars in types passed here | 897 | // There should be no inference vars in types passed here |
1083 | // FIXME check that? | 898 | // FIXME check that? |
1084 | let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; | 899 | let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; |
1085 | let environment = self.ty.environment.clone(); | 900 | let environment = self.ty.environment.clone(); |
1086 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; | 901 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; |
1087 | ty::autoderef(db, Some(self.krate), ty) | 902 | autoderef(db, Some(self.krate), ty) |
1088 | .map(|canonical| canonical.value) | 903 | .map(|canonical| canonical.value) |
1089 | .map(move |ty| self.derived(ty)) | 904 | .map(move |ty| self.derived(ty)) |
1090 | } | 905 | } |
@@ -1097,7 +912,7 @@ impl Type { | |||
1097 | krate: Crate, | 912 | krate: Crate, |
1098 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 913 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
1099 | ) -> Option<T> { | 914 | ) -> Option<T> { |
1100 | for krate in self.ty.value.def_crates(db, krate.crate_id)? { | 915 | for krate in self.ty.value.def_crates(db, krate.id)? { |
1101 | let impls = db.impls_in_crate(krate); | 916 | let impls = db.impls_in_crate(krate); |
1102 | 917 | ||
1103 | for impl_block in impls.lookup_impl_blocks(&self.ty.value) { | 918 | for impl_block in impls.lookup_impl_blocks(&self.ty.value) { |
@@ -1111,11 +926,6 @@ impl Type { | |||
1111 | None | 926 | None |
1112 | } | 927 | } |
1113 | 928 | ||
1114 | // FIXME: remove | ||
1115 | pub fn into_ty(self) -> Ty { | ||
1116 | self.ty.value | ||
1117 | } | ||
1118 | |||
1119 | pub fn as_adt(&self) -> Option<Adt> { | 929 | pub fn as_adt(&self) -> Option<Adt> { |
1120 | let (adt, _subst) = self.ty.value.as_adt()?; | 930 | let (adt, _subst) = self.ty.value.as_adt()?; |
1121 | Some(adt.into()) | 931 | Some(adt.into()) |
@@ -1124,15 +934,14 @@ impl Type { | |||
1124 | // FIXME: provide required accessors such that it becomes implementable from outside. | 934 | // FIXME: provide required accessors such that it becomes implementable from outside. |
1125 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | 935 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { |
1126 | match (&self.ty.value, &other.ty.value) { | 936 | match (&self.ty.value, &other.ty.value) { |
1127 | (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => { | 937 | (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor |
1128 | match ctor { | 938 | { |
1129 | TypeCtor::Ref(..) => match parameters.as_single() { | 939 | TypeCtor::Ref(..) => match parameters.as_single() { |
1130 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, | 940 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, |
1131 | _ => false, | 941 | _ => false, |
1132 | }, | 942 | }, |
1133 | _ => a_original_ty.ctor == *ctor, | 943 | _ => a_original_ty.ctor == *ctor, |
1134 | } | 944 | }, |
1135 | } | ||
1136 | _ => false, | 945 | _ => false, |
1137 | } | 946 | } |
1138 | } | 947 | } |
@@ -1155,7 +964,7 @@ impl HirDisplay for Type { | |||
1155 | pub enum ScopeDef { | 964 | pub enum ScopeDef { |
1156 | ModuleDef(ModuleDef), | 965 | ModuleDef(ModuleDef), |
1157 | MacroDef(MacroDef), | 966 | MacroDef(MacroDef), |
1158 | GenericParam(GenericParam), | 967 | GenericParam(TypeParam), |
1159 | ImplSelfType(ImplBlock), | 968 | ImplSelfType(ImplBlock), |
1160 | AdtSelfType(Adt), | 969 | AdtSelfType(Adt), |
1161 | Local(Local), | 970 | Local(Local), |