aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs449
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
7use hir_def::{ 7use 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};
18use hir_expand::{ 20use hir_expand::{
19 diagnostics::DiagnosticSink, 21 diagnostics::DiagnosticSink,
20 name::{self, AsName}, 22 name::{self, AsName},
21 AstId, MacroDefId, 23 AstId, MacroDefId,
22}; 24};
25use hir_ty::expr::ExprValidator;
23use ra_db::{CrateId, Edition, FileId, FilePosition}; 26use ra_db::{CrateId, Edition, FileId, FilePosition};
24use ra_syntax::{ast, AstNode, SyntaxNode}; 27use ra_syntax::{ast, AstNode, SyntaxNode};
25 28
26use crate::{ 29use 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
169impl Module { 172impl 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
321impl Struct { 324impl 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
370impl Union { 373impl 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 {
469impl_froms!(Adt: Struct, Union, Enum); 491impl_froms!(Adt: Struct, Union, Enum);
470 492
471impl Adt { 493impl 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)]
494pub enum VariantDef { 517pub enum VariantDef {
495 Struct(Struct), 518 Struct(Struct),
519 Union(Union),
496 EnumVariant(EnumVariant), 520 EnumVariant(EnumVariant),
497} 521}
498impl_froms!(VariantDef: Struct, EnumVariant); 522impl_froms!(VariantDef: Struct, Union, EnumVariant);
499 523
500impl VariantDef { 524impl 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 {
538impl_froms!(DefWithBody: Function, Const, Static); 558impl_froms!(DefWithBody: Function, Const, Static);
539 559
540impl DefWithBody { 560impl 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
787impl TypeAlias { 738impl 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
900impl 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)]
911pub struct Local { 857pub 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)]
962pub struct GenericParam { 913pub 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
972impl ImplBlock { 923impl 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)]
967pub struct Type {
968 pub(crate) krate: CrateId,
969 pub(crate) ty: InEnvironment<Ty>,
970}
971
972impl 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
1148impl 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
1008pub enum ScopeDef { 1155pub enum ScopeDef {
1009 ModuleDef(ModuleDef), 1156 ModuleDef(ModuleDef),