about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide')
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/annotations.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/extend_selection.rs54
-rwxr-xr-xsrc/tools/rust-analyzer/crates/ide/src/folding_ranges.rs88
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs45
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs116
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs42
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs43
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs50
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/join_lines.rs26
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/parent_module.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs178
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs34
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/signature_help.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs39
27 files changed, 527 insertions, 362 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
index 05196ac98c0..dec1889926d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
@@ -159,10 +159,10 @@ pub(crate) fn annotations(
                     node.value.syntax().text_range(),
                     Some(name),
                 );
-                if res.call_site.0.file_id == source_file_id {
-                    if let Some(name_range) = res.call_site.1 {
-                        return Some((res.call_site.0.range, Some(name_range)));
-                    }
+                if res.call_site.0.file_id == source_file_id
+                    && let Some(name_range) = res.call_site.1
+                {
+                    return Some((res.call_site.0.range, Some(name_range)));
                 }
             };
             // otherwise try upmapping the entire node out of attributes
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index f31886b9697..ad84eacfb3e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -96,14 +96,14 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
     let (name, expanded, kind) = loop {
         let node = anc.next()?;
 
-        if let Some(item) = ast::Item::cast(node.clone()) {
-            if let Some(def) = sema.resolve_attr_macro_call(&item) {
-                break (
-                    def.name(db).display(db, file_id.edition(db)).to_string(),
-                    expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
-                    SyntaxKind::MACRO_ITEMS,
-                );
-            }
+        if let Some(item) = ast::Item::cast(node.clone())
+            && let Some(def) = sema.resolve_attr_macro_call(&item)
+        {
+            break (
+                def.name(db).display(db, file_id.edition(db)).to_string(),
+                expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
+                SyntaxKind::MACRO_ITEMS,
+            );
         }
         if let Some(mac) = ast::MacroCall::cast(node) {
             let mut name = mac.path()?.segment()?.name_ref()?.to_string();
diff --git a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
index a374f9752fc..2926384c407 100644
--- a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
@@ -81,10 +81,10 @@ fn try_extend_selection(
             if token.text_range() != range {
                 return Some(token.text_range());
             }
-            if let Some(comment) = ast::Comment::cast(token.clone()) {
-                if let Some(range) = extend_comments(comment) {
-                    return Some(range);
-                }
+            if let Some(comment) = ast::Comment::cast(token.clone())
+                && let Some(range) = extend_comments(comment)
+            {
+                return Some(range);
             }
             token.parent()?
         }
@@ -92,12 +92,11 @@ fn try_extend_selection(
     };
 
     // if we are in single token_tree, we maybe live in macro or attr
-    if node.kind() == TOKEN_TREE {
-        if let Some(macro_call) = node.ancestors().find_map(ast::MacroCall::cast) {
-            if let Some(range) = extend_tokens_from_range(sema, macro_call, range) {
-                return Some(range);
-            }
-        }
+    if node.kind() == TOKEN_TREE
+        && let Some(macro_call) = node.ancestors().find_map(ast::MacroCall::cast)
+        && let Some(range) = extend_tokens_from_range(sema, macro_call, range)
+    {
+        return Some(range);
     }
 
     if node.text_range() != range {
@@ -106,10 +105,10 @@ fn try_extend_selection(
 
     let node = shallowest_node(&node);
 
-    if node.parent().is_some_and(|n| list_kinds.contains(&n.kind())) {
-        if let Some(range) = extend_list_item(&node) {
-            return Some(range);
-        }
+    if node.parent().is_some_and(|n| list_kinds.contains(&n.kind()))
+        && let Some(range) = extend_list_item(&node)
+    {
+        return Some(range);
     }
 
     node.parent().map(|it| it.text_range())
@@ -221,19 +220,20 @@ fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextSize) -> TextRange
     let prefix = TextRange::new(ws.text_range().start(), offset) - ws.text_range().start();
     let ws_suffix = &ws_text[suffix];
     let ws_prefix = &ws_text[prefix];
-    if ws_text.contains('\n') && !ws_suffix.contains('\n') {
-        if let Some(node) = ws.next_sibling_or_token() {
-            let start = match ws_prefix.rfind('\n') {
-                Some(idx) => ws.text_range().start() + TextSize::from((idx + 1) as u32),
-                None => node.text_range().start(),
-            };
-            let end = if root.text().char_at(node.text_range().end()) == Some('\n') {
-                node.text_range().end() + TextSize::of('\n')
-            } else {
-                node.text_range().end()
-            };
-            return TextRange::new(start, end);
-        }
+    if ws_text.contains('\n')
+        && !ws_suffix.contains('\n')
+        && let Some(node) = ws.next_sibling_or_token()
+    {
+        let start = match ws_prefix.rfind('\n') {
+            Some(idx) => ws.text_range().start() + TextSize::from((idx + 1) as u32),
+            None => node.text_range().start(),
+        };
+        let end = if root.text().char_at(node.text_range().end()) == Some('\n') {
+            node.text_range().end() + TextSize::of('\n')
+        } else {
+            node.text_range().end()
+        };
+        return TextRange::new(start, end);
     }
     ws.text_range()
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
index 1901bcc797e..ac64413effe 100755
--- a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
@@ -61,30 +61,29 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
             };
             if is_multiline {
                 // for the func with multiline param list
-                if matches!(element.kind(), FN) {
-                    if let NodeOrToken::Node(node) = &element {
-                        if let Some(fn_node) = ast::Fn::cast(node.clone()) {
-                            if !fn_node
-                                .param_list()
-                                .map(|param_list| param_list.syntax().text().contains_char('\n'))
-                                .unwrap_or(false)
-                            {
-                                continue;
-                            }
+                if matches!(element.kind(), FN)
+                    && let NodeOrToken::Node(node) = &element
+                    && let Some(fn_node) = ast::Fn::cast(node.clone())
+                {
+                    if !fn_node
+                        .param_list()
+                        .map(|param_list| param_list.syntax().text().contains_char('\n'))
+                        .unwrap_or(false)
+                    {
+                        continue;
+                    }
 
-                            if fn_node.body().is_some() {
-                                // Get the actual start of the function (excluding doc comments)
-                                let fn_start = fn_node
-                                    .fn_token()
-                                    .map(|token| token.text_range().start())
-                                    .unwrap_or(node.text_range().start());
-                                res.push(Fold {
-                                    range: TextRange::new(fn_start, node.text_range().end()),
-                                    kind: FoldKind::Function,
-                                });
-                                continue;
-                            }
-                        }
+                    if fn_node.body().is_some() {
+                        // Get the actual start of the function (excluding doc comments)
+                        let fn_start = fn_node
+                            .fn_token()
+                            .map(|token| token.text_range().start())
+                            .unwrap_or(node.text_range().start());
+                        res.push(Fold {
+                            range: TextRange::new(fn_start, node.text_range().end()),
+                            kind: FoldKind::Function,
+                        });
+                        continue;
                     }
                 }
                 res.push(Fold { range: element.text_range(), kind });
@@ -120,14 +119,13 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
                 match_ast! {
                     match node {
                         ast::Module(module) => {
-                            if module.item_list().is_none() {
-                                if let Some(range) = contiguous_range_for_item_group(
+                            if module.item_list().is_none()
+                                && let Some(range) = contiguous_range_for_item_group(
                                     module,
                                     &mut visited_nodes,
                                 ) {
                                     res.push(Fold { range, kind: FoldKind::Modules })
                                 }
-                            }
                         },
                         ast::Use(use_) => {
                             if let Some(range) = contiguous_range_for_item_group(use_, &mut visited_nodes) {
@@ -212,11 +210,11 @@ where
     for element in first.syntax().siblings_with_tokens(Direction::Next) {
         let node = match element {
             NodeOrToken::Token(token) => {
-                if let Some(ws) = ast::Whitespace::cast(token) {
-                    if !ws.spans_multiple_lines() {
-                        // Ignore whitespace without blank lines
-                        continue;
-                    }
+                if let Some(ws) = ast::Whitespace::cast(token)
+                    && !ws.spans_multiple_lines()
+                {
+                    // Ignore whitespace without blank lines
+                    continue;
                 }
                 // There is a blank line or another token, which means that the
                 // group ends here
@@ -270,21 +268,21 @@ fn contiguous_range_for_comment(
     for element in first.syntax().siblings_with_tokens(Direction::Next) {
         match element {
             NodeOrToken::Token(token) => {
-                if let Some(ws) = ast::Whitespace::cast(token.clone()) {
-                    if !ws.spans_multiple_lines() {
-                        // Ignore whitespace without blank lines
-                        continue;
-                    }
+                if let Some(ws) = ast::Whitespace::cast(token.clone())
+                    && !ws.spans_multiple_lines()
+                {
+                    // Ignore whitespace without blank lines
+                    continue;
                 }
-                if let Some(c) = ast::Comment::cast(token) {
-                    if c.kind() == group_kind {
-                        let text = c.text().trim_start();
-                        // regions are not real comments
-                        if !(text.starts_with(REGION_START) || text.starts_with(REGION_END)) {
-                            visited.insert(c.clone());
-                            last = c;
-                            continue;
-                        }
+                if let Some(c) = ast::Comment::cast(token)
+                    && c.kind() == group_kind
+                {
+                    let text = c.text().trim_start();
+                    // regions are not real comments
+                    if !(text.starts_with(REGION_START) || text.starts_with(REGION_END)) {
+                        visited.insert(c.clone());
+                        last = c;
+                        continue;
                     }
                 }
                 // The comment group ends because either:
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index 29fc68bb50f..84e41277390 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -94,18 +94,17 @@ pub(crate) fn goto_definition(
             let parent = token.value.parent()?;
 
             let token_file_id = token.file_id;
-            if let Some(token) = ast::String::cast(token.value.clone()) {
-                if let Some(x) =
+            if let Some(token) = ast::String::cast(token.value.clone())
+                && let Some(x) =
                     try_lookup_include_path(sema, InFile::new(token_file_id, token), file_id)
-                {
-                    return Some(vec![x]);
-                }
+            {
+                return Some(vec![x]);
             }
 
-            if ast::TokenTree::can_cast(parent.kind()) {
-                if let Some(x) = try_lookup_macro_def_in_macro_use(sema, token.value) {
-                    return Some(vec![x]);
-                }
+            if ast::TokenTree::can_cast(parent.kind())
+                && let Some(x) = try_lookup_macro_def_in_macro_use(sema, token.value)
+            {
+                return Some(vec![x]);
             }
 
             Some(
@@ -245,12 +244,11 @@ fn try_lookup_macro_def_in_macro_use(
     let krate = extern_crate.resolved_crate(sema.db)?;
 
     for mod_def in krate.root_module().declarations(sema.db) {
-        if let ModuleDef::Macro(mac) = mod_def {
-            if mac.name(sema.db).as_str() == token.text() {
-                if let Some(nav) = mac.try_to_nav(sema.db) {
-                    return Some(nav.call_site);
-                }
-            }
+        if let ModuleDef::Macro(mac) = mod_def
+            && mac.name(sema.db).as_str() == token.text()
+            && let Some(nav) = mac.try_to_nav(sema.db)
+        {
+            return Some(nav.call_site);
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
index 356bd69aa44..9960e79a538 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -722,20 +722,19 @@ impl<'a> WalkExpandedExprCtx<'a> {
                         self.depth += 1;
                     }
 
-                    if let ast::Expr::MacroExpr(expr) = expr {
-                        if let Some(expanded) =
+                    if let ast::Expr::MacroExpr(expr) = expr
+                        && let Some(expanded) =
                             expr.macro_call().and_then(|call| self.sema.expand_macro_call(&call))
-                        {
-                            match_ast! {
-                                match (expanded.value) {
-                                    ast::MacroStmts(it) => {
-                                        self.handle_expanded(it, cb);
-                                    },
-                                    ast::Expr(it) => {
-                                        self.walk(&it, cb);
-                                    },
-                                    _ => {}
-                                }
+                    {
+                        match_ast! {
+                            match (expanded.value) {
+                                ast::MacroStmts(it) => {
+                                    self.handle_expanded(it, cb);
+                                },
+                                ast::Expr(it) => {
+                                    self.walk(&it, cb);
+                                },
+                                _ => {}
                             }
                         }
                     }
@@ -755,10 +754,10 @@ impl<'a> WalkExpandedExprCtx<'a> {
         }
 
         for stmt in expanded.statements() {
-            if let ast::Stmt::ExprStmt(stmt) = stmt {
-                if let Some(expr) = stmt.expr() {
-                    self.walk(&expr, cb);
-                }
+            if let ast::Stmt::ExprStmt(stmt) = stmt
+                && let Some(expr) = stmt.expr()
+            {
+                self.walk(&expr, cb);
             }
         }
     }
@@ -806,12 +805,12 @@ pub(crate) fn highlight_unsafe_points(
         push_to_highlights(unsafe_token_file_id, Some(unsafe_token.text_range()));
 
         // highlight unsafe operations
-        if let Some(block) = block_expr {
-            if let Some(body) = sema.body_for(InFile::new(unsafe_token_file_id, block.syntax())) {
-                let unsafe_ops = sema.get_unsafe_ops(body);
-                for unsafe_op in unsafe_ops {
-                    push_to_highlights(unsafe_op.file_id, Some(unsafe_op.value.text_range()));
-                }
+        if let Some(block) = block_expr
+            && let Some(body) = sema.body_for(InFile::new(unsafe_token_file_id, block.syntax()))
+        {
+            let unsafe_ops = sema.get_unsafe_ops(body);
+            for unsafe_op in unsafe_ops {
+                push_to_highlights(unsafe_op.file_id, Some(unsafe_op.value.text_range()));
             }
         }
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index e4d6279759e..44c98a43f69 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -244,17 +244,15 @@ fn hover_offset(
                     let node = token.parent()?;
 
                     // special case macro calls, we wanna render the invoked arm index
-                    if let Some(name) = ast::NameRef::cast(node.clone()) {
-                        if let Some(path_seg) =
+                    if let Some(name) = ast::NameRef::cast(node.clone())
+                        && let Some(path_seg) =
                             name.syntax().parent().and_then(ast::PathSegment::cast)
-                        {
-                            if let Some(macro_call) = path_seg
+                            && let Some(macro_call) = path_seg
                                 .parent_path()
                                 .syntax()
                                 .parent()
                                 .and_then(ast::MacroCall::cast)
-                            {
-                                if let Some(macro_) = sema.resolve_macro_call(&macro_call) {
+                                && let Some(macro_) = sema.resolve_macro_call(&macro_call) {
                                     break 'a vec![(
                                         (Definition::Macro(macro_), None),
                                         sema.resolve_macro_call_arm(&macro_call),
@@ -262,9 +260,6 @@ fn hover_offset(
                                         node,
                                     )];
                                 }
-                            }
-                        }
-                    }
 
                     match IdentClass::classify_node(sema, &node)? {
                         // It's better for us to fall back to the keyword hover here,
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 670210d4998..51b5900e815 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -95,23 +95,25 @@ pub(super) fn try_expr(
     if let Some((hir::Adt::Enum(inner), hir::Adt::Enum(body))) = adts {
         let famous_defs = FamousDefs(sema, sema.scope(try_expr.syntax())?.krate());
         // special case for two options, there is no value in showing them
-        if let Some(option_enum) = famous_defs.core_option_Option() {
-            if inner == option_enum && body == option_enum {
-                cov_mark::hit!(hover_try_expr_opt_opt);
-                return None;
-            }
+        if let Some(option_enum) = famous_defs.core_option_Option()
+            && inner == option_enum
+            && body == option_enum
+        {
+            cov_mark::hit!(hover_try_expr_opt_opt);
+            return None;
         }
 
         // special case two results to show the error variants only
-        if let Some(result_enum) = famous_defs.core_result_Result() {
-            if inner == result_enum && body == result_enum {
-                let error_type_args =
-                    inner_ty.type_arguments().nth(1).zip(body_ty.type_arguments().nth(1));
-                if let Some((inner, body)) = error_type_args {
-                    inner_ty = inner;
-                    body_ty = body;
-                    "Try Error".clone_into(&mut s);
-                }
+        if let Some(result_enum) = famous_defs.core_result_Result()
+            && inner == result_enum
+            && body == result_enum
+        {
+            let error_type_args =
+                inner_ty.type_arguments().nth(1).zip(body_ty.type_arguments().nth(1));
+            if let Some((inner, body)) = error_type_args {
+                inner_ty = inner;
+                body_ty = body;
+                "Try Error".clone_into(&mut s);
             }
         }
     }
@@ -1132,10 +1134,10 @@ fn markup(
 ) -> (Markup, Option<DocsRangeMap>) {
     let mut buf = String::new();
 
-    if let Some(mod_path) = mod_path {
-        if !mod_path.is_empty() {
-            format_to!(buf, "```rust\n{}\n```\n\n", mod_path);
-        }
+    if let Some(mod_path) = mod_path
+        && !mod_path.is_empty()
+    {
+        format_to!(buf, "```rust\n{}\n```\n\n", mod_path);
     }
     format_to!(buf, "```rust\n{}\n```", rust);
 
@@ -1217,55 +1219,55 @@ fn render_memory_layout(
         format_to!(label, ", ");
     }
 
-    if let Some(render) = config.offset {
-        if let Some(offset) = offset(&layout) {
-            format_to!(label, "offset = ");
-            match render {
-                MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{offset}"),
-                MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{offset:#X}"),
-                MemoryLayoutHoverRenderKind::Both if offset >= 10 => {
-                    format_to!(label, "{offset} ({offset:#X})")
-                }
-                MemoryLayoutHoverRenderKind::Both => {
-                    format_to!(label, "{offset}")
-                }
+    if let Some(render) = config.offset
+        && let Some(offset) = offset(&layout)
+    {
+        format_to!(label, "offset = ");
+        match render {
+            MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{offset}"),
+            MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{offset:#X}"),
+            MemoryLayoutHoverRenderKind::Both if offset >= 10 => {
+                format_to!(label, "{offset} ({offset:#X})")
+            }
+            MemoryLayoutHoverRenderKind::Both => {
+                format_to!(label, "{offset}")
             }
-            format_to!(label, ", ");
         }
+        format_to!(label, ", ");
     }
 
-    if let Some(render) = config.padding {
-        if let Some((padding_name, padding)) = padding(&layout) {
-            format_to!(label, "{padding_name} = ");
-            match render {
-                MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{padding}"),
-                MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{padding:#X}"),
-                MemoryLayoutHoverRenderKind::Both if padding >= 10 => {
-                    format_to!(label, "{padding} ({padding:#X})")
-                }
-                MemoryLayoutHoverRenderKind::Both => {
-                    format_to!(label, "{padding}")
-                }
+    if let Some(render) = config.padding
+        && let Some((padding_name, padding)) = padding(&layout)
+    {
+        format_to!(label, "{padding_name} = ");
+        match render {
+            MemoryLayoutHoverRenderKind::Decimal => format_to!(label, "{padding}"),
+            MemoryLayoutHoverRenderKind::Hexadecimal => format_to!(label, "{padding:#X}"),
+            MemoryLayoutHoverRenderKind::Both if padding >= 10 => {
+                format_to!(label, "{padding} ({padding:#X})")
+            }
+            MemoryLayoutHoverRenderKind::Both => {
+                format_to!(label, "{padding}")
             }
-            format_to!(label, ", ");
         }
+        format_to!(label, ", ");
     }
 
-    if config.niches {
-        if let Some(niches) = layout.niches() {
-            if niches > 1024 {
-                if niches.is_power_of_two() {
-                    format_to!(label, "niches = 2{}, ", pwr2_to_exponent(niches));
-                } else if is_pwr2plus1(niches) {
-                    format_to!(label, "niches = 2{} + 1, ", pwr2_to_exponent(niches - 1));
-                } else if is_pwr2minus1(niches) {
-                    format_to!(label, "niches = 2{} - 1, ", pwr2_to_exponent(niches + 1));
-                } else {
-                    format_to!(label, "niches = a lot, ");
-                }
+    if config.niches
+        && let Some(niches) = layout.niches()
+    {
+        if niches > 1024 {
+            if niches.is_power_of_two() {
+                format_to!(label, "niches = 2{}, ", pwr2_to_exponent(niches));
+            } else if is_pwr2plus1(niches) {
+                format_to!(label, "niches = 2{} + 1, ", pwr2_to_exponent(niches - 1));
+            } else if is_pwr2minus1(niches) {
+                format_to!(label, "niches = 2{} - 1, ", pwr2_to_exponent(niches + 1));
             } else {
-                format_to!(label, "niches = {niches}, ");
+                format_to!(label, "niches = a lot, ");
             }
+        } else {
+            format_to!(label, "niches = {niches}, ");
         }
     }
     label.pop(); // ' '
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
index 19e5509681a..7a8514c47af 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -576,13 +576,13 @@ impl InlayHintLabel {
     }
 
     pub fn append_part(&mut self, part: InlayHintLabelPart) {
-        if part.linked_location.is_none() && part.tooltip.is_none() {
-            if let Some(InlayHintLabelPart { text, linked_location: None, tooltip: None }) =
+        if part.linked_location.is_none()
+            && part.tooltip.is_none()
+            && let Some(InlayHintLabelPart { text, linked_location: None, tooltip: None }) =
                 self.parts.last_mut()
-            {
-                text.push_str(&part.text);
-                return;
-            }
+        {
+            text.push_str(&part.text);
+            return;
         }
         self.parts.push(part);
     }
@@ -1065,4 +1065,34 @@ fn bar() {
 "#,
         );
     }
+
+    #[test]
+    fn regression_20239() {
+        check_with_config(
+            InlayHintsConfig { parameter_hints: true, type_hints: true, ..DISABLED_CONFIG },
+            r#"
+//- minicore: fn
+trait Iterator {
+    type Item;
+    fn map<B, F: FnMut(Self::Item) -> B>(self, f: F);
+}
+trait ToString {
+    fn to_string(&self);
+}
+
+fn check_tostr_eq<L, R>(left: L, right: R)
+where
+    L: Iterator,
+    L::Item: ToString,
+    R: Iterator,
+    R::Item: ToString,
+{
+    left.map(|s| s.to_string());
+           // ^ impl ToString
+    right.map(|s| s.to_string());
+            // ^ impl ToString
+}
+        "#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
index 49b43fc37f2..4d020bac3aa 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
@@ -39,10 +39,10 @@ pub(super) fn hints(
     if let ast::Expr::ParenExpr(_) = expr {
         return None;
     }
-    if let ast::Expr::BlockExpr(b) = expr {
-        if !b.is_standalone() {
-            return None;
-        }
+    if let ast::Expr::BlockExpr(b) = expr
+        && !b.is_standalone()
+    {
+        return None;
     }
 
     let descended = sema.descend_node_into_attributes(expr.clone()).pop();
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
index 729349365e6..922e9598aa0 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
@@ -41,13 +41,11 @@ pub(super) fn hints(
                 Some(it.colon_token())
             },
             ast::LetStmt(it) => {
-                if config.hide_closure_initialization_hints {
-                    if let Some(ast::Expr::ClosureExpr(closure)) = it.initializer() {
-                        if closure_has_block_body(&closure) {
+                if config.hide_closure_initialization_hints
+                    && let Some(ast::Expr::ClosureExpr(closure)) = it.initializer()
+                        && closure_has_block_body(&closure) {
                             return None;
                         }
-                    }
-                }
                 if it.ty().is_some() {
                     return None;
                 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
index ff157fa171b..a8bb652fda2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
@@ -51,12 +51,11 @@ pub(super) fn hints(
             if ty.is_unknown() {
                 return None;
             }
-            if matches!(expr, ast::Expr::PathExpr(_)) {
-                if let Some(hir::Adt::Struct(st)) = ty.as_adt() {
-                    if st.fields(sema.db).is_empty() {
-                        return None;
-                    }
-                }
+            if matches!(expr, ast::Expr::PathExpr(_))
+                && let Some(hir::Adt::Struct(st)) = ty.as_adt()
+                && st.fields(sema.db).is_empty()
+            {
+                return None;
             }
             let label = label_of_ty(famous_defs, config, &ty, display_target)?;
             acc.push(InlayHint {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
index 05253b67948..e80c9dc9d47 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
@@ -120,11 +120,11 @@ pub(super) fn hints(
     };
 
     if let Some(mut next) = closing_token.next_token() {
-        if next.kind() == T![;] {
-            if let Some(tok) = next.next_token() {
-                closing_token = next;
-                next = tok;
-            }
+        if next.kind() == T![;]
+            && let Some(tok) = next.next_token()
+        {
+            closing_token = next;
+            next = tok;
         }
         if !(next.kind() == SyntaxKind::WHITESPACE && next.text().contains('\n')) {
             // Only display the hint if the `}` is the last token on the line
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
index 9e600b5455b..fef1cb83c11 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
@@ -55,11 +55,9 @@ pub(super) fn hints(
 
     // Insert braces if necessary
     let insert_braces = |builder: &mut TextEditBuilder| {
-        if !has_block_body {
-            if let Some(range) = closure.body().map(|b| b.syntax().text_range()) {
-                builder.insert(range.start(), "{ ".to_owned());
-                builder.insert(range.end(), " }".to_owned());
-            }
+        if !has_block_body && let Some(range) = closure.body().map(|b| b.syntax().text_range()) {
+            builder.insert(range.start(), "{ ".to_owned());
+            builder.insert(range.end(), " }".to_owned());
         }
     };
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
index 88152bf3e38..491018a4dda 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
@@ -81,10 +81,10 @@ fn item_hint(
         text_edit: Some(config.lazy_text_edit(|| {
             let mut builder = TextEdit::builder();
             builder.insert(token.text_range().start(), "unsafe ".to_owned());
-            if extern_block.unsafe_token().is_none() {
-                if let Some(abi) = extern_block.abi() {
-                    builder.insert(abi.syntax().text_range().start(), "unsafe ".to_owned());
-                }
+            if extern_block.unsafe_token().is_none()
+                && let Some(abi) = extern_block.abi()
+            {
+                builder.insert(abi.syntax().text_range().start(), "unsafe ".to_owned());
             }
             builder.finish()
         })),
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
index 6e1b3bdbdf0..1fddb6fbe01 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
@@ -33,10 +33,10 @@ pub(crate) fn hints(
     let mut args = generic_arg_list.generic_args().peekable();
     let start_with_lifetime = matches!(args.peek()?, ast::GenericArg::LifetimeArg(_));
     let params = generic_def.params(sema.db).into_iter().filter(|p| {
-        if let hir::GenericParam::TypeParam(it) = p {
-            if it.is_implicit(sema.db) {
-                return false;
-            }
+        if let hir::GenericParam::TypeParam(it) = p
+            && it.is_implicit(sema.db)
+        {
+            return false;
         }
         if !start_with_lifetime {
             return !matches!(p, hir::GenericParam::LifetimeParam(_));
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
index 7212efd954e..bddce904dfd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
@@ -22,30 +22,31 @@ pub(super) fn hints(
         return None;
     }
 
-    if let Either::Right(it) = &statik_or_const {
-        if ast::AssocItemList::can_cast(
+    if let Either::Right(it) = &statik_or_const
+        && ast::AssocItemList::can_cast(
             it.syntax().parent().map_or(SyntaxKind::EOF, |it| it.kind()),
-        ) {
-            return None;
-        }
+        )
+    {
+        return None;
     }
 
-    if let Some(ast::Type::RefType(ty)) = statik_or_const.either(|it| it.ty(), |it| it.ty()) {
-        if ty.lifetime().is_none() {
-            let t = ty.amp_token()?;
-            acc.push(InlayHint {
-                range: t.text_range(),
-                kind: InlayKind::Lifetime,
-                label: "'static".into(),
-                text_edit: Some(config.lazy_text_edit(|| {
-                    TextEdit::insert(t.text_range().start(), "'static ".into())
-                })),
-                position: InlayHintPosition::After,
-                pad_left: false,
-                pad_right: true,
-                resolve_parent: None,
-            });
-        }
+    if let Some(ast::Type::RefType(ty)) = statik_or_const.either(|it| it.ty(), |it| it.ty())
+        && ty.lifetime().is_none()
+    {
+        let t = ty.amp_token()?;
+        acc.push(InlayHint {
+            range: t.text_range(),
+            kind: InlayKind::Lifetime,
+            label: "'static".into(),
+            text_edit: Some(
+                config
+                    .lazy_text_edit(|| TextEdit::insert(t.text_range().start(), "'static ".into())),
+            ),
+            position: InlayHintPosition::After,
+            pad_left: false,
+            pad_right: true,
+            resolve_parent: None,
+        });
     }
 
     Some(())
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
index 49fec0a793c..a89c53e00b3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
@@ -324,35 +324,35 @@ fn hints_(
 
     // apply hints
     // apply output if required
-    if let (Some(output_lt), Some(r)) = (&output, ret_type) {
-        if let Some(ty) = r.ty() {
-            walk_ty(&ty, &mut |ty| match ty {
-                ast::Type::RefType(ty) if ty.lifetime().is_none() => {
-                    if let Some(amp) = ty.amp_token() {
-                        is_trivial = false;
-                        acc.push(mk_lt_hint(amp, output_lt.to_string()));
-                    }
-                    false
+    if let (Some(output_lt), Some(r)) = (&output, ret_type)
+        && let Some(ty) = r.ty()
+    {
+        walk_ty(&ty, &mut |ty| match ty {
+            ast::Type::RefType(ty) if ty.lifetime().is_none() => {
+                if let Some(amp) = ty.amp_token() {
+                    is_trivial = false;
+                    acc.push(mk_lt_hint(amp, output_lt.to_string()));
                 }
-                ast::Type::FnPtrType(_) => {
+                false
+            }
+            ast::Type::FnPtrType(_) => {
+                is_trivial = false;
+                true
+            }
+            ast::Type::PathType(t) => {
+                if t.path()
+                    .and_then(|it| it.segment())
+                    .and_then(|it| it.parenthesized_arg_list())
+                    .is_some()
+                {
                     is_trivial = false;
                     true
+                } else {
+                    false
                 }
-                ast::Type::PathType(t) => {
-                    if t.path()
-                        .and_then(|it| it.segment())
-                        .and_then(|it| it.parenthesized_arg_list())
-                        .is_some()
-                    {
-                        is_trivial = false;
-                        true
-                    } else {
-                        false
-                    }
-                }
-                _ => false,
-            })
-        }
+            }
+            _ => false,
+        })
     }
 
     if config.lifetime_elision_hints == LifetimeElisionHints::SkipTrivial && is_trivial {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
index 5174228466c..ec0a4c46c7f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
@@ -135,10 +135,10 @@ fn should_hide_param_name_hint(
     }
 
     if unary_function {
-        if let Some(function_name) = function_name {
-            if is_param_name_suffix_of_fn_name(param_name, function_name) {
-                return true;
-            }
+        if let Some(function_name) = function_name
+            && is_param_name_suffix_of_fn_name(param_name, function_name)
+        {
+            return true;
         }
         if is_obvious_param(param_name) {
             return true;
diff --git a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
index 0188c105faa..a946559c354 100644
--- a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
@@ -144,15 +144,15 @@ fn remove_newline(
         }
     }
 
-    if config.join_else_if {
-        if let (Some(prev), Some(_next)) = (as_if_expr(&prev), as_if_expr(&next)) {
-            match prev.else_token() {
-                Some(_) => cov_mark::hit!(join_two_ifs_with_existing_else),
-                None => {
-                    cov_mark::hit!(join_two_ifs);
-                    edit.replace(token.text_range(), " else ".to_owned());
-                    return;
-                }
+    if config.join_else_if
+        && let (Some(prev), Some(_next)) = (as_if_expr(&prev), as_if_expr(&next))
+    {
+        match prev.else_token() {
+            Some(_) => cov_mark::hit!(join_two_ifs_with_existing_else),
+            None => {
+                cov_mark::hit!(join_two_ifs);
+                edit.replace(token.text_range(), " else ".to_owned());
+                return;
             }
         }
     }
@@ -213,10 +213,10 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Op
     let mut buf = expr.syntax().text().to_string();
 
     // Match block needs to have a comma after the block
-    if let Some(match_arm) = block_expr.syntax().parent().and_then(ast::MatchArm::cast) {
-        if match_arm.comma_token().is_none() {
-            buf.push(',');
-        }
+    if let Some(match_arm) = block_expr.syntax().parent().and_then(ast::MatchArm::cast)
+        && match_arm.comma_token().is_none()
+    {
+        buf.push(',');
     }
 
     edit.replace(block_range, buf);
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index b3b8deb61fc..98877482ed8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -299,7 +299,7 @@ impl Analysis {
 
     /// Gets the text of the source file.
     pub fn file_text(&self, file_id: FileId) -> Cancellable<Arc<str>> {
-        self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db))
+        self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db).clone())
     }
 
     /// Gets the syntax tree of the file.
diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
index 50219cee57d..96d829d1260 100644
--- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
@@ -29,14 +29,13 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
     let mut module = find_node_at_offset::<ast::Module>(source_file.syntax(), position.offset);
 
     // If cursor is literally on `mod foo`, go to the grandpa.
-    if let Some(m) = &module {
-        if !m
+    if let Some(m) = &module
+        && !m
             .item_list()
             .is_some_and(|it| it.syntax().text_range().contains_inclusive(position.offset))
-        {
-            cov_mark::hit!(test_resolve_parent_module_on_module_decl);
-            module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast);
-        }
+    {
+        cov_mark::hit!(test_resolve_parent_module_on_module_decl);
+        module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast);
     }
 
     match module {
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index a07c647c2cb..aea4ae0fd97 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -13,8 +13,11 @@ use ide_db::{
 };
 use itertools::Itertools;
 use std::fmt::Write;
-use stdx::{always, never};
-use syntax::{AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize, ast};
+use stdx::{always, format_to, never};
+use syntax::{
+    AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize,
+    ast::{self, HasArgList, prec::ExprPrecedence},
+};
 
 use ide_db::text_edit::TextEdit;
 
@@ -35,13 +38,8 @@ pub(crate) fn prepare_rename(
     let syntax = source_file.syntax();
 
     let res = find_definitions(&sema, syntax, position, &Name::new_symbol_root(sym::underscore))?
-        .map(|(frange, kind, def, _, _)| {
-            // ensure all ranges are valid
-
-            if def.range_for_rename(&sema).is_none() {
-                bail!("No references found at position")
-            }
-
+        .filter(|(_, _, def, _, _)| def.range_for_rename(&sema).is_some())
+        .map(|(frange, kind, _, _, _)| {
             always!(
                 frange.range.contains_inclusive(position.offset)
                     && frange.file_id == position.file_id
@@ -336,6 +334,85 @@ fn find_definitions(
     }
 }
 
+fn transform_assoc_fn_into_method_call(
+    sema: &Semantics<'_, RootDatabase>,
+    source_change: &mut SourceChange,
+    f: hir::Function,
+) {
+    let calls = Definition::Function(f).usages(sema).all();
+    for (file_id, calls) in calls {
+        for call in calls {
+            let Some(fn_name) = call.name.as_name_ref() else { continue };
+            let Some(path) = fn_name.syntax().parent().and_then(ast::PathSegment::cast) else {
+                continue;
+            };
+            let path = path.parent_path();
+            // The `PathExpr` is the direct parent, above it is the `CallExpr`.
+            let Some(call) =
+                path.syntax().parent().and_then(|it| ast::CallExpr::cast(it.parent()?))
+            else {
+                continue;
+            };
+
+            let Some(arg_list) = call.arg_list() else { continue };
+            let mut args = arg_list.args();
+            let Some(mut self_arg) = args.next() else { continue };
+            let second_arg = args.next();
+
+            // Strip (de)references, as they will be taken automatically by auto(de)ref.
+            loop {
+                let self_ = match &self_arg {
+                    ast::Expr::RefExpr(self_) => self_.expr(),
+                    ast::Expr::ParenExpr(self_) => self_.expr(),
+                    ast::Expr::PrefixExpr(self_)
+                        if self_.op_kind() == Some(ast::UnaryOp::Deref) =>
+                    {
+                        self_.expr()
+                    }
+                    _ => break,
+                };
+                self_arg = match self_ {
+                    Some(it) => it,
+                    None => break,
+                };
+            }
+
+            let self_needs_parens =
+                self_arg.precedence().needs_parentheses_in(ExprPrecedence::Postfix);
+
+            let replace_start = path.syntax().text_range().start();
+            let replace_end = match second_arg {
+                Some(second_arg) => second_arg.syntax().text_range().start(),
+                None => arg_list
+                    .r_paren_token()
+                    .map(|it| it.text_range().start())
+                    .unwrap_or_else(|| arg_list.syntax().text_range().end()),
+            };
+            let replace_range = TextRange::new(replace_start, replace_end);
+
+            let Some(macro_mapped_self) = sema.original_range_opt(self_arg.syntax()) else {
+                continue;
+            };
+            let mut replacement = String::new();
+            if self_needs_parens {
+                replacement.push('(');
+            }
+            replacement.push_str(macro_mapped_self.text(sema.db));
+            if self_needs_parens {
+                replacement.push(')');
+            }
+            replacement.push('.');
+            format_to!(replacement, "{fn_name}");
+            replacement.push('(');
+
+            source_change.insert_source_edit(
+                file_id.file_id(sema.db),
+                TextEdit::replace(replace_range, replacement),
+            );
+        }
+    }
+}
+
 fn rename_to_self(
     sema: &Semantics<'_, RootDatabase>,
     local: hir::Local,
@@ -413,6 +490,7 @@ fn rename_to_self(
         file_id.original_file(sema.db).file_id(sema.db),
         TextEdit::replace(param_source.syntax().text_range(), String::from(self_param)),
     );
+    transform_assoc_fn_into_method_call(sema, &mut source_change, fn_def);
     Ok(source_change)
 }
 
@@ -499,10 +577,10 @@ mod tests {
     ) {
         let ra_fixture_after = &trim_indent(ra_fixture_after);
         let (analysis, position) = fixture::position(ra_fixture_before);
-        if !ra_fixture_after.starts_with("error: ") {
-            if let Err(err) = analysis.prepare_rename(position).unwrap() {
-                panic!("Prepare rename to '{new_name}' was failed: {err}")
-            }
+        if !ra_fixture_after.starts_with("error: ")
+            && let Err(err) = analysis.prepare_rename(position).unwrap()
+        {
+            panic!("Prepare rename to '{new_name}' was failed: {err}")
         }
         let rename_result = analysis
             .rename(position, new_name)
@@ -3417,4 +3495,78 @@ fn other_place() { Quux::Bar$0; }
 "#,
         );
     }
+
+    #[test]
+    fn rename_to_self_callers() {
+        check(
+            "self",
+            r#"
+//- minicore: add
+struct Foo;
+impl core::ops::Add for Foo {
+    type Target = Foo;
+    fn add(self, _: Self) -> Foo { Foo }
+}
+
+impl Foo {
+    fn foo(th$0is: &Self) {}
+}
+
+fn bar(v: &Foo) {
+    Foo::foo(v);
+}
+
+fn baz() {
+    Foo::foo(&Foo);
+    Foo::foo(Foo + Foo);
+}
+        "#,
+            r#"
+struct Foo;
+impl core::ops::Add for Foo {
+    type Target = Foo;
+    fn add(self, _: Self) -> Foo { Foo }
+}
+
+impl Foo {
+    fn foo(&self) {}
+}
+
+fn bar(v: &Foo) {
+    v.foo();
+}
+
+fn baz() {
+    Foo.foo();
+    (Foo + Foo).foo();
+}
+        "#,
+        );
+        // Multiple arguments:
+        check(
+            "self",
+            r#"
+struct Foo;
+
+impl Foo {
+    fn foo(th$0is: &Self, v: i32) {}
+}
+
+fn bar(v: Foo) {
+    Foo::foo(&v, 123);
+}
+        "#,
+            r#"
+struct Foo;
+
+impl Foo {
+    fn foo(&self, v: i32) {}
+}
+
+fn bar(v: Foo) {
+    v.foo(123);
+}
+        "#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index 9d1a5bae96f..83e5c5ab1df 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -514,20 +514,19 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
             .flat_map(|it| it.name(db))
             .for_each(|name| format_to!(path, "{}::", name.display(db, edition)));
         // This probably belongs to canonical_path?
-        if let Some(assoc_item) = def.as_assoc_item(db) {
-            if let Some(ty) = assoc_item.implementing_ty(db) {
-                if let Some(adt) = ty.as_adt() {
-                    let name = adt.name(db);
-                    let mut ty_args = ty.generic_parameters(db, display_target).peekable();
-                    format_to!(path, "{}", name.display(db, edition));
-                    if ty_args.peek().is_some() {
-                        format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)));
-                    }
-                    format_to!(path, "::{}", def_name.display(db, edition));
-                    path.retain(|c| c != ' ');
-                    return Some(path);
-                }
+        if let Some(assoc_item) = def.as_assoc_item(db)
+            && let Some(ty) = assoc_item.implementing_ty(db)
+            && let Some(adt) = ty.as_adt()
+        {
+            let name = adt.name(db);
+            let mut ty_args = ty.generic_parameters(db, display_target).peekable();
+            format_to!(path, "{}", name.display(db, edition));
+            if ty_args.peek().is_some() {
+                format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)));
             }
+            format_to!(path, "::{}", def_name.display(db, edition));
+            path.retain(|c| c != ' ');
+            return Some(path);
         }
         format_to!(path, "{}", def_name.display(db, edition));
         Some(path)
@@ -697,14 +696,13 @@ impl UpdateTest {
                     continue;
                 };
                 for item in items {
-                    if let hir::ItemInNs::Macros(makro) = item {
-                        if Definition::Macro(makro)
+                    if let hir::ItemInNs::Macros(makro) = item
+                        && Definition::Macro(makro)
                             .usages(sema)
                             .in_scope(&search_scope)
                             .at_least_one()
-                        {
-                            return true;
-                        }
+                    {
+                        return true;
                     }
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
index e30a3ebefb9..382573b6801 100644
--- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -146,12 +146,11 @@ pub(crate) fn signature_help(
 
         // Stop at multi-line expressions, since the signature of the outer call is not very
         // helpful inside them.
-        if let Some(expr) = ast::Expr::cast(node.clone()) {
-            if !matches!(expr, ast::Expr::RecordExpr(..))
-                && expr.syntax().text().contains_char('\n')
-            {
-                break;
-            }
+        if let Some(expr) = ast::Expr::cast(node.clone())
+            && !matches!(expr, ast::Expr::RecordExpr(..))
+            && expr.syntax().text().contains_char('\n')
+        {
+            break;
         }
     }
 
@@ -366,10 +365,10 @@ fn signature_help_for_generics(
     res.signature.push('<');
     let mut buf = String::new();
     for param in params {
-        if let hir::GenericParam::TypeParam(ty) = param {
-            if ty.is_implicit(db) {
-                continue;
-            }
+        if let hir::GenericParam::TypeParam(ty) = param
+            && ty.is_implicit(db)
+        {
+            continue;
         }
 
         buf.clear();
diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
index efee39c13db..694ac22e199 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -133,10 +133,10 @@ fn get_definitions(
 ) -> Option<ArrayVec<Definition, 2>> {
     for token in sema.descend_into_macros_exact(token) {
         let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops);
-        if let Some(defs) = def {
-            if !defs.is_empty() {
-                return Some(defs);
-            }
+        if let Some(defs) = def
+            && !defs.is_empty()
+        {
+            return Some(defs);
         }
     }
     None
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
index 87db0cd7dc5..8bde8fd9700 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
@@ -306,12 +306,12 @@ fn highlight_name_ref(
     };
     let mut h = match name_class {
         NameRefClass::Definition(def, _) => {
-            if let Definition::Local(local) = &def {
-                if let Some(bindings_shadow_count) = bindings_shadow_count {
-                    let name = local.name(sema.db);
-                    let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
-                    *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
-                }
+            if let Definition::Local(local) = &def
+                && let Some(bindings_shadow_count) = bindings_shadow_count
+            {
+                let name = local.name(sema.db);
+                let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
+                *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
             };
 
             let mut h = highlight_def(sema, krate, def, edition, true);
@@ -437,21 +437,21 @@ fn highlight_name(
     edition: Edition,
 ) -> Highlight {
     let name_kind = NameClass::classify(sema, &name);
-    if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind {
-        if let Some(bindings_shadow_count) = bindings_shadow_count {
-            let name = local.name(sema.db);
-            let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
-            *shadow_count += 1;
-            *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
-        }
+    if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind
+        && let Some(bindings_shadow_count) = bindings_shadow_count
+    {
+        let name = local.name(sema.db);
+        let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
+        *shadow_count += 1;
+        *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
     };
     match name_kind {
         Some(NameClass::Definition(def)) => {
             let mut h = highlight_def(sema, krate, def, edition, false) | HlMod::Definition;
-            if let Definition::Trait(trait_) = &def {
-                if trait_.is_unsafe(sema.db) {
-                    h |= HlMod::Unsafe;
-                }
+            if let Definition::Trait(trait_) = &def
+                && trait_.is_unsafe(sema.db)
+            {
+                h |= HlMod::Unsafe;
             }
             h
         }
@@ -743,10 +743,9 @@ fn highlight_method_call(
             hir::Access::Owned => {
                 if let Some(receiver_ty) =
                     method_call.receiver().and_then(|it| sema.type_of_expr(&it))
+                    && !receiver_ty.adjusted().is_copy(sema.db)
                 {
-                    if !receiver_ty.adjusted().is_copy(sema.db) {
-                        h |= HlMod::Consuming
-                    }
+                    h |= HlMod::Consuming
                 }
             }
         }