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, + d: &hir::TypeMismatch, + acc: &mut Vec, +) -> 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() +} + "#, + ); + } }