about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhi-rustin <rustin.liu@gmail.com>2022-07-05 22:43:38 +0800
committerhi-rustin <rustin.liu@gmail.com>2022-07-05 22:47:18 +0800
commitb9ba9fab5a090e497c1149baee027190a1673d42 (patch)
tree13aaf4c4227b917d0fd4aac79726d0bee9366a89
parent6edf624cbe75cb77723d9f62f1f6ba4a5fa8fc74 (diff)
downloadrust-b9ba9fab5a090e497c1149baee027190a1673d42.tar.gz
rust-b9ba9fab5a090e497c1149baee027190a1673d42.zip
Add str_ref_to_string fix
Signed-off-by: hi-rustin <rustin.liu@gmail.com>
-rw-r--r--crates/ide-diagnostics/src/handlers/type_mismatch.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs
index 442268d1352..500a18ffb6e 100644
--- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs
+++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs
@@ -35,6 +35,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Option<Vec<Assi
     add_reference(ctx, d, &mut fixes);
     add_missing_ok_or_some(ctx, d, &mut fixes);
     remove_semicolon(ctx, d, &mut fixes);
+    str_ref_to_string(ctx, d, &mut fixes);
 
     if fixes.is_empty() {
         None
@@ -134,6 +135,32 @@ fn remove_semicolon(
     Some(())
 }
 
+fn str_ref_to_string(
+    ctx: &DiagnosticsContext<'_>,
+    d: &hir::TypeMismatch,
+    acc: &mut Vec<Assist>,
+) -> Option<()> {
+    let expected = d.expected.display(ctx.sema.db);
+    let actual = d.actual.display(ctx.sema.db);
+
+    if expected.to_string() != "String" || actual.to_string() != "&str" {
+        return None;
+    }
+
+    let root = ctx.sema.db.parse_or_expand(d.expr.file_id)?;
+    let expr = d.expr.value.to_node(&root);
+    let expr_range = expr.syntax().text_range();
+
+    let to_string = format!(".to_string()");
+
+    let edit = TextEdit::insert(expr.syntax().text_range().end(), to_string);
+    let source_change =
+        SourceChange::from_text_edit(d.expr.file_id.original_file(ctx.sema.db), edit);
+    acc.push(fix("str_ref_to_string", "Use to_string() here", source_change, expr_range));
+
+    Some(())
+}
+
 #[cfg(test)]
 mod tests {
     use crate::tests::{check_diagnostics, check_fix, check_no_fix};
@@ -498,4 +525,20 @@ fn foo() -> SomeOtherEnum { 0$0 }
     fn remove_semicolon() {
         check_fix(r#"fn f() -> i32 { 92$0; }"#, r#"fn f() -> i32 { 92 }"#);
     }
+
+    #[test]
+    fn str_ref_to_string() {
+        check_fix(
+            r#"
+fn test() -> String {
+    "a"$0
+}
+            "#,
+            r#"
+fn test() -> String {
+    "a".to_string()
+}
+            "#,
+        );
+    }
 }