diff options
author | Seivan Heidari <[email protected]> | 2019-11-28 07:19:14 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-11-28 07:19:14 +0000 |
commit | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (patch) | |
tree | 9de2c0267ddcc00df717f90034d0843d751a851b /crates/ra_hir/src/code_model.rs | |
parent | a7394b44c870f585eacfeb3036a33471aff49ff8 (diff) | |
parent | 484acc8a61d599662ed63a4cbda091d38a982551 (diff) |
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 449 |
1 files changed, 298 insertions, 151 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 3f44a50c4..38d66c2a7 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -6,28 +6,31 @@ use std::sync::Arc; | |||
6 | 6 | ||
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | adt::VariantData, | 8 | adt::VariantData, |
9 | body::{Body, BodySourceMap}, | ||
9 | builtin_type::BuiltinType, | 10 | builtin_type::BuiltinType, |
10 | docs::Documentation, | 11 | docs::Documentation, |
12 | expr::{BindingAnnotation, Pat, PatId}, | ||
11 | per_ns::PerNs, | 13 | per_ns::PerNs, |
12 | resolver::{HasResolver, TypeNs}, | 14 | resolver::HasResolver, |
13 | type_ref::TypeRef, | 15 | type_ref::{Mutability, TypeRef}, |
14 | AstItemDef, ConstId, ContainerId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, | 16 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, |
15 | LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, | 17 | HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, |
16 | TraitId, TypeAliasId, UnionId, | 18 | Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, |
17 | }; | 19 | }; |
18 | use hir_expand::{ | 20 | use hir_expand::{ |
19 | diagnostics::DiagnosticSink, | 21 | diagnostics::DiagnosticSink, |
20 | name::{self, AsName}, | 22 | name::{self, AsName}, |
21 | AstId, MacroDefId, | 23 | AstId, MacroDefId, |
22 | }; | 24 | }; |
25 | use hir_ty::expr::ExprValidator; | ||
23 | use ra_db::{CrateId, Edition, FileId, FilePosition}; | 26 | use ra_db::{CrateId, Edition, FileId, FilePosition}; |
24 | use ra_syntax::{ast, AstNode, SyntaxNode}; | 27 | use ra_syntax::{ast, AstNode, SyntaxNode}; |
25 | 28 | ||
26 | use crate::{ | 29 | use crate::{ |
27 | db::{DefDatabase, HirDatabase}, | 30 | db::{DefDatabase, HirDatabase}, |
28 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 31 | ty::display::HirFormatter, |
29 | ty::{InferenceResult, Namespace, TraitRef}, | 32 | ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk}, |
30 | Either, Name, Source, Ty, | 33 | CallableDef, Either, HirDisplay, Name, Source, |
31 | }; | 34 | }; |
32 | 35 | ||
33 | /// hir::Crate describes a single crate. It's the main interface with which | 36 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -168,15 +171,15 @@ pub use hir_def::attr::Attrs; | |||
168 | 171 | ||
169 | impl Module { | 172 | impl Module { |
170 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 173 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
171 | Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } | 174 | Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } } |
172 | } | 175 | } |
173 | 176 | ||
174 | /// Name of this module. | 177 | /// Name of this module. |
175 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 178 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
176 | let def_map = db.crate_def_map(self.id.krate); | 179 | let def_map = db.crate_def_map(self.id.krate); |
177 | let parent = def_map[self.id.module_id].parent?; | 180 | let parent = def_map[self.id.local_id].parent?; |
178 | def_map[parent].children.iter().find_map(|(name, module_id)| { | 181 | def_map[parent].children.iter().find_map(|(name, module_id)| { |
179 | if *module_id == self.id.module_id { | 182 | if *module_id == self.id.local_id { |
180 | Some(name.clone()) | 183 | Some(name.clone()) |
181 | } else { | 184 | } else { |
182 | None | 185 | None |
@@ -200,14 +203,14 @@ impl Module { | |||
200 | /// Finds a child module with the specified name. | 203 | /// Finds a child module with the specified name. |
201 | pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> { | 204 | pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> { |
202 | let def_map = db.crate_def_map(self.id.krate); | 205 | let def_map = db.crate_def_map(self.id.krate); |
203 | let child_id = def_map[self.id.module_id].children.get(name)?; | 206 | let child_id = def_map[self.id.local_id].children.get(name)?; |
204 | Some(self.with_module_id(*child_id)) | 207 | Some(self.with_module_id(*child_id)) |
205 | } | 208 | } |
206 | 209 | ||
207 | /// Iterates over all child modules. | 210 | /// Iterates over all child modules. |
208 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { | 211 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { |
209 | let def_map = db.crate_def_map(self.id.krate); | 212 | let def_map = db.crate_def_map(self.id.krate); |
210 | let children = def_map[self.id.module_id] | 213 | let children = def_map[self.id.local_id] |
211 | .children | 214 | .children |
212 | .iter() | 215 | .iter() |
213 | .map(|(_, module_id)| self.with_module_id(*module_id)) | 216 | .map(|(_, module_id)| self.with_module_id(*module_id)) |
@@ -218,7 +221,7 @@ impl Module { | |||
218 | /// Finds a parent module. | 221 | /// Finds a parent module. |
219 | pub fn parent(self, db: &impl DefDatabase) -> Option<Module> { | 222 | pub fn parent(self, db: &impl DefDatabase) -> Option<Module> { |
220 | let def_map = db.crate_def_map(self.id.krate); | 223 | let def_map = db.crate_def_map(self.id.krate); |
221 | let parent_id = def_map[self.id.module_id].parent?; | 224 | let parent_id = def_map[self.id.local_id].parent?; |
222 | Some(self.with_module_id(parent_id)) | 225 | Some(self.with_module_id(parent_id)) |
223 | } | 226 | } |
224 | 227 | ||
@@ -234,7 +237,7 @@ impl Module { | |||
234 | 237 | ||
235 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 238 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
236 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { | 239 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { |
237 | db.crate_def_map(self.id.krate)[self.id.module_id] | 240 | db.crate_def_map(self.id.krate)[self.id.local_id] |
238 | .scope | 241 | .scope |
239 | .entries() | 242 | .entries() |
240 | .map(|(name, res)| { | 243 | .map(|(name, res)| { |
@@ -244,7 +247,7 @@ impl Module { | |||
244 | } | 247 | } |
245 | 248 | ||
246 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 249 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
247 | db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.module_id, sink); | 250 | db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink); |
248 | for decl in self.declarations(db) { | 251 | for decl in self.declarations(db) { |
249 | match decl { | 252 | match decl { |
250 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), | 253 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), |
@@ -269,12 +272,12 @@ impl Module { | |||
269 | 272 | ||
270 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { | 273 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { |
271 | let def_map = db.crate_def_map(self.id.krate); | 274 | let def_map = db.crate_def_map(self.id.krate); |
272 | def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() | 275 | def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() |
273 | } | 276 | } |
274 | 277 | ||
275 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { | 278 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { |
276 | let def_map = db.crate_def_map(self.id.krate); | 279 | let def_map = db.crate_def_map(self.id.krate); |
277 | def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() | 280 | def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() |
278 | } | 281 | } |
279 | 282 | ||
280 | fn with_module_id(self, module_id: LocalModuleId) -> Module { | 283 | fn with_module_id(self, module_id: LocalModuleId) -> Module { |
@@ -320,14 +323,14 @@ pub struct Struct { | |||
320 | 323 | ||
321 | impl Struct { | 324 | impl Struct { |
322 | pub fn module(self, db: &impl DefDatabase) -> Module { | 325 | pub fn module(self, db: &impl DefDatabase) -> Module { |
323 | Module { id: self.id.0.module(db) } | 326 | Module { id: self.id.module(db) } |
324 | } | 327 | } |
325 | 328 | ||
326 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 329 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
327 | Some(self.module(db).krate()) | 330 | Some(self.module(db).krate()) |
328 | } | 331 | } |
329 | 332 | ||
330 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 333 | pub fn name(self, db: &impl DefDatabase) -> Name { |
331 | db.struct_data(self.id.into()).name.clone() | 334 | db.struct_data(self.id.into()).name.clone() |
332 | } | 335 | } |
333 | 336 | ||
@@ -349,12 +352,12 @@ impl Struct { | |||
349 | .map(|(id, _)| StructField { parent: self.into(), id }) | 352 | .map(|(id, _)| StructField { parent: self.into(), id }) |
350 | } | 353 | } |
351 | 354 | ||
352 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 355 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
353 | db.type_for_def(self.into(), Namespace::Types) | 356 | Type::from_def(db, self.id.module(db).krate, self.id) |
354 | } | 357 | } |
355 | 358 | ||
356 | pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { | 359 | pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { |
357 | db.type_for_def(self.into(), Namespace::Values) | 360 | db.value_ty(self.id.into()) |
358 | } | 361 | } |
359 | 362 | ||
360 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 363 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
@@ -368,16 +371,38 @@ pub struct Union { | |||
368 | } | 371 | } |
369 | 372 | ||
370 | impl Union { | 373 | impl Union { |
371 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 374 | pub fn name(self, db: &impl DefDatabase) -> Name { |
372 | db.struct_data(self.id.into()).name.clone() | 375 | db.union_data(self.id).name.clone() |
373 | } | 376 | } |
374 | 377 | ||
375 | pub fn module(self, db: &impl DefDatabase) -> Module { | 378 | pub fn module(self, db: &impl DefDatabase) -> Module { |
376 | Module { id: self.id.0.module(db) } | 379 | Module { id: self.id.module(db) } |
377 | } | 380 | } |
378 | 381 | ||
379 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 382 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
380 | db.type_for_def(self.into(), Namespace::Types) | 383 | Type::from_def(db, self.id.module(db).krate, self.id) |
384 | } | ||
385 | |||
386 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | ||
387 | db.union_data(self.id) | ||
388 | .variant_data | ||
389 | .fields() | ||
390 | .iter() | ||
391 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
392 | .collect() | ||
393 | } | ||
394 | |||
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> { | ||
405 | db.union_data(self.id).variant_data.clone() | ||
381 | } | 406 | } |
382 | } | 407 | } |
383 | 408 | ||
@@ -395,7 +420,7 @@ impl Enum { | |||
395 | Some(self.module(db).krate()) | 420 | Some(self.module(db).krate()) |
396 | } | 421 | } |
397 | 422 | ||
398 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 423 | pub fn name(self, db: &impl DefDatabase) -> Name { |
399 | db.enum_data(self.id).name.clone() | 424 | db.enum_data(self.id).name.clone() |
400 | } | 425 | } |
401 | 426 | ||
@@ -408,15 +433,12 @@ impl Enum { | |||
408 | } | 433 | } |
409 | 434 | ||
410 | pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { | 435 | pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { |
411 | db.enum_data(self.id) | 436 | let id = db.enum_data(self.id).variant(name)?; |
412 | .variants | 437 | Some(EnumVariant { parent: self, id }) |
413 | .iter() | ||
414 | .find(|(_id, data)| data.name.as_ref() == Some(name)) | ||
415 | .map(|(id, _)| EnumVariant { parent: self, id }) | ||
416 | } | 438 | } |
417 | 439 | ||
418 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 440 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
419 | db.type_for_def(self.into(), Namespace::Types) | 441 | Type::from_def(db, self.id.module(db).krate, self.id) |
420 | } | 442 | } |
421 | } | 443 | } |
422 | 444 | ||
@@ -434,7 +456,7 @@ impl EnumVariant { | |||
434 | self.parent | 456 | self.parent |
435 | } | 457 | } |
436 | 458 | ||
437 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 459 | pub fn name(self, db: &impl DefDatabase) -> Name { |
438 | db.enum_data(self.parent.id).variants[self.id].name.clone() | 460 | db.enum_data(self.parent.id).variants[self.id].name.clone() |
439 | } | 461 | } |
440 | 462 | ||
@@ -469,12 +491,13 @@ pub enum Adt { | |||
469 | impl_froms!(Adt: Struct, Union, Enum); | 491 | impl_froms!(Adt: Struct, Union, Enum); |
470 | 492 | ||
471 | impl Adt { | 493 | impl Adt { |
472 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 494 | pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { |
473 | match self { | 495 | let subst = db.generic_defaults(self.into()); |
474 | Adt::Struct(it) => it.ty(db), | 496 | subst.iter().any(|ty| ty == &Ty::Unknown) |
475 | Adt::Union(it) => it.ty(db), | 497 | } |
476 | Adt::Enum(it) => it.ty(db), | 498 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
477 | } | 499 | let id = AdtId::from(self); |
500 | Type::from_def(db, id.module(db).krate, id) | ||
478 | } | 501 | } |
479 | 502 | ||
480 | pub fn module(self, db: &impl DefDatabase) -> Module { | 503 | pub fn module(self, db: &impl DefDatabase) -> Module { |
@@ -493,28 +516,24 @@ impl Adt { | |||
493 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 516 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
494 | pub enum VariantDef { | 517 | pub enum VariantDef { |
495 | Struct(Struct), | 518 | Struct(Struct), |
519 | Union(Union), | ||
496 | EnumVariant(EnumVariant), | 520 | EnumVariant(EnumVariant), |
497 | } | 521 | } |
498 | impl_froms!(VariantDef: Struct, EnumVariant); | 522 | impl_froms!(VariantDef: Struct, Union, EnumVariant); |
499 | 523 | ||
500 | impl VariantDef { | 524 | impl VariantDef { |
501 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 525 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
502 | match self { | 526 | match self { |
503 | VariantDef::Struct(it) => it.fields(db), | 527 | VariantDef::Struct(it) => it.fields(db), |
528 | VariantDef::Union(it) => it.fields(db), | ||
504 | VariantDef::EnumVariant(it) => it.fields(db), | 529 | VariantDef::EnumVariant(it) => it.fields(db), |
505 | } | 530 | } |
506 | } | 531 | } |
507 | 532 | ||
508 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
509 | match self { | ||
510 | VariantDef::Struct(it) => it.field(db, name), | ||
511 | VariantDef::EnumVariant(it) => it.field(db, name), | ||
512 | } | ||
513 | } | ||
514 | |||
515 | pub fn module(self, db: &impl HirDatabase) -> Module { | 533 | pub fn module(self, db: &impl HirDatabase) -> Module { |
516 | match self { | 534 | match self { |
517 | VariantDef::Struct(it) => it.module(db), | 535 | VariantDef::Struct(it) => it.module(db), |
536 | VariantDef::Union(it) => it.module(db), | ||
518 | VariantDef::EnumVariant(it) => it.module(db), | 537 | VariantDef::EnumVariant(it) => it.module(db), |
519 | } | 538 | } |
520 | } | 539 | } |
@@ -522,6 +541,7 @@ impl VariantDef { | |||
522 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 541 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
523 | match self { | 542 | match self { |
524 | VariantDef::Struct(it) => it.variant_data(db), | 543 | VariantDef::Struct(it) => it.variant_data(db), |
544 | VariantDef::Union(it) => it.variant_data(db), | ||
525 | VariantDef::EnumVariant(it) => it.variant_data(db), | 545 | VariantDef::EnumVariant(it) => it.variant_data(db), |
526 | } | 546 | } |
527 | } | 547 | } |
@@ -538,14 +558,6 @@ pub enum DefWithBody { | |||
538 | impl_froms!(DefWithBody: Function, Const, Static); | 558 | impl_froms!(DefWithBody: Function, Const, Static); |
539 | 559 | ||
540 | impl DefWithBody { | 560 | impl DefWithBody { |
541 | pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> { | ||
542 | match self { | ||
543 | DefWithBody::Const(c) => c.krate(db), | ||
544 | DefWithBody::Function(f) => f.krate(db), | ||
545 | DefWithBody::Static(s) => s.krate(db), | ||
546 | } | ||
547 | } | ||
548 | |||
549 | pub fn module(self, db: &impl HirDatabase) -> Module { | 561 | pub fn module(self, db: &impl HirDatabase) -> Module { |
550 | match self { | 562 | match self { |
551 | DefWithBody::Const(c) => c.module(db), | 563 | DefWithBody::Const(c) => c.module(db), |
@@ -590,11 +602,11 @@ impl Function { | |||
590 | } | 602 | } |
591 | 603 | ||
592 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 604 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
593 | db.type_for_def(self.into(), Namespace::Values) | 605 | db.value_ty(self.id.into()) |
594 | } | 606 | } |
595 | 607 | ||
596 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 608 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
597 | db.infer(self.into()) | 609 | db.infer(self.id.into()) |
598 | } | 610 | } |
599 | 611 | ||
600 | /// The containing impl block, if this is a method. | 612 | /// The containing impl block, if this is a method. |
@@ -623,8 +635,8 @@ impl Function { | |||
623 | 635 | ||
624 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 636 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
625 | let infer = self.infer(db); | 637 | let infer = self.infer(db); |
626 | infer.add_diagnostics(db, self, sink); | 638 | infer.add_diagnostics(db, self.id, sink); |
627 | let mut validator = ExprValidator::new(self, infer, sink); | 639 | let mut validator = ExprValidator::new(self.id, infer, sink); |
628 | validator.validate_body(db); | 640 | validator.validate_body(db); |
629 | } | 641 | } |
630 | } | 642 | } |
@@ -648,7 +660,7 @@ impl Const { | |||
648 | } | 660 | } |
649 | 661 | ||
650 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 662 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
651 | db.infer(self.into()) | 663 | db.infer(self.id.into()) |
652 | } | 664 | } |
653 | 665 | ||
654 | /// The containing impl block, if this is a type alias. | 666 | /// The containing impl block, if this is a type alias. |
@@ -691,7 +703,7 @@ impl Static { | |||
691 | } | 703 | } |
692 | 704 | ||
693 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 705 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
694 | db.infer(self.into()) | 706 | db.infer(self.id.into()) |
695 | } | 707 | } |
696 | } | 708 | } |
697 | 709 | ||
@@ -705,73 +717,12 @@ impl Trait { | |||
705 | Module { id: self.id.module(db) } | 717 | Module { id: self.id.module(db) } |
706 | } | 718 | } |
707 | 719 | ||
708 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 720 | pub fn name(self, db: &impl DefDatabase) -> Name { |
709 | db.trait_data(self.id).name.clone() | 721 | db.trait_data(self.id).name.clone() |
710 | } | 722 | } |
711 | 723 | ||
712 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 724 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
713 | db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() | 725 | db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() |
714 | } | ||
715 | |||
716 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | ||
717 | let resolver = self.id.resolver(db); | ||
718 | // returning the iterator directly doesn't easily work because of | ||
719 | // lifetime problems, but since there usually shouldn't be more than a | ||
720 | // few direct traits this should be fine (we could even use some kind of | ||
721 | // SmallVec if performance is a concern) | ||
722 | db.generic_params(self.id.into()) | ||
723 | .where_predicates | ||
724 | .iter() | ||
725 | .filter_map(|pred| match &pred.type_ref { | ||
726 | TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(), | ||
727 | _ => None, | ||
728 | }) | ||
729 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { | ||
730 | Some(TypeNs::TraitId(t)) => Some(t), | ||
731 | _ => None, | ||
732 | }) | ||
733 | .map(Trait::from) | ||
734 | .collect() | ||
735 | } | ||
736 | |||
737 | /// Returns an iterator over the whole super trait hierarchy (including the | ||
738 | /// trait itself). | ||
739 | pub fn all_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | ||
740 | // we need to take care a bit here to avoid infinite loops in case of cycles | ||
741 | // (i.e. if we have `trait A: B; trait B: A;`) | ||
742 | let mut result = vec![self]; | ||
743 | let mut i = 0; | ||
744 | while i < result.len() { | ||
745 | let t = result[i]; | ||
746 | // yeah this is quadratic, but trait hierarchies should be flat | ||
747 | // enough that this doesn't matter | ||
748 | for tt in t.direct_super_traits(db) { | ||
749 | if !result.contains(&tt) { | ||
750 | result.push(tt); | ||
751 | } | ||
752 | } | ||
753 | i += 1; | ||
754 | } | ||
755 | result | ||
756 | } | ||
757 | |||
758 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | ||
759 | let trait_data = db.trait_data(self.id); | ||
760 | let res = | ||
761 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; | ||
762 | Some(res) | ||
763 | } | ||
764 | |||
765 | pub fn associated_type_by_name_including_super_traits( | ||
766 | self, | ||
767 | db: &impl HirDatabase, | ||
768 | name: &Name, | ||
769 | ) -> Option<TypeAlias> { | ||
770 | self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) | ||
771 | } | ||
772 | |||
773 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | ||
774 | TraitRef::for_trait(db, self) | ||
775 | } | 726 | } |
776 | 727 | ||
777 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | 728 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { |
@@ -785,6 +736,11 @@ pub struct TypeAlias { | |||
785 | } | 736 | } |
786 | 737 | ||
787 | impl TypeAlias { | 738 | impl TypeAlias { |
739 | pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { | ||
740 | let subst = db.generic_defaults(self.id.into()); | ||
741 | subst.iter().any(|ty| ty == &Ty::Unknown) | ||
742 | } | ||
743 | |||
788 | pub fn module(self, db: &impl DefDatabase) -> Module { | 744 | pub fn module(self, db: &impl DefDatabase) -> Module { |
789 | Module { id: self.id.lookup(db).module(db) } | 745 | Module { id: self.id.lookup(db).module(db) } |
790 | } | 746 | } |
@@ -821,8 +777,8 @@ impl TypeAlias { | |||
821 | db.type_alias_data(self.id).type_ref.clone() | 777 | db.type_alias_data(self.id).type_ref.clone() |
822 | } | 778 | } |
823 | 779 | ||
824 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 780 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
825 | db.type_for_def(self.into(), Namespace::Types) | 781 | Type::from_def(db, self.id.lookup(db).module(db).krate, self.id) |
826 | } | 782 | } |
827 | 783 | ||
828 | pub fn name(self, db: &impl DefDatabase) -> Name { | 784 | pub fn name(self, db: &impl DefDatabase) -> Name { |
@@ -897,16 +853,6 @@ impl_froms!( | |||
897 | Const | 853 | Const |
898 | ); | 854 | ); |
899 | 855 | ||
900 | impl From<AssocItem> for GenericDef { | ||
901 | fn from(item: AssocItem) -> Self { | ||
902 | match item { | ||
903 | AssocItem::Function(f) => f.into(), | ||
904 | AssocItem::Const(c) => c.into(), | ||
905 | AssocItem::TypeAlias(t) => t.into(), | ||
906 | } | ||
907 | } | ||
908 | } | ||
909 | |||
910 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 856 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
911 | pub struct Local { | 857 | pub struct Local { |
912 | pub(crate) parent: DefWithBody, | 858 | pub(crate) parent: DefWithBody, |
@@ -945,9 +891,14 @@ impl Local { | |||
945 | self.parent.module(db) | 891 | self.parent.module(db) |
946 | } | 892 | } |
947 | 893 | ||
948 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 894 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
949 | let infer = db.infer(self.parent); | 895 | let def = DefWithBodyId::from(self.parent); |
950 | infer[self.pat_id].clone() | 896 | let infer = db.infer(def); |
897 | let ty = infer[self.pat_id].clone(); | ||
898 | let resolver = def.resolver(db); | ||
899 | let krate = def.module(db).krate; | ||
900 | let environment = TraitEnvironment::lower(db, &resolver); | ||
901 | Type { krate, ty: InEnvironment { value: ty, environment } } | ||
951 | } | 902 | } |
952 | 903 | ||
953 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | 904 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { |
@@ -960,7 +911,7 @@ impl Local { | |||
960 | 911 | ||
961 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 912 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
962 | pub struct GenericParam { | 913 | pub struct GenericParam { |
963 | pub(crate) parent: GenericDef, | 914 | pub(crate) parent: GenericDefId, |
964 | pub(crate) idx: u32, | 915 | pub(crate) idx: u32, |
965 | } | 916 | } |
966 | 917 | ||
@@ -970,6 +921,15 @@ pub struct ImplBlock { | |||
970 | } | 921 | } |
971 | 922 | ||
972 | impl ImplBlock { | 923 | impl ImplBlock { |
924 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { | ||
925 | let impls = db.impls_in_crate(krate.crate_id); | ||
926 | impls.all_impls().map(Self::from).collect() | ||
927 | } | ||
928 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { | ||
929 | let impls = db.impls_in_crate(krate.crate_id); | ||
930 | impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() | ||
931 | } | ||
932 | |||
973 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 933 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
974 | db.impl_data(self.id).target_trait.clone() | 934 | db.impl_data(self.id).target_trait.clone() |
975 | } | 935 | } |
@@ -978,13 +938,12 @@ impl ImplBlock { | |||
978 | db.impl_data(self.id).target_type.clone() | 938 | db.impl_data(self.id).target_type.clone() |
979 | } | 939 | } |
980 | 940 | ||
981 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | 941 | pub fn target_ty(&self, db: &impl HirDatabase) -> Type { |
982 | Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) | 942 | let impl_data = db.impl_data(self.id); |
983 | } | 943 | let resolver = self.id.resolver(db); |
984 | 944 | let environment = TraitEnvironment::lower(db, &resolver); | |
985 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | 945 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); |
986 | let target_ty = self.target_ty(db); | 946 | Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } } |
987 | TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) | ||
988 | } | 947 | } |
989 | 948 | ||
990 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | 949 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { |
@@ -1004,6 +963,194 @@ impl ImplBlock { | |||
1004 | } | 963 | } |
1005 | } | 964 | } |
1006 | 965 | ||
966 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
967 | pub struct Type { | ||
968 | pub(crate) krate: CrateId, | ||
969 | pub(crate) ty: InEnvironment<Ty>, | ||
970 | } | ||
971 | |||
972 | impl Type { | ||
973 | fn from_def( | ||
974 | db: &impl HirDatabase, | ||
975 | krate: CrateId, | ||
976 | def: impl HasResolver + Into<TyDefId>, | ||
977 | ) -> Type { | ||
978 | let resolver = def.resolver(db); | ||
979 | let environment = TraitEnvironment::lower(db, &resolver); | ||
980 | let ty = db.ty(def.into()); | ||
981 | Type { krate, ty: InEnvironment { value: ty, environment } } | ||
982 | } | ||
983 | |||
984 | pub fn is_bool(&self) -> bool { | ||
985 | match &self.ty.value { | ||
986 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
987 | TypeCtor::Bool => true, | ||
988 | _ => false, | ||
989 | }, | ||
990 | _ => false, | ||
991 | } | ||
992 | } | ||
993 | |||
994 | pub fn is_mutable_reference(&self) -> bool { | ||
995 | match &self.ty.value { | ||
996 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
997 | TypeCtor::Ref(Mutability::Mut) => true, | ||
998 | _ => false, | ||
999 | }, | ||
1000 | _ => false, | ||
1001 | } | ||
1002 | } | ||
1003 | |||
1004 | pub fn is_unknown(&self) -> bool { | ||
1005 | match &self.ty.value { | ||
1006 | Ty::Unknown => true, | ||
1007 | _ => false, | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | // FIXME: this method is broken, as it doesn't take closures into account. | ||
1012 | pub fn as_callable(&self) -> Option<CallableDef> { | ||
1013 | Some(self.ty.value.as_callable()?.0) | ||
1014 | } | ||
1015 | |||
1016 | pub fn contains_unknown(&self) -> bool { | ||
1017 | return go(&self.ty.value); | ||
1018 | |||
1019 | fn go(ty: &Ty) -> bool { | ||
1020 | match ty { | ||
1021 | Ty::Unknown => true, | ||
1022 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), | ||
1023 | _ => false, | ||
1024 | } | ||
1025 | } | ||
1026 | } | ||
1027 | |||
1028 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { | ||
1029 | if let Ty::Apply(a_ty) = &self.ty.value { | ||
1030 | match a_ty.ctor { | ||
1031 | ty::TypeCtor::Adt(AdtId::StructId(s)) => { | ||
1032 | let var_def = s.into(); | ||
1033 | return db | ||
1034 | .field_types(var_def) | ||
1035 | .iter() | ||
1036 | .map(|(local_id, ty)| { | ||
1037 | let def = StructField { parent: var_def.into(), id: local_id }; | ||
1038 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1039 | (def, self.derived(ty)) | ||
1040 | }) | ||
1041 | .collect(); | ||
1042 | } | ||
1043 | _ => {} | ||
1044 | } | ||
1045 | }; | ||
1046 | Vec::new() | ||
1047 | } | ||
1048 | |||
1049 | pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> { | ||
1050 | let mut res = Vec::new(); | ||
1051 | if let Ty::Apply(a_ty) = &self.ty.value { | ||
1052 | match a_ty.ctor { | ||
1053 | ty::TypeCtor::Tuple { .. } => { | ||
1054 | for ty in a_ty.parameters.iter() { | ||
1055 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1056 | res.push(self.derived(ty)); | ||
1057 | } | ||
1058 | } | ||
1059 | _ => {} | ||
1060 | } | ||
1061 | }; | ||
1062 | res | ||
1063 | } | ||
1064 | |||
1065 | pub fn variant_fields( | ||
1066 | &self, | ||
1067 | db: &impl HirDatabase, | ||
1068 | def: VariantDef, | ||
1069 | ) -> Vec<(StructField, Type)> { | ||
1070 | // FIXME: check that ty and def match | ||
1071 | match &self.ty.value { | ||
1072 | Ty::Apply(a_ty) => def | ||
1073 | .fields(db) | ||
1074 | .into_iter() | ||
1075 | .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) | ||
1076 | .collect(), | ||
1077 | _ => Vec::new(), | ||
1078 | } | ||
1079 | } | ||
1080 | |||
1081 | 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 | ||
1083 | // FIXME check that? | ||
1084 | let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
1085 | let environment = self.ty.environment.clone(); | ||
1086 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; | ||
1087 | ty::autoderef(db, Some(self.krate), ty) | ||
1088 | .map(|canonical| canonical.value) | ||
1089 | .map(move |ty| self.derived(ty)) | ||
1090 | } | ||
1091 | |||
1092 | // This would be nicer if it just returned an iterator, but that runs into | ||
1093 | // lifetime problems, because we need to borrow temp `CrateImplBlocks`. | ||
1094 | pub fn iterate_impl_items<T>( | ||
1095 | self, | ||
1096 | db: &impl HirDatabase, | ||
1097 | krate: Crate, | ||
1098 | mut callback: impl FnMut(AssocItem) -> Option<T>, | ||
1099 | ) -> Option<T> { | ||
1100 | for krate in self.ty.value.def_crates(db, krate.crate_id)? { | ||
1101 | let impls = db.impls_in_crate(krate); | ||
1102 | |||
1103 | for impl_block in impls.lookup_impl_blocks(&self.ty.value) { | ||
1104 | for &item in db.impl_data(impl_block).items.iter() { | ||
1105 | if let Some(result) = callback(item.into()) { | ||
1106 | return Some(result); | ||
1107 | } | ||
1108 | } | ||
1109 | } | ||
1110 | } | ||
1111 | None | ||
1112 | } | ||
1113 | |||
1114 | // FIXME: remove | ||
1115 | pub fn into_ty(self) -> Ty { | ||
1116 | self.ty.value | ||
1117 | } | ||
1118 | |||
1119 | pub fn as_adt(&self) -> Option<Adt> { | ||
1120 | let (adt, _subst) = self.ty.value.as_adt()?; | ||
1121 | Some(adt.into()) | ||
1122 | } | ||
1123 | |||
1124 | // FIXME: provide required accessors such that it becomes implementable from outside. | ||
1125 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | ||
1126 | match (&self.ty.value, &other.ty.value) { | ||
1127 | (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => { | ||
1128 | match ctor { | ||
1129 | TypeCtor::Ref(..) => match parameters.as_single() { | ||
1130 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, | ||
1131 | _ => false, | ||
1132 | }, | ||
1133 | _ => a_original_ty.ctor == *ctor, | ||
1134 | } | ||
1135 | } | ||
1136 | _ => false, | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | fn derived(&self, ty: Ty) -> Type { | ||
1141 | Type { | ||
1142 | krate: self.krate, | ||
1143 | ty: InEnvironment { value: ty, environment: self.ty.environment.clone() }, | ||
1144 | } | ||
1145 | } | ||
1146 | } | ||
1147 | |||
1148 | impl HirDisplay for Type { | ||
1149 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> std::fmt::Result { | ||
1150 | self.ty.value.hir_fmt(f) | ||
1151 | } | ||
1152 | } | ||
1153 | |||
1007 | /// For IDE only | 1154 | /// For IDE only |
1008 | pub enum ScopeDef { | 1155 | pub enum ScopeDef { |
1009 | ModuleDef(ModuleDef), | 1156 | ModuleDef(ModuleDef), |