aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs86
1 files changed, 53 insertions, 33 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 6ee9080d3..13080b5aa 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -360,46 +360,66 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
360 // we might have resolved into a type for which 360 // we might have resolved into a type for which
361 // we may find some associated item starting at the 361 // we may find some associated item starting at the
362 // path.segment pointed to by `remaining_index´ 362 // path.segment pointed to by `remaining_index´
363 let resolved = 363 let mut resolved =
364 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; 364 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? };
365 365
366 let remaining_index = remaining_index.unwrap_or(path.segments.len());
367
368 // resolve intermediate segments
369 for segment in &path.segments[remaining_index..] {
370 let ty = match resolved {
371 Resolution::Def(def) => {
372 let typable: Option<TypableDef> = def.into();
373 let typable = typable?;
374
375 let substs =
376 Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable);
377 self.db.type_for_def(typable, Namespace::Types).apply_substs(substs)
378 }
379 Resolution::LocalBinding(_) => {
380 // can't have a local binding in an associated item path
381 return None;
382 }
383 Resolution::GenericParam(..) => {
384 // TODO associated item of generic param
385 return None;
386 }
387 Resolution::SelfType(_) => {
388 // TODO associated item of self type
389 return None;
390 }
391 };
392
393 // Attempt to find an impl_item for the type which has a name matching
394 // the current segment
395 log::debug!("looking for path segment: {:?}", segment);
396 let item = ty.iterate_impl_items(self.db, |item| match item {
397 crate::ImplItem::Method(func) => {
398 let sig = func.signature(self.db);
399 if segment.name == *sig.name() {
400 return Some(func);
401 }
402 None
403 }
404
405 // TODO: Resolve associated const
406 crate::ImplItem::Const(_) => None,
407
408 // TODO: Resolve associated types
409 crate::ImplItem::Type(_) => None,
410 })?;
411 resolved = Resolution::Def(item.into());
412 }
413
366 match resolved { 414 match resolved {
367 Resolution::Def(def) => { 415 Resolution::Def(def) => {
368 let typable: Option<TypableDef> = def.into(); 416 let typable: Option<TypableDef> = def.into();
369 let typable = typable?; 417 let typable = typable?;
370 418
371 if let Some(remaining_index) = remaining_index { 419 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
372 let ty = self.db.type_for_def(typable, Namespace::Types); 420 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
373 // TODO: Keep resolving the segments 421 let ty = self.insert_type_vars(ty);
374 // if we have more segments to process 422 Some(ty)
375 let segment = &path.segments[remaining_index];
376
377 log::debug!("looking for path segment: {:?}", segment);
378
379 // Attempt to find an impl_item for the type which has a name matching
380 // the current segment
381 let ty = ty.iterate_impl_items(self.db, |item| match item {
382 crate::ImplItem::Method(func) => {
383 let sig = func.signature(self.db);
384 if segment.name == *sig.name() {
385 return Some(func.ty(self.db));
386 }
387 None
388 }
389
390 // TODO: Resolve associated const
391 crate::ImplItem::Const(_) => None,
392
393 // TODO: Resolve associated types
394 crate::ImplItem::Type(_) => None,
395 });
396 ty
397 } else {
398 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
399 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
400 let ty = self.insert_type_vars(ty);
401 Some(ty)
402 }
403 } 423 }
404 Resolution::LocalBinding(pat) => { 424 Resolution::LocalBinding(pat) => {
405 let ty = self.type_of_pat.get(pat)?; 425 let ty = self.type_of_pat.get(pat)?;