From 8ad536f2d12846684fed51dd95d95a4c56e5be62 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Fri, 15 Sep 2023 23:26:45 +0200 Subject: [PATCH 1/4] Make path start with a QualifiedPathType --- .../src/handlers/into_to_qualified_from.rs | 84 +++++++++++++++++-- 1 file changed, 75 insertions(+), 9 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..32d30e6b18d 100644 --- a/crates/ide-assists/src/handlers/into_to_qualified_from.rs +++ b/crates/ide-assists/src/handlers/into_to_qualified_from.rs @@ -52,18 +52,24 @@ 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.is_unknown() && adjusted_tc.contains_unknown() { + return None; + } + + let qualified_from = format!( + "<{}>::from({})", + adjusted_tc.display_source_code(db, scope.module().into(), true).ok()?, + receiver + ); acc.add( AssistId("into_to_qualified_from", AssistKind::Generate), "Convert `into` to fully qualified `from`", nameref.syntax().text_range(), |edit| { - edit.replace( - method_call.syntax().text_range(), - format!("{}::from({})", type_call_disp, receiver), - ); + edit.replace(method_call.syntax().text_range(), qualified_from); }, ); } @@ -106,7 +112,7 @@ fn from(a: A) -> Self { fn main() -> () { let a: A = A; - let b: B = B::from(a); + let b: B = ::from(a); }"#, ) } @@ -154,7 +160,7 @@ fn from(a: A) -> Self { fn main() -> () { let a: A = A; - let b: B = B::from(a); + let b: B = ::from(a); }"#, ) } @@ -198,7 +204,67 @@ fn from(a: A) -> Self { fn main() -> () { let a: A = A; - let b: C::B = C::B::from(a); + let b: C::B = ::from(a); +}"#, + ) + } + + #[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); + +impl From for StructA { + fn from(value: i32) -> Self { + StructA(value + 1) + } +} + +fn main() -> () { + let a: StructA = 3.in$0to(); +}"#, + r#" +struct StructA(Gen); + +impl From for StructA { + fn from(value: i32) -> Self { + StructA(value + 1) + } +} + +fn main() -> () { + let a: StructA = >::from(3); }"#, ) } From 695a1349fa1c41333e079381e4ec06bb6539f2f1 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Wed, 20 Sep 2023 19:43:02 +0200 Subject: [PATCH 2/4] Fix doctest --- crates/ide-assists/src/handlers/into_to_qualified_from.rs | 2 +- crates/ide-assists/src/tests/generated.rs | 2 +- 2 files changed, 2 insertions(+), 2 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 32d30e6b18d..640883b1bc1 100644 --- a/crates/ide-assists/src/handlers/into_to_qualified_from.rs +++ b/crates/ide-assists/src/handlers/into_to_qualified_from.rs @@ -36,7 +36,7 @@ // // fn main() -> () { // let a = 3; -// let b: B = B::from(a); +// let b: B = ::from(a); // } // ``` pub(crate) fn into_to_qualified_from(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index 63a08a0e569..e65058f70b5 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -1812,7 +1812,7 @@ fn from(a: i32) -> Self { fn main() -> () { let a = 3; - let b: B = B::from(a); + let b: B = ::from(a); } "#####, ) From 132a6ce8fc20ccf56d29334fecf978a9ceec2a55 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Fri, 22 Sep 2023 13:21:38 +0200 Subject: [PATCH 3/4] Omit QualPathTy when possible --- .../src/handlers/into_to_qualified_from.rs | 26 ++++++++++--------- crates/ide-assists/src/tests/generated.rs | 2 +- 2 files changed, 15 insertions(+), 13 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 640883b1bc1..0589cbaf8a7 100644 --- a/crates/ide-assists/src/handlers/into_to_qualified_from.rs +++ b/crates/ide-assists/src/handlers/into_to_qualified_from.rs @@ -36,7 +36,7 @@ // // fn main() -> () { // let a = 3; -// let b: B = ::from(a); +// let b: B = B::from(a); // } // ``` pub(crate) fn into_to_qualified_from(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { @@ -54,22 +54,24 @@ pub(crate) fn into_to_qualified_from(acc: &mut Assists, ctx: &AssistContext<'_>) let type_call = sema.type_of_expr(&method_call.clone().into())?; let adjusted_tc = type_call.adjusted(); - if adjusted_tc.is_unknown() && adjusted_tc.contains_unknown() { + if adjusted_tc.contains_unknown() { return None; } - let qualified_from = format!( - "<{}>::from({})", - adjusted_tc.display_source_code(db, scope.module().into(), true).ok()?, - receiver - ); - + 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`", nameref.syntax().text_range(), |edit| { - edit.replace(method_call.syntax().text_range(), qualified_from); + edit.replace( + method_call.syntax().text_range(), + if sc.chars().find(|c| !c.is_alphanumeric() && c != &':').is_some() { + format!("<{}>::from({})", sc, receiver) + } else { + format!("{}::from({})", sc, receiver) + }, + ); }, ); } @@ -112,7 +114,7 @@ fn from(a: A) -> Self { fn main() -> () { let a: A = A; - let b: B = ::from(a); + let b: B = B::from(a); }"#, ) } @@ -160,7 +162,7 @@ fn from(a: A) -> Self { fn main() -> () { let a: A = A; - let b: B = ::from(a); + let b: B = B::from(a); }"#, ) } @@ -204,7 +206,7 @@ fn from(a: A) -> Self { fn main() -> () { let a: A = A; - let b: C::B = ::from(a); + let b: C::B = C::B::from(a); }"#, ) } diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index e65058f70b5..63a08a0e569 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -1812,7 +1812,7 @@ fn from(a: i32) -> Self { fn main() -> () { let a = 3; - let b: B = ::from(a); + let b: B = B::from(a); } "#####, ) From fc258de5a3ae7a40b8625b862295d5bca00a8c7b Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Fri, 22 Sep 2023 21:22:22 +0200 Subject: [PATCH 4/4] Make QualPathTy case readable --- crates/ide-assists/src/handlers/into_to_qualified_from.rs | 6 +++--- 1 file changed, 3 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 0589cbaf8a7..965e4aa786e 100644 --- a/crates/ide-assists/src/handlers/into_to_qualified_from.rs +++ b/crates/ide-assists/src/handlers/into_to_qualified_from.rs @@ -66,10 +66,10 @@ pub(crate) fn into_to_qualified_from(acc: &mut Assists, ctx: &AssistContext<'_>) |edit| { edit.replace( method_call.syntax().text_range(), - if sc.chars().find(|c| !c.is_alphanumeric() && c != &':').is_some() { - format!("<{}>::from({})", sc, receiver) - } else { + if sc.chars().all(|c| c.is_alphanumeric() || c == ':') { format!("{}::from({})", sc, receiver) + } else { + format!("<{}>::from({})", sc, receiver) }, ); },