Skip to content

Commit 6447d48

Browse files
committed
Normalize type anchor type before resolving the rest of value paths
1 parent 8aef04f commit 6447d48

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

crates/hir-ty/src/infer/path.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,18 @@ impl<'a> InferenceContext<'a> {
3030

3131
fn resolve_value_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<Ty> {
3232
let (value, self_subst) = if let Some(type_ref) = path.type_anchor() {
33-
let Some(last) = path.segments().last() else { return None };
34-
let ty = self.make_ty(type_ref);
35-
let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1);
33+
let last = path.segments().last()?;
34+
35+
// Don't use `self.make_ty()` here as we need `orig_ns`.
3636
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
37-
let (ty, _) = ctx.lower_ty_relative_path(ty, None, remaining_segments_for_ty);
37+
let (ty, orig_ns) = ctx.lower_ty_ext(type_ref);
38+
let ty = self.table.insert_type_vars(ty);
39+
let ty = self.table.normalize_associated_types_in(ty);
40+
41+
let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1);
42+
let (ty, _) = ctx.lower_ty_relative_path(ty, orig_ns, remaining_segments_for_ty);
43+
let ty = self.table.insert_type_vars(ty);
44+
let ty = self.table.normalize_associated_types_in(ty);
3845
self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))?
3946
} else {
4047
// FIXME: report error, unresolved first path segment
@@ -169,7 +176,7 @@ impl<'a> InferenceContext<'a> {
169176
) -> Option<(ValueNs, Substitution)> {
170177
let trait_ = trait_ref.hir_trait_id();
171178
let item =
172-
self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| {
179+
self.db.trait_data(trait_).items.iter().map(|(_name, id)| *id).find_map(|item| {
173180
match item {
174181
AssocItemId::FunctionId(func) => {
175182
if segment.name == &self.db.function_data(func).name {
@@ -288,7 +295,7 @@ impl<'a> InferenceContext<'a> {
288295
name: &Name,
289296
id: ExprOrPatId,
290297
) -> Option<(ValueNs, Substitution)> {
291-
let ty = self.resolve_ty_shallow(ty);
298+
let ty = self.resolve_ty_shallow(&ty);
292299
let (enum_id, subst) = match ty.as_adt() {
293300
Some((AdtId::EnumId(e), subst)) => (e, subst),
294301
_ => return None,

crates/hir-ty/src/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl ImplTraitLoweringState {
103103
#[derive(Debug)]
104104
pub struct TyLoweringContext<'a> {
105105
pub db: &'a dyn HirDatabase,
106-
pub resolver: &'a Resolver,
106+
resolver: &'a Resolver,
107107
in_binders: DebruijnIndex,
108108
/// Note: Conceptually, it's thinkable that we could be in a location where
109109
/// some type params should be represented as placeholders, and others

crates/hir-ty/src/tests/traits.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4239,6 +4239,26 @@ impl Trait for () {
42394239
type Assoc = E;
42404240
42414241
fn f() {
4242+
let a = Self::Assoc::Unit;
4243+
// ^ E
4244+
let a = <Self>::Assoc::Unit;
4245+
// ^ E
4246+
let a = <Self::Assoc>::Unit;
4247+
// ^ E
4248+
let a = <<Self>::Assoc>::Unit;
4249+
// ^ E
4250+
4251+
// should be `Copy` but we don't track ownership anyway.
4252+
let value = E::Unit;
4253+
if let Self::Assoc::Unit = value {}
4254+
// ^^^^^^^^^^^^^^^^^ E
4255+
if let <Self>::Assoc::Unit = value {}
4256+
// ^^^^^^^^^^^^^^^^^^^ E
4257+
if let <Self::Assoc>::Unit = value {}
4258+
// ^^^^^^^^^^^^^^^^^^^ E
4259+
if let <<Self>::Assoc>::Unit = value {}
4260+
// ^^^^^^^^^^^^^^^^^^^^^ E
4261+
42424262
let x = 42;
42434263
let a = Self::Assoc::Struct { x };
42444264
// ^ E

0 commit comments

Comments
 (0)