diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-26 18:07:21 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-26 18:07:21 +0000 |
commit | 141fca60061d85494fcb719a4c8237eaf6c7c134 (patch) | |
tree | 6a7abab05196f1cd3bc2185ab7f02ac89e413c69 /crates/ra_hir | |
parent | 3b0fc8ac6224e8ab8848de791011add6a149b9d4 (diff) | |
parent | 4e415a269e2d821f31963c05843517c6fde0132d (diff) |
Merge #2419
2419: Remove ns-polymorphic type_for_def r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 25 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/path.rs | 46 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 204 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/utils.rs | 4 |
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; | |||
19 | use std::{fmt, iter, mem}; | 19 | use std::{fmt, iter, mem}; |
20 | 20 | ||
21 | use hir_def::{ | 21 | use 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 | }; |
25 | use ra_db::{impl_intern_key, salsa}; | 25 | use ra_db::{impl_intern_key, salsa}; |
26 | 26 | ||
27 | use crate::{ | 27 | use 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 | }; |
31 | use display::{HirDisplay, HirFormatter}; | 33 | use display::{HirDisplay, HirFormatter}; |
32 | 34 | ||
@@ -35,8 +37,8 @@ pub(crate) use infer::{infer_query, InferTy, InferenceResult}; | |||
35 | pub use lower::CallableDef; | 37 | pub use lower::CallableDef; |
36 | pub(crate) use lower::{ | 38 | pub(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 | }; |
41 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 43 | pub(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)] |
446 | pub struct TraitRef { | 448 | pub 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 | ||
36 | use super::{ | 36 | use 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 | }; |
41 | use crate::{ | 41 | use 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 | ||
49 | macro_rules! ty_app { | 49 | macro_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 | ||
8 | use crate::{ | 8 | use 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 | }; |
20 | use ra_arena::map::ArenaMap; | 20 | use ra_arena::map::ArenaMap; |
21 | use ra_db::CrateId; | 21 | use 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)] | ||
43 | pub 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 | |||
50 | impl Ty { | 38 | impl 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. | ||
530 | pub(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). |
554 | pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { | 504 | pub(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. |
651 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | 601 | fn 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. |
658 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { | 608 | fn 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. |
666 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { | 616 | fn 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. |
697 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | 647 | fn 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 | ||
707 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { | 657 | fn 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. |
723 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | 673 | fn 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 | ||
733 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { | 684 | fn 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 | ||
740 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { | 689 | fn 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)] | ||
763 | pub enum TyDefId { | ||
764 | BuiltinType(BuiltinType), | ||
765 | AdtId(AdtId), | ||
766 | TypeAliasId(TypeAliasId), | ||
767 | } | ||
768 | impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId); | ||
769 | |||
770 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
771 | pub enum ValueTyDefId { | ||
772 | FunctionId(FunctionId), | ||
773 | StructId(StructId), | ||
774 | EnumVariantId(EnumVariantId), | ||
775 | ConstId(ConstId), | ||
776 | StaticId(StaticId), | ||
777 | } | ||
778 | impl_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. | ||
784 | pub(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 | } | ||
791 | pub(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 { | |||
373 | fn generic_implements_goal( | 371 | fn 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 @@ | |||
2 | use std::sync::{Arc, Mutex}; | 2 | use std::sync::{Arc, Mutex}; |
3 | 3 | ||
4 | use chalk_ir::{cast::Cast, family::ChalkIr}; | 4 | use chalk_ir::{cast::Cast, family::ChalkIr}; |
5 | use hir_def::DefWithBodyId; | 5 | use hir_def::{expr::ExprId, DefWithBodyId}; |
6 | use log::debug; | 6 | use log::debug; |
7 | use ra_db::{impl_intern_key, salsa}; | 7 | use ra_db::{impl_intern_key, salsa}; |
8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
9 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
10 | 10 | ||
11 | use crate::{db::HirDatabase, Crate, ImplBlock, Trait, TypeAlias}; | ||
12 | |||
11 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; | 13 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; |
12 | use crate::{db::HirDatabase, expr::ExprId, Crate, ImplBlock, Trait, TypeAlias}; | ||
13 | 14 | ||
14 | use self::chalk::{from_chalk, ToChalk}; | 15 | use 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 | }; |
10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; | 10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; |
11 | 11 | ||
12 | use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId}; | 12 | use hir_def::{ |
13 | lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, | ||
14 | }; | ||
13 | use hir_expand::name; | 15 | use hir_expand::name; |
14 | 16 | ||
15 | use ra_db::salsa::{InternId, InternKey}; | 17 | use 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 | ||
170 | impl ToChalk for Trait { | 172 | impl 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). |
36 | pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> { | 36 | pub(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 | ||
55 | pub(crate) fn associated_type_by_name_including_super_traits( | 55 | pub(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, |