about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-05 08:25:58 +0000
committerbors <bors@rust-lang.org>2023-10-05 08:25:58 +0000
commit695c612489d54aa81f9817076819273bdc8aa64b (patch)
tree0b2780371683e615285d352d1fa3cd2d46b64e6e
parentb57658d9a9fbc3ca34c1eb13ef41ef0e5e4b49d0 (diff)
parentfc258de5a3ae7a40b8625b862295d5bca00a8c7b (diff)
downloadrust-695c612489d54aa81f9817076819273bdc8aa64b.tar.gz
rust-695c612489d54aa81f9817076819273bdc8aa64b.zip
Auto merge of #15641 - alibektas:15598/fix_into_to_from, r=Veykril
fix: preceding QualifiedPathType for into_to_from assist

fixes #15598
-rw-r--r--crates/ide-assists/src/handlers/into_to_qualified_from.rs74
1 files changed, 71 insertions, 3 deletions
diff --git a/crates/ide-assists/src/handlers/into_to_qualified_from.rs b/crates/ide-assists/src/handlers/into_to_qualified_from.rs
index 663df266b6f..965e4aa786e 100644
--- a/crates/ide-assists/src/handlers/into_to_qualified_from.rs
+++ b/crates/ide-assists/src/handlers/into_to_qualified_from.rs
@@ -52,9 +52,13 @@ pub(crate) fn into_to_qualified_from(acc: &mut Assists, ctx: &AssistContext<'_>)
         == FamousDefs(sema, scope.krate()).core_convert_Into()?
     {
         let type_call = sema.type_of_expr(&method_call.clone().into())?;
-        let type_call_disp =
-            type_call.adjusted().display_source_code(db, scope.module().into(), true).ok()?;
+        let adjusted_tc = type_call.adjusted();
 
+        if adjusted_tc.contains_unknown() {
+            return None;
+        }
+
+        let sc = adjusted_tc.display_source_code(db, scope.module().into(), true).ok()?;
         acc.add(
             AssistId("into_to_qualified_from", AssistKind::Generate),
             "Convert `into` to fully qualified `from`",
@@ -62,7 +66,11 @@ pub(crate) fn into_to_qualified_from(acc: &mut Assists, ctx: &AssistContext<'_>)
             |edit| {
                 edit.replace(
                     method_call.syntax().text_range(),
-                    format!("{}::from({})", type_call_disp, receiver),
+                    if sc.chars().all(|c| c.is_alphanumeric() || c == ':') {
+                        format!("{}::from({})", sc, receiver)
+                    } else {
+                        format!("<{}>::from({})", sc, receiver)
+                    },
                 );
             },
         );
@@ -202,4 +210,64 @@ fn main() -> () {
 }"#,
         )
     }
+
+    #[test]
+    fn preceding_type_qualifier() {
+        check_assist(
+            into_to_qualified_from,
+            r#"
+//- minicore: from
+impl From<(i32,i32)> for [i32;2] {
+    fn from(value: (i32,i32)) -> Self {
+        [value.0, value.1]
+    }
+}
+
+fn tuple_to_array() -> [i32; 2] {
+    (0,1).in$0to()
+}"#,
+            r#"
+impl From<(i32,i32)> for [i32;2] {
+    fn from(value: (i32,i32)) -> Self {
+        [value.0, value.1]
+    }
+}
+
+fn tuple_to_array() -> [i32; 2] {
+    <[i32; 2]>::from((0,1))
+}"#,
+        )
+    }
+
+    #[test]
+    fn type_with_gens() {
+        check_assist(
+            into_to_qualified_from,
+            r#"
+//- minicore: from
+struct StructA<Gen>(Gen);
+
+impl From<i32> for StructA<i32> {
+    fn from(value: i32) -> Self {
+        StructA(value + 1)
+    }
+}
+
+fn main() -> () {
+    let a: StructA<i32> = 3.in$0to();
+}"#,
+            r#"
+struct StructA<Gen>(Gen);
+
+impl From<i32> for StructA<i32> {
+    fn from(value: i32) -> Self {
+        StructA(value + 1)
+    }
+}
+
+fn main() -> () {
+    let a: StructA<i32> = <StructA<i32>>::from(3);
+}"#,
+        )
+    }
 }