From 1fcdc6ed76e2aef23ba3086eca90f4f84dc6ffdd Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 26 May 2026 08:33:26 +0800 Subject: [PATCH 1/3] fix: use add deref in assign instead add `&mut` for value Example --- ```rust fn test(arg: &mut i32) { arg = $02; } ``` **Before this PR** ```rust fn test(arg: &mut i32) { arg = &mut 2; } ``` **After this PR** ```rust fn test(arg: &mut i32) { *arg = 2; } ``` --- .../src/handlers/type_mismatch.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs index f3cf823efe68..82f63aa66eb8 100644 --- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -120,6 +120,19 @@ fn add_or_fix_reference( return None; } + let expr = expr_ptr.to_node(ctx.db()); + let assign = expr.syntax().parent().and_then(ast::BinExpr::cast).filter(|it| { + it.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) && it.rhs() == Some(expr) + }); + if let Some(assign) = assign + && expected_mutability.is_mut() + && let Some(range) = ctx.sema.original_range_opt(assign.syntax()) + { + let edit = TextEdit::insert(range.range.start(), "*".to_owned()); + let source_change = SourceChange::from_text_edit(range.file_id.file_id(ctx.db()), edit); + acc.push(fix("add_deref_here", "Add deref here", source_change, range.range)); + } + let ampersands = format!("&{}", expected_mutability.as_keyword_for_ref()); let edit = TextEdit::insert(range.range.start(), ampersands); @@ -507,6 +520,22 @@ fn test(_arg: &mut i32) {} ); } + #[test] + fn add_deref_in_assign() { + check_fix( + r#" +fn test(arg: &mut i32) { + arg = $02; +} + "#, + r#" +fn test(arg: &mut i32) { + *arg = 2; +} + "#, + ); + } + #[test] fn add_reference_to_array() { check_fix( From 1cc7055060a9232d61e0d56d176c6f44495382f2 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 27 May 2026 19:38:24 +0800 Subject: [PATCH 2/3] Add missing early return --- crates/ide-diagnostics/src/handlers/type_mismatch.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 82f63aa66eb8..c53208274920 100644 --- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -131,6 +131,7 @@ fn add_or_fix_reference( let edit = TextEdit::insert(range.range.start(), "*".to_owned()); let source_change = SourceChange::from_text_edit(range.file_id.file_id(ctx.db()), edit); acc.push(fix("add_deref_here", "Add deref here", source_change, range.range)); + return Some(()); } let ampersands = format!("&{}", expected_mutability.as_keyword_for_ref()); From 3db3c1a2a3a8599e22a63c85f18aa3b2babd19f6 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Mon, 1 Jun 2026 07:09:50 +0800 Subject: [PATCH 3/3] Remove redundant filter Co-authored-by: Chayim Refael Friedman --- crates/ide-diagnostics/src/handlers/type_mismatch.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs index c53208274920..5a1856c89df3 100644 --- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -121,9 +121,11 @@ fn add_or_fix_reference( } let expr = expr_ptr.to_node(ctx.db()); - let assign = expr.syntax().parent().and_then(ast::BinExpr::cast).filter(|it| { - it.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) && it.rhs() == Some(expr) - }); + let assign = expr + .syntax() + .parent() + .and_then(ast::BinExpr::cast) + .filter(|it| it.op_kind() == Some(ast::BinaryOp::Assignment { op: None })); if let Some(assign) = assign && expected_mutability.is_mut() && let Some(range) = ctx.sema.original_range_opt(assign.syntax())