aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model.rs17
-rw-r--r--crates/ra_hir/src/db.rs11
-rw-r--r--crates/ra_hir/src/ty.rs25
-rw-r--r--crates/ra_hir/src/ty/infer.rs53
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs10
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs46
-rw-r--r--crates/ra_hir/src/ty/lower.rs204
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs18
-rw-r--r--crates/ra_hir/src/ty/traits.rs5
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs52
-rw-r--r--crates/ra_hir/src/ty/utils.rs4
11 files changed, 205 insertions, 240 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 9578c20b0..c5cf39ee1 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -28,8 +28,7 @@ use crate::{
28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
29 ty::display::HirFormatter, 29 ty::display::HirFormatter,
30 ty::{ 30 ty::{
31 self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, 31 self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
32 TypeWalk,
33 }, 32 },
34 CallableDef, Either, HirDisplay, Name, Source, 33 CallableDef, Either, HirDisplay, Name, Source,
35}; 34};
@@ -354,11 +353,11 @@ impl Struct {
354 } 353 }
355 354
356 pub fn ty(self, db: &impl HirDatabase) -> Ty { 355 pub fn ty(self, db: &impl HirDatabase) -> Ty {
357 db.type_for_def(self.into(), Namespace::Types) 356 db.ty(self.id.into())
358 } 357 }
359 358
360 pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { 359 pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty {
361 db.type_for_def(self.into(), Namespace::Values) 360 db.value_ty(self.id.into())
362 } 361 }
363 362
364 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 363 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
@@ -381,7 +380,7 @@ impl Union {
381 } 380 }
382 381
383 pub fn ty(self, db: &impl HirDatabase) -> Ty { 382 pub fn ty(self, db: &impl HirDatabase) -> Ty {
384 db.type_for_def(self.into(), Namespace::Types) 383 db.ty(self.id.into())
385 } 384 }
386 385
387 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 386 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
@@ -442,7 +441,7 @@ impl Enum {
442 } 441 }
443 442
444 pub fn ty(self, db: &impl HirDatabase) -> Ty { 443 pub fn ty(self, db: &impl HirDatabase) -> Ty {
445 db.type_for_def(self.into(), Namespace::Types) 444 db.ty(self.id.into())
446 } 445 }
447} 446}
448 447
@@ -617,7 +616,7 @@ impl Function {
617 } 616 }
618 617
619 pub fn ty(self, db: &impl HirDatabase) -> Ty { 618 pub fn ty(self, db: &impl HirDatabase) -> Ty {
620 db.type_for_def(self.into(), Namespace::Values) 619 db.value_ty(self.id.into())
621 } 620 }
622 621
623 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 622 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
@@ -741,7 +740,7 @@ impl Trait {
741 } 740 }
742 741
743 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { 742 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
744 TraitRef::for_trait(db, self) 743 TraitRef::for_trait(db, self.id)
745 } 744 }
746 745
747 pub fn is_auto(self, db: &impl DefDatabase) -> bool { 746 pub fn is_auto(self, db: &impl DefDatabase) -> bool {
@@ -797,7 +796,7 @@ impl TypeAlias {
797 } 796 }
798 797
799 pub fn ty(self, db: &impl HirDatabase) -> Ty { 798 pub fn ty(self, db: &impl HirDatabase) -> Ty {
800 db.type_for_def(self.into(), Namespace::Types) 799 db.ty(self.id.into())
801 } 800 }
802 801
803 pub fn name(self, db: &impl DefDatabase) -> Name { 802 pub fn name(self, db: &impl DefDatabase) -> Name {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 32f05a4d8..3b5aa7516 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -9,8 +9,8 @@ use crate::{
9 ty::{ 9 ty::{
10 method_resolution::CrateImplBlocks, 10 method_resolution::CrateImplBlocks,
11 traits::{AssocTyValue, Impl}, 11 traits::{AssocTyValue, Impl},
12 CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, 12 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor,
13 TypeCtor, 13 ValueTyDefId,
14 }, 14 },
15 Crate, DefWithBody, ImplBlock, Trait, 15 Crate, DefWithBody, ImplBlock, Trait,
16}; 16};
@@ -37,8 +37,11 @@ pub trait HirDatabase: DefDatabase {
37 #[salsa::invoke(crate::ty::infer_query)] 37 #[salsa::invoke(crate::ty::infer_query)]
38 fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; 38 fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>;
39 39
40 #[salsa::invoke(crate::ty::type_for_def)] 40 #[salsa::invoke(crate::ty::ty_query)]
41 fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; 41 fn ty(&self, def: TyDefId) -> Ty;
42
43 #[salsa::invoke(crate::ty::value_ty_query)]
44 fn value_ty(&self, def: ValueTyDefId) -> Ty;
42 45
43 #[salsa::invoke(crate::ty::field_types_query)] 46 #[salsa::invoke(crate::ty::field_types_query)]
44 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; 47 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>;
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 2a2dc26b4..680ddc2f9 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -19,14 +19,16 @@ use std::sync::Arc;
19use std::{fmt, iter, mem}; 19use std::{fmt, iter, mem};
20 20
21use hir_def::{ 21use hir_def::{
22 generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, 22 expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId,
23 TraitId, TypeAliasId, 23 GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
24}; 24};
25use ra_db::{impl_intern_key, salsa}; 25use ra_db::{impl_intern_key, salsa};
26 26
27use crate::{ 27use crate::{
28 db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, 28 db::HirDatabase,
29 Name, Trait, Uncertain, 29 ty::primitive::{FloatTy, IntTy, Uncertain},
30 util::make_mut_slice,
31 Adt, Crate, Name,
30}; 32};
31use display::{HirDisplay, HirFormatter}; 33use display::{HirDisplay, HirFormatter};
32 34
@@ -35,8 +37,8 @@ pub(crate) use infer::{infer_query, InferTy, InferenceResult};
35pub use lower::CallableDef; 37pub use lower::CallableDef;
36pub(crate) use lower::{ 38pub(crate) use lower::{
37 callable_item_sig, field_types_query, generic_defaults_query, 39 callable_item_sig, field_types_query, generic_defaults_query,
38 generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace, 40 generic_predicates_for_param_query, generic_predicates_query, ty_query, value_ty_query,
39 TypableDef, 41 TyDefId, TypableDef, ValueTyDefId,
40}; 42};
41pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 43pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
42 44
@@ -445,7 +447,7 @@ impl Deref for Substs {
445#[derive(Clone, PartialEq, Eq, Debug, Hash)] 447#[derive(Clone, PartialEq, Eq, Debug, Hash)]
446pub struct TraitRef { 448pub struct TraitRef {
447 /// FIXME name? 449 /// FIXME name?
448 pub trait_: Trait, 450 pub trait_: TraitId,
449 pub substs: Substs, 451 pub substs: Substs,
450} 452}
451 453
@@ -676,7 +678,7 @@ impl Ty {
676 } 678 }
677 679
678 /// If this is an `impl Trait` or `dyn Trait`, returns that trait. 680 /// If this is an `impl Trait` or `dyn Trait`, returns that trait.
679 pub fn inherent_trait(&self) -> Option<Trait> { 681 pub fn inherent_trait(&self) -> Option<TraitId> {
680 match self { 682 match self {
681 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 683 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
682 predicates.iter().find_map(|pred| match pred { 684 predicates.iter().find_map(|pred| match pred {
@@ -988,7 +990,10 @@ impl HirDisplay for Ty {
988 write!( 990 write!(
989 f, 991 f,
990 "{}", 992 "{}",
991 trait_ref.trait_.name(f.db).unwrap_or_else(Name::missing) 993 f.db.trait_data(trait_ref.trait_)
994 .name
995 .clone()
996 .unwrap_or_else(Name::missing)
992 )?; 997 )?;
993 if trait_ref.substs.len() > 1 { 998 if trait_ref.substs.len() > 1 {
994 write!(f, "<")?; 999 write!(f, "<")?;
@@ -1049,7 +1054,7 @@ impl TraitRef {
1049 } else { 1054 } else {
1050 write!(f, ": ")?; 1055 write!(f, ": ")?;
1051 } 1056 }
1052 write!(f, "{}", self.trait_.name(f.db).unwrap_or_else(Name::missing))?; 1057 write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?;
1053 if self.substs.len() > 1 { 1058 if self.substs.len() > 1 {
1054 write!(f, "<")?; 1059 write!(f, "<")?;
1055 f.write_joined(&self.substs[1..], ", ")?; 1060 f.write_joined(&self.substs[1..], ", ")?;
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index b023ae690..beb2efb7a 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -35,15 +35,15 @@ use test_utils::tested_by;
35 35
36use super::{ 36use super::{
37 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 37 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
38 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, 38 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
39 TypeCtor, TypeWalk, Uncertain, 39 TypeWalk, Uncertain,
40}; 40};
41use crate::{ 41use crate::{
42 code_model::TypeAlias, 42 code_model::TypeAlias,
43 db::HirDatabase, 43 db::HirDatabase,
44 expr::{BindingAnnotation, Body, ExprId, PatId}, 44 expr::{BindingAnnotation, Body, ExprId, PatId},
45 ty::infer::diagnostics::InferenceDiagnostic, 45 ty::infer::diagnostics::InferenceDiagnostic,
46 Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, 46 AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef,
47}; 47};
48 48
49macro_rules! ty_app { 49macro_rules! ty_app {
@@ -520,45 +520,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
520 None => return (Ty::Unknown, None), 520 None => return (Ty::Unknown, None),
521 }; 521 };
522 let resolver = &self.resolver; 522 let resolver = &self.resolver;
523 let def: TypableDef = 523 // FIXME: this should resolve assoc items as well, see this example:
524 // FIXME: this should resolve assoc items as well, see this example: 524 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
525 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 525 match resolver.resolve_path_in_type_ns_fully(self.db, &path) {
526 match resolver.resolve_path_in_type_ns_fully(self.db, &path) { 526 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => {
527 Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), 527 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into());
528 Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), 528 let ty = self.db.ty(strukt.into());
529 Some(TypeNs::AdtSelfType(adt)) => adt.into(),
530 Some(TypeNs::EnumVariantId(it)) => it.into(),
531 Some(TypeNs::TypeAliasId(it)) => it.into(),
532
533 Some(TypeNs::SelfType(_)) |
534 Some(TypeNs::GenericParam(_)) |
535 Some(TypeNs::BuiltinType(_)) |
536 Some(TypeNs::TraitId(_)) |
537 Some(TypeNs::AdtId(AdtId::EnumId(_))) |
538 None => {
539 return (Ty::Unknown, None)
540 }
541 };
542 // FIXME remove the duplication between here and `Ty::from_path`?
543 let substs = Ty::substs_from_path(self.db, resolver, path, def);
544 match def {
545 TypableDef::Adt(Adt::Struct(s)) => {
546 let ty = s.ty(self.db);
547 let ty = self.insert_type_vars(ty.apply_substs(substs)); 529 let ty = self.insert_type_vars(ty.apply_substs(substs));
548 (ty, Some(s.into())) 530 (ty, Some(VariantDef::Struct(strukt.into())))
549 } 531 }
550 TypableDef::EnumVariant(var) => { 532 Some(TypeNs::EnumVariantId(var)) => {
551 let ty = var.parent_enum(self.db).ty(self.db); 533 let substs = Ty::substs_from_path(self.db, resolver, path, var.into());
534 let ty = self.db.ty(var.parent.into());
552 let ty = self.insert_type_vars(ty.apply_substs(substs)); 535 let ty = self.insert_type_vars(ty.apply_substs(substs));
553 (ty, Some(var.into())) 536 (ty, Some(VariantDef::EnumVariant(var.into())))
554 } 537 }
555 TypableDef::Adt(Adt::Enum(_)) 538 Some(_) | None => (Ty::Unknown, None),
556 | TypableDef::Adt(Adt::Union(_))
557 | TypableDef::TypeAlias(_)
558 | TypableDef::Function(_)
559 | TypableDef::Const(_)
560 | TypableDef::Static(_)
561 | TypableDef::BuiltinType(_) => (Ty::Unknown, None),
562 } 539 }
563 } 540 }
564 541
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index 3d0895dc6..eb221d6bc 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -17,8 +17,8 @@ use crate::{
17 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 17 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
18 ty::{ 18 ty::{
19 autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, 19 autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy,
20 Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, 20 Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
21 TypeCtor, TypeWalk, Uncertain, 21 TypeWalk, Uncertain,
22 }, 22 },
23 Name, 23 Name,
24}; 24};
@@ -558,11 +558,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
558 Some((ty, func)) => { 558 Some((ty, func)) => {
559 let ty = canonicalized_receiver.decanonicalize_ty(ty); 559 let ty = canonicalized_receiver.decanonicalize_ty(ty);
560 self.write_method_resolution(tgt_expr, func); 560 self.write_method_resolution(tgt_expr, func);
561 ( 561 (ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into())))
562 ty,
563 self.db.type_for_def(func.into(), Namespace::Values),
564 Some(self.db.generic_params(func.id.into())),
565 )
566 } 562 }
567 None => (receiver_ty, Ty::Unknown, None), 563 None => (receiver_ty, Ty::Unknown, None),
568 }; 564 };
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs
index 6165eba4f..be2067dd4 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir/src/ty/infer/path.rs
@@ -7,7 +7,7 @@ use hir_def::{
7 7
8use crate::{ 8use crate::{
9 db::HirDatabase, 9 db::HirDatabase,
10 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, 10 ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId},
11 AssocItem, Container, Function, Name, Path, 11 AssocItem, Container, Function, Name, Path,
12}; 12};
13 13
@@ -56,7 +56,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
56 } 56 }
57 }; 57 };
58 58
59 let typable: TypableDef = match value { 59 let typable: ValueTyDefId = match value {
60 ValueNs::LocalBinding(pat) => { 60 ValueNs::LocalBinding(pat) => {
61 let ty = self.result.type_of_pat.get(pat)?.clone(); 61 let ty = self.result.type_of_pat.get(pat)?.clone();
62 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 62 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
@@ -69,11 +69,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
69 ValueNs::EnumVariantId(it) => it.into(), 69 ValueNs::EnumVariantId(it) => it.into(),
70 }; 70 };
71 71
72 let mut ty = self.db.type_for_def(typable, Namespace::Values); 72 let mut ty = self.db.value_ty(typable);
73 if let Some(self_subst) = self_subst { 73 if let Some(self_subst) = self_subst {
74 ty = ty.subst(&self_subst); 74 ty = ty.subst(&self_subst);
75 } 75 }
76
77 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 76 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
78 let ty = ty.subst(&substs); 77 let ty = ty.subst(&substs);
79 Some(ty) 78 Some(ty)
@@ -143,24 +142,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
143 id: ExprOrPatId, 142 id: ExprOrPatId,
144 ) -> Option<(ValueNs, Option<Substs>)> { 143 ) -> Option<(ValueNs, Option<Substs>)> {
145 let trait_ = trait_ref.trait_; 144 let trait_ = trait_ref.trait_;
146 let item = trait_.items(self.db).iter().copied().find_map(|item| match item { 145 let item =
147 AssocItem::Function(func) => { 146 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id).into()).find_map(
148 if segment.name == func.name(self.db) { 147 |item| match item {
149 Some(AssocItem::Function(func)) 148 AssocItem::Function(func) => {
150 } else { 149 if segment.name == func.name(self.db) {
151 None 150 Some(AssocItem::Function(func))
152 } 151 } else {
153 } 152 None
153 }
154 }
154 155
155 AssocItem::Const(konst) => { 156 AssocItem::Const(konst) => {
156 if konst.name(self.db).map_or(false, |n| n == segment.name) { 157 if konst.name(self.db).map_or(false, |n| n == segment.name) {
157 Some(AssocItem::Const(konst)) 158 Some(AssocItem::Const(konst))
158 } else { 159 } else {
159 None 160 None
160 } 161 }
161 } 162 }
162 AssocItem::TypeAlias(_) => None, 163 AssocItem::TypeAlias(_) => None,
163 })?; 164 },
165 )?;
164 let def = match item { 166 let def = match item {
165 AssocItem::Function(f) => ValueNs::FunctionId(f.id), 167 AssocItem::Function(f) => ValueNs::FunctionId(f.id),
166 AssocItem::Const(c) => ValueNs::ConstId(c.id), 168 AssocItem::Const(c) => ValueNs::ConstId(c.id),
@@ -212,7 +214,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
212 .fill_with_params() 214 .fill_with_params()
213 .build(); 215 .build();
214 self.obligations.push(super::Obligation::Trait(TraitRef { 216 self.obligations.push(super::Obligation::Trait(TraitRef {
215 trait_: t, 217 trait_: t.id,
216 substs: trait_substs, 218 substs: trait_substs,
217 })); 219 }));
218 Some(substs) 220 Some(substs)
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 805a73ff5..709492d21 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -14,8 +14,8 @@ use hir_def::{
14 path::{GenericArg, PathSegment}, 14 path::{GenericArg, PathSegment},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, 17 AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule,
18 Lookup, StructId, VariantId, 18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
19}; 19};
20use ra_arena::map::ArenaMap; 20use ra_arena::map::ArenaMap;
21use ra_db::CrateId; 21use ra_db::CrateId;
@@ -29,24 +29,12 @@ use crate::{
29 ty::{ 29 ty::{
30 primitive::{FloatTy, IntTy}, 30 primitive::{FloatTy, IntTy},
31 utils::{all_super_traits, associated_type_by_name_including_super_traits}, 31 utils::{all_super_traits, associated_type_by_name_including_super_traits},
32 Adt,
33 }, 32 },
34 util::make_mut_slice, 33 util::make_mut_slice,
35 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, 34 Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait,
36 TypeAlias, Union, 35 TypeAlias, Union,
37}; 36};
38 37
39// FIXME: this is only really used in `type_for_def`, which contains a bunch of
40// impossible cases. Perhaps we should recombine `TypeableDef` and `Namespace`
41// into a `AsTypeDef`, `AsValueDef` enums?
42#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub enum Namespace {
44 Types,
45 Values,
46 // Note that only type inference uses this enum, and it doesn't care about macros.
47 // Macro,
48}
49
50impl Ty { 38impl Ty {
51 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { 39 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
52 match type_ref { 40 match type_ref {
@@ -172,7 +160,7 @@ impl Ty {
172 let segment = &remaining_segments[0]; 160 let segment = &remaining_segments[0];
173 let associated_ty = associated_type_by_name_including_super_traits( 161 let associated_ty = associated_type_by_name_including_super_traits(
174 db, 162 db,
175 trait_ref.trait_.id, 163 trait_ref.trait_,
176 &segment.name, 164 &segment.name,
177 ); 165 );
178 match associated_ty { 166 match associated_ty {
@@ -263,7 +251,7 @@ impl Ty {
263 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), 251 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_),
264 _ => None, 252 _ => None,
265 }); 253 });
266 let traits = traits_from_env.flat_map(|t| all_super_traits(db, t.id)).map(Trait::from); 254 let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)).map(Trait::from);
267 for t in traits { 255 for t in traits {
268 if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name) 256 if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name)
269 { 257 {
@@ -282,27 +270,15 @@ impl Ty {
282 db: &impl HirDatabase, 270 db: &impl HirDatabase,
283 resolver: &Resolver, 271 resolver: &Resolver,
284 segment: &PathSegment, 272 segment: &PathSegment,
285 typable: TypableDef, 273 typable: TyDefId,
286 ) -> Ty { 274 ) -> Ty {
287 let ty = db.type_for_def(typable, Namespace::Types); 275 let generic_def = match typable {
288 let substs = Ty::substs_from_path_segment(db, resolver, segment, typable); 276 TyDefId::BuiltinType(_) => None,
289 ty.subst(&substs) 277 TyDefId::AdtId(it) => Some(it.into()),
290 } 278 TyDefId::TypeAliasId(it) => Some(it.into()),
291
292 pub(super) fn substs_from_path_segment(
293 db: &impl HirDatabase,
294 resolver: &Resolver,
295 segment: &PathSegment,
296 resolved: TypableDef,
297 ) -> Substs {
298 let def_generic: Option<GenericDefId> = match resolved {
299 TypableDef::Function(func) => Some(func.id.into()),
300 TypableDef::Adt(adt) => Some(adt.into()),
301 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()),
302 TypableDef::TypeAlias(t) => Some(t.id.into()),
303 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None,
304 }; 279 };
305 substs_from_path_segment(db, resolver, segment, def_generic, false) 280 let substs = substs_from_path_segment(db, resolver, segment, generic_def, false);
281 db.ty(typable).subst(&substs)
306 } 282 }
307 283
308 /// Collect generic arguments from a path into a `Substs`. See also 284 /// Collect generic arguments from a path into a `Substs`. See also
@@ -311,17 +287,18 @@ impl Ty {
311 db: &impl HirDatabase, 287 db: &impl HirDatabase,
312 resolver: &Resolver, 288 resolver: &Resolver,
313 path: &Path, 289 path: &Path,
314 resolved: TypableDef, 290 // Note that we don't call `db.value_type(resolved)` here,
291 // `ValueTyDefId` is just a convenient way to pass generics and
292 // special-case enum variants
293 resolved: ValueTyDefId,
315 ) -> Substs { 294 ) -> Substs {
316 let last = path.segments.last().expect("path should have at least one segment"); 295 let last = path.segments.last().expect("path should have at least one segment");
317 let segment = match resolved { 296 let (segment, generic_def) = match resolved {
318 TypableDef::Function(_) 297 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
319 | TypableDef::Adt(_) 298 ValueTyDefId::StructId(it) => (last, Some(it.into())),
320 | TypableDef::Const(_) 299 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
321 | TypableDef::Static(_) 300 ValueTyDefId::StaticId(_) => (last, None),
322 | TypableDef::TypeAlias(_) 301 ValueTyDefId::EnumVariantId(var) => {
323 | TypableDef::BuiltinType(_) => last,
324 TypableDef::EnumVariant(_) => {
325 // the generic args for an enum variant may be either specified 302 // the generic args for an enum variant may be either specified
326 // on the segment referring to the enum, or on the segment 303 // on the segment referring to the enum, or on the segment
327 // referring to the variant. So `Option::<T>::None` and 304 // referring to the variant. So `Option::<T>::None` and
@@ -335,10 +312,10 @@ impl Ty {
335 // Option::None::<T> 312 // Option::None::<T>
336 last 313 last
337 }; 314 };
338 segment 315 (segment, Some(var.parent.into()))
339 } 316 }
340 }; 317 };
341 Ty::substs_from_path_segment(db, resolver, segment, resolved) 318 substs_from_path_segment(db, resolver, segment, generic_def, false)
342 } 319 }
343} 320}
344 321
@@ -423,7 +400,7 @@ impl TraitRef {
423 if let Some(self_ty) = explicit_self_ty { 400 if let Some(self_ty) = explicit_self_ty {
424 make_mut_slice(&mut substs.0)[0] = self_ty; 401 make_mut_slice(&mut substs.0)[0] = self_ty;
425 } 402 }
426 TraitRef { trait_: resolved, substs } 403 TraitRef { trait_: resolved.id, substs }
427 } 404 }
428 405
429 pub(crate) fn from_hir( 406 pub(crate) fn from_hir(
@@ -450,8 +427,8 @@ impl TraitRef {
450 substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param) 427 substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param)
451 } 428 }
452 429
453 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { 430 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef {
454 let substs = Substs::identity(&db.generic_params(trait_.id.into())); 431 let substs = Substs::identity(&db.generic_params(trait_.into()));
455 TraitRef { trait_, substs } 432 TraitRef { trait_, substs }
456 } 433 }
457 434
@@ -510,7 +487,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
510 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 487 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
511 .map(move |(name, type_ref)| { 488 .map(move |(name, type_ref)| {
512 let associated_ty = 489 let associated_ty =
513 associated_type_by_name_including_super_traits(db, trait_ref.trait_.id, &name); 490 associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name);
514 let associated_ty = match associated_ty { 491 let associated_ty = match associated_ty {
515 None => return GenericPredicate::Error, 492 None => return GenericPredicate::Error,
516 Some(t) => t, 493 Some(t) => t,
@@ -523,33 +500,6 @@ fn assoc_type_bindings_from_type_bound<'a>(
523 }) 500 })
524} 501}
525 502
526/// Build the declared type of an item. This depends on the namespace; e.g. for
527/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
528/// the constructor function `(usize) -> Foo` which lives in the values
529/// namespace.
530pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty {
531 match (def, ns) {
532 (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f),
533 (TypableDef::Adt(Adt::Struct(s)), Namespace::Values) => type_for_struct_constructor(db, s),
534 (TypableDef::Adt(adt), Namespace::Types) => type_for_adt(db, adt),
535 (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v),
536 (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t),
537 (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c),
538 (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c),
539 (TypableDef::BuiltinType(t), Namespace::Types) => type_for_builtin(t),
540
541 // 'error' cases:
542 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown,
543 (TypableDef::Adt(Adt::Union(_)), Namespace::Values) => Ty::Unknown,
544 (TypableDef::Adt(Adt::Enum(_)), Namespace::Values) => Ty::Unknown,
545 (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown,
546 (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown,
547 (TypableDef::Const(_), Namespace::Types) => Ty::Unknown,
548 (TypableDef::Static(_), Namespace::Types) => Ty::Unknown,
549 (TypableDef::BuiltinType(_), Namespace::Values) => Ty::Unknown,
550 }
551}
552
553/// Build the signature of a callable item (function, struct or enum variant). 503/// Build the signature of a callable item (function, struct or enum variant).
554pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { 504pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig {
555 match def { 505 match def {
@@ -648,24 +598,24 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig {
648 598
649/// Build the declared type of a function. This should not need to look at the 599/// Build the declared type of a function. This should not need to look at the
650/// function body. 600/// function body.
651fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 601fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty {
652 let generics = db.generic_params(def.id.into()); 602 let generics = db.generic_params(def.into());
653 let substs = Substs::identity(&generics); 603 let substs = Substs::identity(&generics);
654 Ty::apply(TypeCtor::FnDef(def.id.into()), substs) 604 Ty::apply(TypeCtor::FnDef(def.into()), substs)
655} 605}
656 606
657/// Build the declared type of a const. 607/// Build the declared type of a const.
658fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { 608fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty {
659 let data = db.const_data(def.id); 609 let data = db.const_data(def);
660 let resolver = def.id.resolver(db); 610 let resolver = def.resolver(db);
661 611
662 Ty::from_hir(db, &resolver, &data.type_ref) 612 Ty::from_hir(db, &resolver, &data.type_ref)
663} 613}
664 614
665/// Build the declared type of a static. 615/// Build the declared type of a static.
666fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { 616fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty {
667 let data = db.static_data(def.id); 617 let data = db.static_data(def);
668 let resolver = def.id.resolver(db); 618 let resolver = def.resolver(db);
669 619
670 Ty::from_hir(db, &resolver, &data.type_ref) 620 Ty::from_hir(db, &resolver, &data.type_ref)
671} 621}
@@ -689,19 +639,19 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig
689 .iter() 639 .iter()
690 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 640 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
691 .collect::<Vec<_>>(); 641 .collect::<Vec<_>>();
692 let ret = type_for_adt(db, Struct::from(def)); 642 let ret = type_for_adt(db, def.into());
693 FnSig::from_params_and_return(params, ret) 643 FnSig::from_params_and_return(params, ret)
694} 644}
695 645
696/// Build the type of a tuple struct constructor. 646/// Build the type of a tuple struct constructor.
697fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 647fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty {
698 let struct_data = db.struct_data(def.id.into()); 648 let struct_data = db.struct_data(def.into());
699 if struct_data.variant_data.is_unit() { 649 if struct_data.variant_data.is_unit() {
700 return type_for_adt(db, def); // Unit struct 650 return type_for_adt(db, def.into()); // Unit struct
701 } 651 }
702 let generics = db.generic_params(def.id.into()); 652 let generics = db.generic_params(def.into());
703 let substs = Substs::identity(&generics); 653 let substs = Substs::identity(&generics);
704 Ty::apply(TypeCtor::FnDef(def.id.into()), substs) 654 Ty::apply(TypeCtor::FnDef(def.into()), substs)
705} 655}
706 656
707fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { 657fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig {
@@ -715,34 +665,33 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId
715 .collect::<Vec<_>>(); 665 .collect::<Vec<_>>();
716 let generics = db.generic_params(def.parent.into()); 666 let generics = db.generic_params(def.parent.into());
717 let substs = Substs::identity(&generics); 667 let substs = Substs::identity(&generics);
718 let ret = type_for_adt(db, Enum::from(def.parent)).subst(&substs); 668 let ret = type_for_adt(db, def.parent.into()).subst(&substs);
719 FnSig::from_params_and_return(params, ret) 669 FnSig::from_params_and_return(params, ret)
720} 670}
721 671
722/// Build the type of a tuple enum variant constructor. 672/// Build the type of a tuple enum variant constructor.
723fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { 673fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty {
724 let var_data = def.variant_data(db); 674 let enum_data = db.enum_data(def.parent);
675 let var_data = &enum_data.variants[def.local_id].variant_data;
725 if var_data.is_unit() { 676 if var_data.is_unit() {
726 return type_for_adt(db, def.parent_enum(db)); // Unit variant 677 return type_for_adt(db, def.parent.into()); // Unit variant
727 } 678 }
728 let generics = db.generic_params(def.parent_enum(db).id.into()); 679 let generics = db.generic_params(def.parent.into());
729 let substs = Substs::identity(&generics); 680 let substs = Substs::identity(&generics);
730 Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) 681 Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs)
731} 682}
732 683
733fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { 684fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty {
734 let adt = adt.into(); 685 let generics = db.generic_params(adt.into());
735 let adt_id: AdtId = adt.into(); 686 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics))
736 let generics = db.generic_params(adt_id.into());
737 Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics))
738} 687}
739 688
740fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 689fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty {
741 let generics = db.generic_params(t.id.into()); 690 let generics = db.generic_params(t.into());
742 let resolver = t.id.resolver(db); 691 let resolver = t.resolver(db);
743 let type_ref = t.type_ref(db); 692 let type_ref = &db.type_alias_data(t).type_ref;
744 let substs = Substs::identity(&generics); 693 let substs = Substs::identity(&generics);
745 let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); 694 let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error));
746 inner.subst(&substs) 695 inner.subst(&substs)
747} 696}
748 697
@@ -809,3 +758,42 @@ impl From<CallableDef> for GenericDefId {
809 } 758 }
810 } 759 }
811} 760}
761
762#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
763pub enum TyDefId {
764 BuiltinType(BuiltinType),
765 AdtId(AdtId),
766 TypeAliasId(TypeAliasId),
767}
768impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId);
769
770#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
771pub enum ValueTyDefId {
772 FunctionId(FunctionId),
773 StructId(StructId),
774 EnumVariantId(EnumVariantId),
775 ConstId(ConstId),
776 StaticId(StaticId),
777}
778impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId);
779
780/// Build the declared type of an item. This depends on the namespace; e.g. for
781/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
782/// the constructor function `(usize) -> Foo` which lives in the values
783/// namespace.
784pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty {
785 match def {
786 TyDefId::BuiltinType(it) => type_for_builtin(it),
787 TyDefId::AdtId(it) => type_for_adt(db, it),
788 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
789 }
790}
791pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty {
792 match def {
793 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
794 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
795 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
796 ValueTyDefId::ConstId(it) => type_for_const(db, it),
797 ValueTyDefId::StaticId(it) => type_for_static(db, it),
798 }
799}
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 9988570e8..f1bc638ee 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -68,7 +68,7 @@ impl CrateImplBlocks {
68 if let Some(tr) = 68 if let Some(tr) =
69 TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) 69 TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))
70 { 70 {
71 res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); 71 res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id);
72 } 72 }
73 } 73 }
74 None => { 74 None => {
@@ -249,13 +249,11 @@ fn iterate_trait_method_candidates<T>(
249 let traits_from_env = env 249 let traits_from_env = env
250 .trait_predicates_for_self_ty(&ty.value) 250 .trait_predicates_for_self_ty(&ty.value)
251 .map(|tr| tr.trait_) 251 .map(|tr| tr.trait_)
252 .flat_map(|t| all_super_traits(db, t.id)) 252 .flat_map(|t| all_super_traits(db, t));
253 .map(Trait::from); 253 let traits =
254 let traits = inherent_trait 254 inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter());
255 .chain(traits_from_env)
256 .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from));
257 'traits: for t in traits { 255 'traits: for t in traits {
258 let data = db.trait_data(t.id); 256 let data = db.trait_data(t);
259 257
260 // we'll be lazy about checking whether the type implements the 258 // we'll be lazy about checking whether the type implements the
261 // trait, but if we find out it doesn't, we'll skip the rest of the 259 // trait, but if we find out it doesn't, we'll skip the rest of the
@@ -330,7 +328,7 @@ pub(crate) fn implements_trait(
330 db: &impl HirDatabase, 328 db: &impl HirDatabase,
331 resolver: &Resolver, 329 resolver: &Resolver,
332 krate: Crate, 330 krate: Crate,
333 trait_: Trait, 331 trait_: TraitId,
334) -> bool { 332) -> bool {
335 if ty.value.inherent_trait() == Some(trait_) { 333 if ty.value.inherent_trait() == Some(trait_) {
336 // FIXME this is a bit of a hack, since Chalk should say the same thing 334 // FIXME this is a bit of a hack, since Chalk should say the same thing
@@ -373,11 +371,11 @@ impl Ty {
373fn generic_implements_goal( 371fn generic_implements_goal(
374 db: &impl HirDatabase, 372 db: &impl HirDatabase,
375 env: Arc<TraitEnvironment>, 373 env: Arc<TraitEnvironment>,
376 trait_: Trait, 374 trait_: TraitId,
377 self_ty: Canonical<Ty>, 375 self_ty: Canonical<Ty>,
378) -> Canonical<InEnvironment<super::Obligation>> { 376) -> Canonical<InEnvironment<super::Obligation>> {
379 let num_vars = self_ty.num_vars; 377 let num_vars = self_ty.num_vars;
380 let substs = super::Substs::build_for_def(db, trait_.id) 378 let substs = super::Substs::build_for_def(db, trait_)
381 .push(self_ty.value) 379 .push(self_ty.value)
382 .fill_with_bound_vars(num_vars as u32) 380 .fill_with_bound_vars(num_vars as u32)
383 .build(); 381 .build();
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index 2eeb03099..a91c2476b 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/traits.rs
@@ -2,14 +2,15 @@
2use std::sync::{Arc, Mutex}; 2use std::sync::{Arc, Mutex};
3 3
4use chalk_ir::{cast::Cast, family::ChalkIr}; 4use chalk_ir::{cast::Cast, family::ChalkIr};
5use hir_def::DefWithBodyId; 5use hir_def::{expr::ExprId, DefWithBodyId};
6use log::debug; 6use log::debug;
7use ra_db::{impl_intern_key, salsa}; 7use ra_db::{impl_intern_key, salsa};
8use ra_prof::profile; 8use ra_prof::profile;
9use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
10 10
11use crate::{db::HirDatabase, Crate, ImplBlock, Trait, TypeAlias};
12
11use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
12use crate::{db::HirDatabase, expr::ExprId, Crate, ImplBlock, Trait, TypeAlias};
13 14
14use self::chalk::{from_chalk, ToChalk}; 15use self::chalk::{from_chalk, ToChalk};
15 16
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 78f4b3e27..4b0f4f56c 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -9,7 +9,9 @@ use chalk_ir::{
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11 11
12use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId}; 12use hir_def::{
13 lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId,
14};
13use hir_expand::name; 15use hir_expand::name;
14 16
15use ra_db::salsa::{InternId, InternKey}; 17use ra_db::salsa::{InternId, InternKey};
@@ -19,7 +21,7 @@ use crate::{
19 db::HirDatabase, 21 db::HirDatabase,
20 ty::display::HirDisplay, 22 ty::display::HirDisplay,
21 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, 23 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
22 Crate, ImplBlock, Trait, TypeAlias, 24 Crate, ImplBlock, TypeAlias,
23}; 25};
24 26
25/// This represents a trait whose name we could not resolve. 27/// This represents a trait whose name we could not resolve.
@@ -167,15 +169,15 @@ impl ToChalk for TraitRef {
167 } 169 }
168} 170}
169 171
170impl ToChalk for Trait { 172impl ToChalk for TraitId {
171 type Chalk = chalk_ir::TraitId; 173 type Chalk = chalk_ir::TraitId;
172 174
173 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { 175 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId {
174 chalk_ir::TraitId(id_to_chalk(self.id)) 176 chalk_ir::TraitId(id_to_chalk(self))
175 } 177 }
176 178
177 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait { 179 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId {
178 Trait { id: id_from_chalk(trait_id.0) } 180 id_from_chalk(trait_id.0)
179 } 181 }
180} 182}
181 183
@@ -443,10 +445,10 @@ where
443 if trait_id == UNKNOWN_TRAIT { 445 if trait_id == UNKNOWN_TRAIT {
444 return Vec::new(); 446 return Vec::new();
445 } 447 }
446 let trait_: Trait = from_chalk(self.db, trait_id); 448 let trait_: TraitId = from_chalk(self.db, trait_id);
447 let mut result: Vec<_> = self 449 let mut result: Vec<_> = self
448 .db 450 .db
449 .impls_for_trait(self.krate, trait_) 451 .impls_for_trait(self.krate, trait_.into())
450 .iter() 452 .iter()
451 .copied() 453 .copied()
452 .map(Impl::ImplBlock) 454 .map(Impl::ImplBlock)
@@ -459,7 +461,7 @@ where
459 [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() 461 [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
460 { 462 {
461 if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) { 463 if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) {
462 if trait_.id == actual_trait { 464 if trait_ == actual_trait {
463 let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait }; 465 let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait };
464 result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db)); 466 result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db));
465 } 467 }
@@ -516,7 +518,7 @@ pub(crate) fn associated_ty_data_query(
516 where_clauses: vec![], 518 where_clauses: vec![],
517 }; 519 };
518 let datum = AssociatedTyDatum { 520 let datum = AssociatedTyDatum {
519 trait_id: Trait::from(trait_).to_chalk(db), 521 trait_id: trait_.to_chalk(db),
520 id, 522 id,
521 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), 523 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()),
522 binders: make_binders(bound_data, generic_params.count_params_including_parent()), 524 binders: make_binders(bound_data, generic_params.count_params_including_parent()),
@@ -548,29 +550,23 @@ pub(crate) fn trait_datum_query(
548 associated_ty_ids: vec![], 550 associated_ty_ids: vec![],
549 }); 551 });
550 } 552 }
551 let trait_: Trait = from_chalk(db, trait_id); 553 let trait_: TraitId = from_chalk(db, trait_id);
552 debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); 554 let trait_data = db.trait_data(trait_);
553 let generic_params = db.generic_params(trait_.id.into()); 555 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
556 let generic_params = db.generic_params(trait_.into());
554 let bound_vars = Substs::bound_vars(&generic_params); 557 let bound_vars = Substs::bound_vars(&generic_params);
555 let flags = chalk_rust_ir::TraitFlags { 558 let flags = chalk_rust_ir::TraitFlags {
556 auto: trait_.is_auto(db), 559 auto: trait_data.auto,
557 upstream: trait_.module(db).krate() != krate, 560 upstream: trait_.module(db).krate != krate.crate_id,
558 non_enumerable: true, 561 non_enumerable: true,
559 coinductive: false, // only relevant for Chalk testing 562 coinductive: false, // only relevant for Chalk testing
560 // FIXME set these flags correctly 563 // FIXME set these flags correctly
561 marker: false, 564 marker: false,
562 fundamental: false, 565 fundamental: false,
563 }; 566 };
564 let where_clauses = convert_where_clauses(db, trait_.id.into(), &bound_vars); 567 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
565 let associated_ty_ids = trait_ 568 let associated_ty_ids =
566 .items(db) 569 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
567 .into_iter()
568 .filter_map(|trait_item| match trait_item {
569 crate::AssocItem::TypeAlias(type_alias) => Some(type_alias.id),
570 _ => None,
571 })
572 .map(|type_alias| type_alias.to_chalk(db))
573 .collect();
574 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses }; 570 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
575 let trait_datum = TraitDatum { 571 let trait_datum = TraitDatum {
576 id: trait_id, 572 id: trait_id,
@@ -661,7 +657,7 @@ fn impl_block_datum(
661 }; 657 };
662 658
663 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses }; 659 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses };
664 let trait_data = db.trait_data(trait_.id); 660 let trait_data = db.trait_data(trait_);
665 let associated_ty_value_ids = impl_block 661 let associated_ty_value_ids = impl_block
666 .items(db) 662 .items(db)
667 .into_iter() 663 .into_iter()
@@ -785,12 +781,12 @@ fn type_alias_associated_ty_value(
785 .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved 781 .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved
786 .trait_; 782 .trait_;
787 let assoc_ty = db 783 let assoc_ty = db
788 .trait_data(trait_.id) 784 .trait_data(trait_)
789 .associated_type_by_name(&type_alias.name(db)) 785 .associated_type_by_name(&type_alias.name(db))
790 .expect("assoc ty value should not exist"); // validated when building the impl data as well 786 .expect("assoc ty value should not exist"); // validated when building the impl data as well
791 let generic_params = db.generic_params(impl_block.id.into()); 787 let generic_params = db.generic_params(impl_block.id.into());
792 let bound_vars = Substs::bound_vars(&generic_params); 788 let bound_vars = Substs::bound_vars(&generic_params);
793 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); 789 let ty = db.ty(type_alias.id.into()).subst(&bound_vars);
794 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; 790 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
795 let value = chalk_rust_ir::AssociatedTyValue { 791 let value = chalk_rust_ir::AssociatedTyValue {
796 impl_id, 792 impl_id,
diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs
index 52994b9e3..80ffceb4b 100644
--- a/crates/ra_hir/src/ty/utils.rs
+++ b/crates/ra_hir/src/ty/utils.rs
@@ -33,7 +33,7 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
33 33
34/// Returns an iterator over the whole super trait hierarchy (including the 34/// Returns an iterator over the whole super trait hierarchy (including the
35/// trait itself). 35/// trait itself).
36pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> { 36pub(super) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
37 // we need to take care a bit here to avoid infinite loops in case of cycles 37 // we need to take care a bit here to avoid infinite loops in case of cycles
38 // (i.e. if we have `trait A: B; trait B: A;`) 38 // (i.e. if we have `trait A: B; trait B: A;`)
39 let mut result = vec![trait_]; 39 let mut result = vec![trait_];
@@ -52,7 +52,7 @@ pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<Tr
52 result 52 result
53} 53}
54 54
55pub(crate) fn associated_type_by_name_including_super_traits( 55pub(super) fn associated_type_by_name_including_super_traits(
56 db: &impl DefDatabase, 56 db: &impl DefDatabase,
57 trait_: TraitId, 57 trait_: TraitId,
58 name: &Name, 58 name: &Name,