Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/path.rs')
| -rw-r--r-- | crates/hir-ty/src/infer/path.rs | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index fcfe1a3b5c..49fb78f67a 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -40,33 +40,7 @@ impl InferenceContext<'_> { } fn resolve_value_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<ValuePathResolution> { - let (value, self_subst) = if let Some(type_ref) = path.type_anchor() { - let last = path.segments().last()?; - - // Don't use `self.make_ty()` here as we need `orig_ns`. - let ctx = - crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into()); - let (ty, orig_ns) = ctx.lower_ty_ext(type_ref); - let ty = self.table.insert_type_vars(ty); - let ty = self.table.normalize_associated_types_in(ty); - - let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); - let (ty, _) = ctx.lower_ty_relative_path(ty, orig_ns, remaining_segments_for_ty); - let ty = self.table.insert_type_vars(ty); - let ty = self.table.normalize_associated_types_in(ty); - self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))? - } else { - // FIXME: report error, unresolved first path segment - let value_or_partial = - self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?; - - match value_or_partial { - ResolveValueResult::ValueNs(it, _) => (it, None), - ResolveValueResult::Partial(def, remaining_index, _) => self - .resolve_assoc_item(def, path, remaining_index, id) - .map(|(it, substs)| (it, Some(substs)))?, - } - }; + let (value, self_subst) = self.resolve_value_path_inner(path, id)?; let value_def = match value { ValueNs::LocalBinding(pat) => match self.result.type_of_binding.get(pat) { @@ -144,6 +118,41 @@ impl InferenceContext<'_> { Some(ValuePathResolution::GenericDef(value_def, generic_def, substs)) } + pub(super) fn resolve_value_path_inner( + &mut self, + path: &Path, + id: ExprOrPatId, + ) -> Option<(ValueNs, Option<chalk_ir::Substitution<Interner>>)> { + let (value, self_subst) = if let Some(type_ref) = path.type_anchor() { + let last = path.segments().last()?; + + // Don't use `self.make_ty()` here as we need `orig_ns`. + let ctx = + crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into()); + let (ty, orig_ns) = ctx.lower_ty_ext(type_ref); + let ty = self.table.insert_type_vars(ty); + let ty = self.table.normalize_associated_types_in(ty); + + let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); + let (ty, _) = ctx.lower_ty_relative_path(ty, orig_ns, remaining_segments_for_ty); + let ty = self.table.insert_type_vars(ty); + let ty = self.table.normalize_associated_types_in(ty); + self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))? + } else { + // FIXME: report error, unresolved first path segment + let value_or_partial = + self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?; + + match value_or_partial { + ResolveValueResult::ValueNs(it, _) => (it, None), + ResolveValueResult::Partial(def, remaining_index, _) => self + .resolve_assoc_item(def, path, remaining_index, id) + .map(|(it, substs)| (it, Some(substs)))?, + } + }; + Some((value, self_subst)) + } + fn add_required_obligations_for_value_path(&mut self, def: GenericDefId, subst: &Substitution) { let predicates = self.db.generic_predicates(def); for predicate in predicates.iter() { |