about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-13 09:57:51 +0000
committerbors <bors@rust-lang.org>2022-07-13 09:57:51 +0000
commitfc47ce53c8ed91dec1f791d79eb4566988266e73 (patch)
treeb38523a6a8ccfa187e5cd030721a43ff371e25ea
parent84a6bc99ad7ac14fd15b1026d52ce7bc321e311a (diff)
parent638abba05cbd8488bd62547ad8f6c1131615f7e9 (diff)
downloadrust-fc47ce53c8ed91dec1f791d79eb4566988266e73.tar.gz
rust-fc47ce53c8ed91dec1f791d79eb4566988266e73.zip
Auto merge of #12696 - hi-rustin:rustin-patch-fix, r=Veykril
Add str_ref_to_string fix

close https://github.com/rust-lang/rust-analyzer/issues/11383
When type mismatch is `&str` -> `String` try to fix it.
-rw-r--r--crates/ide-diagnostics/src/handlers/type_mismatch.rs47
1 files changed, 47 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..22393824722 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", "Add .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,24 @@ 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#"
+struct String;
+
+fn test() -> String {
+    "a"$0
+}
+            "#,
+            r#"
+struct String;
+
+fn test() -> String {
+    "a".to_string()
+}
+            "#,
+        );
+    }
 }