diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 6b3485264..d6ff968f0 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -27,9 +27,8 @@ use std::{iter, mem, ops::Deref, sync::Arc}; | |||
27 | 27 | ||
28 | use base_db::salsa; | 28 | use base_db::salsa; |
29 | use hir_def::{ | 29 | use hir_def::{ |
30 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, DefWithBodyId, | 30 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, |
31 | FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, | 31 | GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, |
32 | TypeParamId, | ||
33 | }; | 32 | }; |
34 | use itertools::Itertools; | 33 | use itertools::Itertools; |
35 | 34 | ||
@@ -53,7 +52,10 @@ pub use crate::traits::chalk::Interner; | |||
53 | 52 | ||
54 | pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; | 53 | pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; |
55 | pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | 54 | pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; |
56 | pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>; | 55 | pub type FnDefId = chalk_ir::FnDefId<Interner>; |
56 | pub type ClosureId = chalk_ir::ClosureId<Interner>; | ||
57 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | ||
58 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | ||
57 | 59 | ||
58 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
59 | pub enum Lifetime { | 61 | pub enum Lifetime { |
@@ -195,7 +197,7 @@ pub enum TyKind { | |||
195 | /// | 197 | /// |
196 | /// The closure signature is stored in a `FnPtr` type in the first type | 198 | /// The closure signature is stored in a `FnPtr` type in the first type |
197 | /// parameter. | 199 | /// parameter. |
198 | Closure(DefWithBodyId, ExprId, Substs), | 200 | Closure(ClosureId, Substs), |
199 | 201 | ||
200 | /// Represents a foreign type declared in external blocks. | 202 | /// Represents a foreign type declared in external blocks. |
201 | ForeignType(ForeignDefId), | 203 | ForeignType(ForeignDefId), |
@@ -220,7 +222,7 @@ pub enum TyKind { | |||
220 | /// {}` when we're type-checking the body of that function. In this | 222 | /// {}` when we're type-checking the body of that function. In this |
221 | /// situation, we know this stands for *some* type, but don't know the exact | 223 | /// situation, we know this stands for *some* type, but don't know the exact |
222 | /// type. | 224 | /// type. |
223 | Placeholder(TypeParamId), | 225 | Placeholder(PlaceholderIndex), |
224 | 226 | ||
225 | /// A bound type variable. This is used in various places: when representing | 227 | /// A bound type variable. This is used in various places: when representing |
226 | /// some polymorphic type like the type of function `fn f<T>`, the type | 228 | /// some polymorphic type like the type of function `fn f<T>`, the type |
@@ -310,11 +312,14 @@ impl Substs { | |||
310 | } | 312 | } |
311 | 313 | ||
312 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 314 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
313 | pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs { | 315 | pub(crate) fn type_params_for_generics( |
316 | db: &dyn HirDatabase, | ||
317 | generic_params: &Generics, | ||
318 | ) -> Substs { | ||
314 | Substs( | 319 | Substs( |
315 | generic_params | 320 | generic_params |
316 | .iter() | 321 | .iter() |
317 | .map(|(id, _)| TyKind::Placeholder(id).intern(&Interner)) | 322 | .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)) |
318 | .collect(), | 323 | .collect(), |
319 | ) | 324 | ) |
320 | } | 325 | } |
@@ -322,7 +327,7 @@ impl Substs { | |||
322 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 327 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
323 | pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { | 328 | pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { |
324 | let params = generics(db.upcast(), def.into()); | 329 | let params = generics(db.upcast(), def.into()); |
325 | Substs::type_params_for_generics(¶ms) | 330 | Substs::type_params_for_generics(db, ¶ms) |
326 | } | 331 | } |
327 | 332 | ||
328 | /// Return Substs that replace each parameter by a bound variable. | 333 | /// Return Substs that replace each parameter by a bound variable. |
@@ -734,9 +739,7 @@ impl Ty { | |||
734 | ty_id == ty_id2 | 739 | ty_id == ty_id2 |
735 | } | 740 | } |
736 | (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | 741 | (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2, |
737 | (TyKind::Closure(def, expr, _), TyKind::Closure(def2, expr2, _)) => { | 742 | (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2, |
738 | expr == expr2 && def == def2 | ||
739 | } | ||
740 | (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..)) | 743 | (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..)) |
741 | | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => { | 744 | | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => { |
742 | mutability == mutability2 | 745 | mutability == mutability2 |
@@ -873,8 +876,8 @@ impl Ty { | |||
873 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 876 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
874 | match self.interned(&Interner) { | 877 | match self.interned(&Interner) { |
875 | TyKind::OpaqueType(opaque_ty_id, ..) => { | 878 | TyKind::OpaqueType(opaque_ty_id, ..) => { |
876 | match opaque_ty_id { | 879 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { |
877 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 880 | ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { |
878 | let krate = def.module(db.upcast()).krate(); | 881 | let krate = def.module(db.upcast()).krate(); |
879 | if let Some(future_trait) = db | 882 | if let Some(future_trait) = db |
880 | .lang_item(krate, "future_trait".into()) | 883 | .lang_item(krate, "future_trait".into()) |
@@ -892,12 +895,13 @@ impl Ty { | |||
892 | None | 895 | None |
893 | } | 896 | } |
894 | } | 897 | } |
895 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | 898 | ImplTraitId::ReturnTypeImplTrait(..) => None, |
896 | } | 899 | } |
897 | } | 900 | } |
898 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | 901 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
899 | let predicates = match opaque_ty.opaque_ty_id { | 902 | let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into()) |
900 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 903 | { |
904 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
901 | db.return_type_impl_traits(func).map(|it| { | 905 | db.return_type_impl_traits(func).map(|it| { |
902 | let data = (*it) | 906 | let data = (*it) |
903 | .as_ref() | 907 | .as_ref() |
@@ -906,18 +910,19 @@ impl Ty { | |||
906 | }) | 910 | }) |
907 | } | 911 | } |
908 | // It always has an parameter for Future::Output type. | 912 | // It always has an parameter for Future::Output type. |
909 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), | 913 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), |
910 | }; | 914 | }; |
911 | 915 | ||
912 | predicates.map(|it| it.value) | 916 | predicates.map(|it| it.value) |
913 | } | 917 | } |
914 | TyKind::Placeholder(id) => { | 918 | TyKind::Placeholder(idx) => { |
919 | let id = from_placeholder_idx(db, *idx); | ||
915 | let generic_params = db.generic_params(id.parent); | 920 | let generic_params = db.generic_params(id.parent); |
916 | let param_data = &generic_params.types[id.local_id]; | 921 | let param_data = &generic_params.types[id.local_id]; |
917 | match param_data.provenance { | 922 | match param_data.provenance { |
918 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { | 923 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { |
919 | let predicates = db | 924 | let predicates = db |
920 | .generic_predicates_for_param(*id) | 925 | .generic_predicates_for_param(id) |
921 | .into_iter() | 926 | .into_iter() |
922 | .map(|pred| pred.value.clone()) | 927 | .map(|pred| pred.value.clone()) |
923 | .collect_vec(); | 928 | .collect_vec(); |
@@ -1120,7 +1125,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> { | |||
1120 | } | 1125 | } |
1121 | 1126 | ||
1122 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 1127 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
1123 | pub enum OpaqueTyId { | 1128 | pub enum ImplTraitId { |
1124 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | 1129 | ReturnTypeImplTrait(hir_def::FunctionId, u16), |
1125 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), | 1130 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), |
1126 | } | 1131 | } |
@@ -1150,3 +1155,17 @@ pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { | |||
1150 | pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { | 1155 | pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { |
1151 | salsa::InternKey::from_intern_id(id.0) | 1156 | salsa::InternKey::from_intern_id(id.0) |
1152 | } | 1157 | } |
1158 | |||
1159 | pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { | ||
1160 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
1161 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
1162 | db.lookup_intern_type_param_id(interned_id) | ||
1163 | } | ||
1164 | |||
1165 | pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { | ||
1166 | let interned_id = db.intern_type_param_id(id); | ||
1167 | PlaceholderIndex { | ||
1168 | ui: chalk_ir::UniverseIndex::ROOT, | ||
1169 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), | ||
1170 | } | ||
1171 | } | ||