about summary refs log tree commit diff
diff options
context:
space:
mode:
authoraustaras <austaras@outlook.com>2023-11-26 20:46:02 +0800
committeraustaras <austaras@outlook.com>2023-11-26 21:00:11 +0800
commit2411f1383ab8f7798527206e764c54bdac467637 (patch)
tree26651c1a15fe0dfc16d7989404590da333e00ef0
parent79ec2c584b990a533f7fde685a51d45d2a896103 (diff)
downloadrust-2411f1383ab8f7798527206e764c54bdac467637.tar.gz
rust-2411f1383ab8f7798527206e764c54bdac467637.zip
fix variant resolve for type alias
-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 3d5ed1f93c0..8262edec22c 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 04005311b67..9f5b59b239a 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 0f5a3e1752c..5d7bab09c26 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 8af6cce98f6..b2e8274a84d 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#"