about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKirill Bulatov <mail4score@gmail.com>2022-01-03 01:34:33 +0200
committerKirill Bulatov <mail4score@gmail.com>2022-01-03 01:34:33 +0200
commit03291db8013b3ad75b610669538c0c8cf6639d14 (patch)
treeb19fb653b41dea608a5a4752691758816781848e
parente1099aaa5749afe3d6dc8f196ef50ffc07fe3d68 (diff)
downloadrust-03291db8013b3ad75b610669538c0c8cf6639d14.tar.gz
rust-03291db8013b3ad75b610669538c0c8cf6639d14.zip
Allow adding partially resolved types
-rw-r--r--crates/hir_ty/src/display.rs22
-rw-r--r--crates/ide_assists/src/handlers/add_explicit_type.rs29
2 files changed, 47 insertions, 4 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index cd898a45d21..95d1550afc3 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -567,7 +567,27 @@ impl HirDisplay for Ty {
                     };
                     if !parameters_to_write.is_empty() {
                         write!(f, "<")?;
-                        f.write_joined(parameters_to_write, ", ")?;
+
+                        if f.display_target.is_source_code() {
+                            let mut first = true;
+                            for generic_arg in parameters_to_write {
+                                if !first {
+                                    write!(f, ", ")?;
+                                }
+                                first = false;
+
+                                if generic_arg.ty(Interner).map(|ty| ty.kind(Interner))
+                                    == Some(&TyKind::Error)
+                                {
+                                    write!(f, "_")?;
+                                } else {
+                                    generic_arg.hir_fmt(f)?;
+                                }
+                            }
+                        } else {
+                            f.write_joined(parameters_to_write, ", ")?;
+                        }
+
                         write!(f, ">")?;
                     }
                 }
diff --git a/crates/ide_assists/src/handlers/add_explicit_type.rs b/crates/ide_assists/src/handlers/add_explicit_type.rs
index 169bb0cbf4f..d7e1be900ff 100644
--- a/crates/ide_assists/src/handlers/add_explicit_type.rs
+++ b/crates/ide_assists/src/handlers/add_explicit_type.rs
@@ -60,8 +60,8 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
     }
     .adjusted();
 
-    // Unresolved or unnameable types can't be annotated
-    if ty.contains_unknown() || ty.is_closure() {
+    // Fully unresolved or unnameable types can't be annotated
+    if (ty.contains_unknown() && ty.type_arguments().count() == 0) || ty.is_closure() {
         cov_mark::hit!(add_explicit_type_not_applicable_if_ty_not_inferred);
         return None;
     }
@@ -139,12 +139,35 @@ fn f() {
     }
 
     #[test]
-    fn add_explicit_type_not_applicable_unresolved() {
+    fn add_explicit_type_not_applicable_for_fully_unresolved() {
         cov_mark::check!(add_explicit_type_not_applicable_if_ty_not_inferred);
         check_assist_not_applicable(add_explicit_type, r#"fn f() { let a$0 = None; }"#);
     }
 
     #[test]
+    fn add_explicit_type_applicable_for_partially_unresolved() {
+        check_assist(
+            add_explicit_type,
+            r#"
+        struct Vec<T, V> { t: T, v: V }
+        impl<T> Vec<T, Vec<ZZZ, i32>> {
+            fn new() -> Self {
+                panic!()
+            }
+        }
+        fn f() { let a$0 = Vec::new(); }"#,
+            r#"
+        struct Vec<T, V> { t: T, v: V }
+        impl<T> Vec<T, Vec<ZZZ, i32>> {
+            fn new() -> Self {
+                panic!()
+            }
+        }
+        fn f() { let a: Vec<_, Vec<_, i32>> = Vec::new(); }"#,
+        );
+    }
+
+    #[test]
     fn add_explicit_type_not_applicable_closure_expr() {
         check_assist_not_applicable(add_explicit_type, r#"fn f() { let a$0 = || {}; }"#);
     }