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.rs52
1 files changed, 46 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 1a3e1994f..ae595c16d 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -37,7 +37,7 @@ use crate::{
37 FnSignature, ModuleDef, AdtDef, 37 FnSignature, ModuleDef, AdtDef,
38 HirDatabase, 38 HirDatabase,
39 type_ref::{TypeRef, Mutability}, 39 type_ref::{TypeRef, Mutability},
40 name::KnownName, 40 name::{KnownName},
41 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, 41 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
42 generics::GenericParams, 42 generics::GenericParams,
43 path::{ GenericArgs, GenericArg}, 43 path::{ GenericArgs, GenericArg},
@@ -1166,15 +1166,55 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1166 } 1166 }
1167 1167
1168 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> { 1168 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> {
1169 let resolved = resolver.resolve_path(self.db, &path).take_values()?; 1169 let resolved = resolver.resolve_path_segments(self.db, &path);
1170
1171 let (def, remaining_index) = resolved.into_inner();
1172
1173 // if the remaining_index is None, we expect the path
1174 // to be fully resolved, in this case we continue with
1175 // the default by attempting to `take_values´ from the resolution.
1176 // Otherwise the path was partially resolved, which means
1177 // we might have resolved into a type for which
1178 // we may find some associated item starting at the
1179 // path.segment pointed to by `remaining_index´
1180 let resolved =
1181 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? };
1182
1170 match resolved { 1183 match resolved {
1171 Resolution::Def(def) => { 1184 Resolution::Def(def) => {
1172 let typable: Option<TypableDef> = def.into(); 1185 let typable: Option<TypableDef> = def.into();
1173 let typable = typable?; 1186 let typable = typable?;
1174 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 1187
1175 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs); 1188 if let Some(remaining_index) = remaining_index {
1176 let ty = self.insert_type_vars(ty); 1189 let ty = self.db.type_for_def(typable, Namespace::Types);
1177 Some(ty) 1190 // TODO: Keep resolving the segments
1191 // if we have more segments to process
1192 let segment = &path.segments[remaining_index];
1193
1194 // Attempt to find an impl_item for the type which has a name matching
1195 // the current segment
1196 let ty = ty.iterate_impl_items(self.db, |item| match item {
1197 crate::ImplItem::Method(func) => {
1198 let sig = func.signature(self.db);
1199 if segment.name == *sig.name() {
1200 return Some(type_for_fn(self.db, func));
1201 }
1202 None
1203 }
1204
1205 // TODO: Resolve associated const
1206 crate::ImplItem::Const(_) => None,
1207
1208 // TODO: Resolve associated types
1209 crate::ImplItem::Type(_) => None,
1210 });
1211 ty
1212 } else {
1213 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
1214 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
1215 let ty = self.insert_type_vars(ty);
1216 Some(ty)
1217 }
1178 } 1218 }
1179 Resolution::LocalBinding(pat) => { 1219 Resolution::LocalBinding(pat) => {
1180 let ty = self.type_of_pat.get(pat)?; 1220 let ty = self.type_of_pat.get(pat)?;