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.rs108
1 files changed, 83 insertions, 25 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index d4d896673..2751ab3ab 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -32,17 +32,20 @@ use rustc_hash::FxHashMap;
32 32
33use test_utils::tested_by; 33use test_utils::tested_by;
34 34
35use ra_syntax::ast::NameOwner;
36
35use crate::{ 37use crate::{
36 Function, Struct, StructField, Enum, EnumVariant, Path, Name, 38 Function, Struct, StructField, Enum, EnumVariant, Path, Name,
39 Const,
37 FnSignature, ModuleDef, AdtDef, 40 FnSignature, ModuleDef, AdtDef,
38 HirDatabase, 41 HirDatabase,
39 type_ref::{TypeRef, Mutability}, 42 type_ref::{TypeRef, Mutability},
40 name::KnownName, 43 name::{KnownName, AsName},
41 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, 44 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
42 generics::GenericParams, 45 generics::GenericParams,
43 path::GenericArg, 46 path::GenericArg,
44 adt::VariantDef, 47 adt::VariantDef,
45 resolve::{Resolver, Resolution}, nameres::Namespace 48 resolve::{Resolver, Resolution, PathResult}, nameres::Namespace
46}; 49};
47 50
48/// The ID of a type variable. 51/// The ID of a type variable.
@@ -370,7 +373,7 @@ impl Ty {
370 } 373 }
371 374
372 // Resolve the path (in type namespace) 375 // Resolve the path (in type namespace)
373 let resolution = resolver.resolve_path(db, path).take_types(); 376 let resolution = resolver.resolve_path(db, path).into_per_ns().take_types();
374 377
375 let def = match resolution { 378 let def = match resolution {
376 Some(Resolution::Def(def)) => def, 379 Some(Resolution::Def(def)) => def,
@@ -678,6 +681,19 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
678 Ty::FnDef { def: def.into(), sig, name, substs } 681 Ty::FnDef { def: def.into(), sig, name, substs }
679} 682}
680 683
684fn type_for_const(db: &impl HirDatabase, resolver: &Resolver, def: Const) -> Ty {
685 let node = def.source(db).1;
686
687 let tr = node
688 .type_ref()
689 .map(TypeRef::from_ast)
690 .as_ref()
691 .map(|tr| Ty::from_hir(db, resolver, tr))
692 .unwrap_or_else(|| Ty::Unknown);
693
694 tr
695}
696
681/// Compute the type of a tuple struct constructor. 697/// Compute the type of a tuple struct constructor.
682fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 698fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
683 let var_data = def.variant_data(db); 699 let var_data = def.variant_data(db);
@@ -1172,15 +1188,56 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1172 } 1188 }
1173 1189
1174 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> { 1190 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> {
1175 let resolved = resolver.resolve_path(self.db, &path).take_values()?; 1191 let resolved = resolver.resolve_path(self.db, &path);
1192
1193 let (resolved, segment_index) = match resolved {
1194 PathResult::FullyResolved(def) => (def.take_values()?, None),
1195 PathResult::PartiallyResolved(def, index) => (def.take_types()?, Some(index)),
1196 };
1197
1176 match resolved { 1198 match resolved {
1177 Resolution::Def(def) => { 1199 Resolution::Def(def) => {
1178 let typable: Option<TypableDef> = def.into(); 1200 let typable: Option<TypableDef> = def.into();
1179 let typable = typable?; 1201 let typable = typable?;
1180 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 1202
1181 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs); 1203 if let Some(segment_index) = segment_index {
1182 let ty = self.insert_type_vars(ty); 1204 let ty = self.db.type_for_def(typable, Namespace::Types);
1183 Some(ty) 1205 // TODO: What to do if segment_index is not the last segment
1206 // in the path
1207 let segment = &path.segments[segment_index];
1208
1209 // Attempt to find an impl_item for the type which has a name matching
1210 // the current segment
1211 let ty = ty.iterate_impl_items(self.db, |item| match item {
1212 crate::ImplItem::Method(func) => {
1213 let sig = func.signature(self.db);
1214 if segment.name == *sig.name() {
1215 return Some(type_for_fn(self.db, func));
1216 }
1217 None
1218 }
1219 crate::ImplItem::Const(c) => {
1220 let node = c.source(self.db).1;
1221
1222 if let Some(name) = node.name().map(|n| n.as_name()) {
1223 if segment.name == name {
1224 return Some(type_for_const(self.db, resolver, c));
1225 }
1226 }
1227
1228 None
1229 }
1230
1231 // TODO: Resolve associated types
1232 crate::ImplItem::Type(_) => None,
1233 });
1234 ty
1235 } else {
1236 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
1237 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
1238 let ty = self.insert_type_vars(ty);
1239 Some(ty)
1240 }
1184 } 1241 }
1185 Resolution::LocalBinding(pat) => { 1242 Resolution::LocalBinding(pat) => {
1186 let ty = self.type_of_pat.get(pat)?; 1243 let ty = self.type_of_pat.get(pat)?;
@@ -1204,23 +1261,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1204 None => return (Ty::Unknown, None), 1261 None => return (Ty::Unknown, None),
1205 }; 1262 };
1206 let resolver = &self.resolver; 1263 let resolver = &self.resolver;
1207 let typable: Option<TypableDef> = match resolver.resolve_path(self.db, &path).take_types() { 1264 let typable: Option<TypableDef> =
1208 Some(Resolution::Def(def)) => def.into(), 1265 match resolver.resolve_path(self.db, &path).into_per_ns().take_types() {
1209 Some(Resolution::LocalBinding(..)) => { 1266 Some(Resolution::Def(def)) => def.into(),
1210 // this cannot happen 1267 Some(Resolution::LocalBinding(..)) => {
1211 log::error!("path resolved to local binding in type ns"); 1268 // this cannot happen
1212 return (Ty::Unknown, None); 1269 log::error!("path resolved to local binding in type ns");
1213 } 1270 return (Ty::Unknown, None);
1214 Some(Resolution::GenericParam(..)) => { 1271 }
1215 // generic params can't be used in struct literals 1272 Some(Resolution::GenericParam(..)) => {
1216 return (Ty::Unknown, None); 1273 // generic params can't be used in struct literals
1217 } 1274 return (Ty::Unknown, None);
1218 Some(Resolution::SelfType(..)) => { 1275 }
1219 // TODO this is allowed in an impl for a struct, handle this 1276 Some(Resolution::SelfType(..)) => {
1220 return (Ty::Unknown, None); 1277 // TODO this is allowed in an impl for a struct, handle this
1221 } 1278 return (Ty::Unknown, None);
1222 None => return (Ty::Unknown, None), 1279 }
1223 }; 1280 None => return (Ty::Unknown, None),
1281 };
1224 let def = match typable { 1282 let def = match typable {
1225 None => return (Ty::Unknown, None), 1283 None => return (Ty::Unknown, None),
1226 Some(it) => it, 1284 Some(it) => it,