diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 3cbcbd1d0..388530f31 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -17,12 +17,15 @@ use std::ops::Deref; | |||
17 | use std::sync::Arc; | 17 | use std::sync::Arc; |
18 | use std::{fmt, iter, mem}; | 18 | use std::{fmt, iter, mem}; |
19 | 19 | ||
20 | use hir_def::{generics::GenericParams, AdtId, GenericDefId}; | 20 | use hir_def::{ |
21 | generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, | ||
22 | TraitId, TypeAliasId, | ||
23 | }; | ||
21 | use ra_db::{impl_intern_key, salsa}; | 24 | use ra_db::{impl_intern_key, salsa}; |
22 | 25 | ||
23 | use crate::{ | 26 | use crate::{ |
24 | db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, IntTy, | 27 | db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, |
25 | Mutability, Name, Trait, TypeAlias, Uncertain, | 28 | Name, Trait, Uncertain, |
26 | }; | 29 | }; |
27 | use display::{HirDisplay, HirFormatter}; | 30 | use display::{HirDisplay, HirFormatter}; |
28 | 31 | ||
@@ -107,13 +110,13 @@ pub enum TypeCtor { | |||
107 | /// when we have tried to normalize a projection like `T::Item` but | 110 | /// when we have tried to normalize a projection like `T::Item` but |
108 | /// couldn't find a better representation. In that case, we generate | 111 | /// couldn't find a better representation. In that case, we generate |
109 | /// an **application type** like `(Iterator::Item)<T>`. | 112 | /// an **application type** like `(Iterator::Item)<T>`. |
110 | AssociatedType(TypeAlias), | 113 | AssociatedType(TypeAliasId), |
111 | 114 | ||
112 | /// The type of a specific closure. | 115 | /// The type of a specific closure. |
113 | /// | 116 | /// |
114 | /// The closure signature is stored in a `FnPtr` type in the first type | 117 | /// The closure signature is stored in a `FnPtr` type in the first type |
115 | /// parameter. | 118 | /// parameter. |
116 | Closure { def: DefWithBody, expr: ExprId }, | 119 | Closure { def: DefWithBodyId, expr: ExprId }, |
117 | } | 120 | } |
118 | 121 | ||
119 | /// This exists just for Chalk, because Chalk just has a single `StructId` where | 122 | /// This exists just for Chalk, because Chalk just has a single `StructId` where |
@@ -147,7 +150,7 @@ impl TypeCtor { | |||
147 | generic_params.count_params_including_parent() | 150 | generic_params.count_params_including_parent() |
148 | } | 151 | } |
149 | TypeCtor::AssociatedType(type_alias) => { | 152 | TypeCtor::AssociatedType(type_alias) => { |
150 | let generic_params = db.generic_params(type_alias.id.into()); | 153 | let generic_params = db.generic_params(type_alias.into()); |
151 | generic_params.count_params_including_parent() | 154 | generic_params.count_params_including_parent() |
152 | } | 155 | } |
153 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, | 156 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, |
@@ -169,10 +172,13 @@ impl TypeCtor { | |||
169 | | TypeCtor::Ref(_) | 172 | | TypeCtor::Ref(_) |
170 | | TypeCtor::FnPtr { .. } | 173 | | TypeCtor::FnPtr { .. } |
171 | | TypeCtor::Tuple { .. } => None, | 174 | | TypeCtor::Tuple { .. } => None, |
172 | TypeCtor::Closure { def, .. } => def.krate(db), | 175 | // Closure's krate is irrelevant for coherence I would think? |
176 | TypeCtor::Closure { .. } => None, | ||
173 | TypeCtor::Adt(adt) => adt.krate(db), | 177 | TypeCtor::Adt(adt) => adt.krate(db), |
174 | TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), | 178 | TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), |
175 | TypeCtor::AssociatedType(type_alias) => type_alias.krate(db), | 179 | TypeCtor::AssociatedType(type_alias) => { |
180 | Some(type_alias.lookup(db).module(db).krate.into()) | ||
181 | } | ||
176 | } | 182 | } |
177 | } | 183 | } |
178 | 184 | ||
@@ -193,7 +199,7 @@ impl TypeCtor { | |||
193 | | TypeCtor::Closure { .. } => None, | 199 | | TypeCtor::Closure { .. } => None, |
194 | TypeCtor::Adt(adt) => Some(adt.into()), | 200 | TypeCtor::Adt(adt) => Some(adt.into()), |
195 | TypeCtor::FnDef(callable) => Some(callable.into()), | 201 | TypeCtor::FnDef(callable) => Some(callable.into()), |
196 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.id.into()), | 202 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), |
197 | } | 203 | } |
198 | } | 204 | } |
199 | } | 205 | } |
@@ -212,18 +218,19 @@ pub struct ApplicationTy { | |||
212 | /// trait and all its parameters are fully known. | 218 | /// trait and all its parameters are fully known. |
213 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 219 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
214 | pub struct ProjectionTy { | 220 | pub struct ProjectionTy { |
215 | pub associated_ty: TypeAlias, | 221 | pub associated_ty: TypeAliasId, |
216 | pub parameters: Substs, | 222 | pub parameters: Substs, |
217 | } | 223 | } |
218 | 224 | ||
219 | impl ProjectionTy { | 225 | impl ProjectionTy { |
220 | pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef { | 226 | pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef { |
221 | TraitRef { | 227 | TraitRef { trait_: self.trait_(db).into(), substs: self.parameters.clone() } |
222 | trait_: self | 228 | } |
223 | .associated_ty | 229 | |
224 | .parent_trait(db) | 230 | fn trait_(&self, db: &impl HirDatabase) -> TraitId { |
225 | .expect("projection ty without parent trait"), | 231 | match self.associated_ty.lookup(db).container { |
226 | substs: self.parameters.clone(), | 232 | ContainerId::TraitId(it) => it, |
233 | _ => panic!("projection ty without parent trait"), | ||
227 | } | 234 | } |
228 | } | 235 | } |
229 | } | 236 | } |
@@ -895,11 +902,12 @@ impl HirDisplay for ApplicationTy { | |||
895 | } | 902 | } |
896 | } | 903 | } |
897 | TypeCtor::AssociatedType(type_alias) => { | 904 | TypeCtor::AssociatedType(type_alias) => { |
898 | let trait_name = type_alias | 905 | let trait_ = match type_alias.lookup(f.db).container { |
899 | .parent_trait(f.db) | 906 | ContainerId::TraitId(it) => it, |
900 | .and_then(|t| t.name(f.db)) | 907 | _ => panic!("not an associated type"), |
901 | .unwrap_or_else(Name::missing); | 908 | }; |
902 | let name = type_alias.name(f.db); | 909 | let trait_name = f.db.trait_data(trait_).name.clone().unwrap_or_else(Name::missing); |
910 | let name = f.db.type_alias_data(type_alias).name.clone(); | ||
903 | write!(f, "{}::{}", trait_name, name)?; | 911 | write!(f, "{}::{}", trait_name, name)?; |
904 | if self.parameters.len() > 0 { | 912 | if self.parameters.len() > 0 { |
905 | write!(f, "<")?; | 913 | write!(f, "<")?; |
@@ -926,18 +934,15 @@ impl HirDisplay for ProjectionTy { | |||
926 | return write!(f, "…"); | 934 | return write!(f, "…"); |
927 | } | 935 | } |
928 | 936 | ||
929 | let trait_name = self | 937 | let trait_name = |
930 | .associated_ty | 938 | f.db.trait_data(self.trait_(f.db)).name.clone().unwrap_or_else(Name::missing); |
931 | .parent_trait(f.db) | ||
932 | .and_then(|t| t.name(f.db)) | ||
933 | .unwrap_or_else(Name::missing); | ||
934 | write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; | 939 | write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; |
935 | if self.parameters.len() > 1 { | 940 | if self.parameters.len() > 1 { |
936 | write!(f, "<")?; | 941 | write!(f, "<")?; |
937 | f.write_joined(&self.parameters[1..], ", ")?; | 942 | f.write_joined(&self.parameters[1..], ", ")?; |
938 | write!(f, ">")?; | 943 | write!(f, ">")?; |
939 | } | 944 | } |
940 | write!(f, ">::{}", self.associated_ty.name(f.db))?; | 945 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; |
941 | Ok(()) | 946 | Ok(()) |
942 | } | 947 | } |
943 | } | 948 | } |
@@ -1000,7 +1005,10 @@ impl HirDisplay for Ty { | |||
1000 | write!(f, "<")?; | 1005 | write!(f, "<")?; |
1001 | angle_open = true; | 1006 | angle_open = true; |
1002 | } | 1007 | } |
1003 | let name = projection_pred.projection_ty.associated_ty.name(f.db); | 1008 | let name = |
1009 | f.db.type_alias_data(projection_pred.projection_ty.associated_ty) | ||
1010 | .name | ||
1011 | .clone(); | ||
1004 | write!(f, "{} = ", name)?; | 1012 | write!(f, "{} = ", name)?; |
1005 | projection_pred.ty.hir_fmt(f)?; | 1013 | projection_pred.ty.hir_fmt(f)?; |
1006 | } | 1014 | } |
@@ -1076,7 +1084,7 @@ impl HirDisplay for GenericPredicate { | |||
1076 | write!( | 1084 | write!( |
1077 | f, | 1085 | f, |
1078 | ">::{} = {}", | 1086 | ">::{} = {}", |
1079 | projection_pred.projection_ty.associated_ty.name(f.db), | 1087 | f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, |
1080 | projection_pred.ty.display(f.db) | 1088 | projection_pred.ty.display(f.db) |
1081 | )?; | 1089 | )?; |
1082 | } | 1090 | } |