Unnamed repository; edit this file 'description' to name the repository.
fix variant resolve for type alias
austaras 2023-11-26
parent 79ec2c5 · commit 2411f13
-rw-r--r--crates/hir-ty/src/infer.rs21
-rw-r--r--crates/hir-ty/src/lower.rs2
-rw-r--r--crates/hir-ty/src/tests/patterns.rs24
-rw-r--r--crates/ide-completion/src/tests/pattern.rs29
4 files changed, 62 insertions, 14 deletions
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 3d5ed1f93c..8262edec22 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -1152,20 +1152,15 @@ impl<'a> InferenceContext<'a> {
(ty, variant)
}
TypeNs::TypeAliasId(it) => {
- let container = it.lookup(self.db.upcast()).container;
- let parent_subst = match container {
- ItemContainerId::TraitId(id) => {
- let subst = TyBuilder::subst_for_def(self.db, id, None)
- .fill_with_inference_vars(&mut self.table)
- .build();
- Some(subst)
- }
- // Type aliases do not exist in impls.
- _ => None,
+ let resolved_seg = match unresolved {
+ None => path.segments().last().unwrap(),
+ Some(n) => path.segments().get(path.segments().len() - n - 1).unwrap(),
};
- let ty = TyBuilder::def_ty(self.db, it.into(), parent_subst)
- .fill_with_inference_vars(&mut self.table)
- .build();
+ let substs =
+ ctx.substs_from_path_segment(resolved_seg, Some(it.into()), true, None);
+ let ty = self.db.ty(it.into());
+ let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
+
self.resolve_variant_on_alias(ty, unresolved, mod_path)
}
TypeNs::AdtSelfType(_) => {
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 04005311b6..9f5b59b239 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -768,7 +768,7 @@ impl<'a> TyLoweringContext<'a> {
}
}
- fn substs_from_path_segment(
+ pub(super) fn substs_from_path_segment(
&self,
segment: PathSegment<'_>,
def: Option<GenericDefId>,
diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs
index 0f5a3e1752..5d7bab09c2 100644
--- a/crates/hir-ty/src/tests/patterns.rs
+++ b/crates/hir-ty/src/tests/patterns.rs
@@ -1129,3 +1129,27 @@ fn foo() {
"#,
);
}
+
+#[test]
+fn generic_alias() {
+ check_types(
+ r#"
+type Wrap<T> = T;
+
+enum X {
+ A { cool: u32, stuff: u32 },
+ B,
+}
+
+fn main() {
+ let wrapped = Wrap::<X>::A {
+ cool: 100,
+ stuff: 100,
+ };
+
+ if let Wrap::<X>::A { cool, ..} = &wrapped {}
+ //^^^^ &u32
+}
+"#,
+ );
+}
diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs
index 8af6cce98f..b2e8274a84 100644
--- a/crates/ide-completion/src/tests/pattern.rs
+++ b/crates/ide-completion/src/tests/pattern.rs
@@ -355,6 +355,35 @@ fn outer(Foo { bar$0 }: Foo) {}
}
#[test]
+fn completes_in_record_field_pat_with_generic_type_alias() {
+ check_empty(
+ r#"
+type Wrap<T> = T;
+
+enum X {
+ A { cool: u32, stuff: u32 },
+ B,
+}
+
+fn main() {
+ let wrapped = Wrap::<X>::A {
+ cool: 100,
+ stuff: 100,
+ };
+
+ if let Wrap::<X>::A { $0 } = &wrapped {};
+}
+"#,
+ expect![[r#"
+ fd cool u32
+ fd stuff u32
+ kw mut
+ kw ref
+ "#]],
+ )
+}
+
+#[test]
fn completes_in_fn_param() {
check_empty(
r#"