aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs66
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;
17use std::sync::Arc; 17use std::sync::Arc;
18use std::{fmt, iter, mem}; 18use std::{fmt, iter, mem};
19 19
20use hir_def::{generics::GenericParams, AdtId, GenericDefId}; 20use hir_def::{
21 generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup,
22 TraitId, TypeAliasId,
23};
21use ra_db::{impl_intern_key, salsa}; 24use ra_db::{impl_intern_key, salsa};
22 25
23use crate::{ 26use 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};
27use display::{HirDisplay, HirFormatter}; 30use 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)]
214pub struct ProjectionTy { 220pub struct ProjectionTy {
215 pub associated_ty: TypeAlias, 221 pub associated_ty: TypeAliasId,
216 pub parameters: Substs, 222 pub parameters: Substs,
217} 223}
218 224
219impl ProjectionTy { 225impl 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 }