about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-08-24 02:26:37 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2025-08-24 02:26:37 +0300
commit4715c6d41a949358e8dd8dd96de0650939c8bf6b (patch)
tree08a095264d7aac335e0dbe819ff44938ddba3625
parentcf358c09cebfe3e1c0d7145242396f6066033fad (diff)
downloadrust-4715c6d41a949358e8dd8dd96de0650939c8bf6b.tar.gz
rust-4715c6d41a949358e8dd8dd96de0650939c8bf6b.zip
Add an option to remove reborrows from adjustment inlay hints
Reborrows are consecutive deref then ref. Make it the default because reborrows are mostly useless to the programmer.

Also rename `rust-analyzer.inlayHints.expressionAdjustmentHints.enable: "reborrow"` to `rust-analyzer.inlayHints.expressionAdjustmentHints.enable: "borrows"`, as it's not about reborrows but about any ref/deref and it's confusing with the new setting.
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs49
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs17
-rw-r--r--src/tools/rust-analyzer/docs/book/src/configuration_generated.md11
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json10
7 files changed, 88 insertions, 5 deletions
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 d7d31716649..cc44ae8fc8b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -306,6 +306,7 @@ pub struct InlayHintsConfig {
     pub generic_parameter_hints: GenericParameterHints,
     pub chaining_hints: bool,
     pub adjustment_hints: AdjustmentHints,
+    pub adjustment_hints_disable_reborrows: bool,
     pub adjustment_hints_mode: AdjustmentHintsMode,
     pub adjustment_hints_hide_outside_unsafe: bool,
     pub closure_return_type_hints: ClosureReturnTypeHints,
@@ -430,7 +431,7 @@ pub enum LifetimeElisionHints {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum AdjustmentHints {
     Always,
-    ReborrowOnly,
+    BorrowsOnly,
     Never,
 }
 
@@ -886,6 +887,7 @@ mod tests {
         closure_return_type_hints: ClosureReturnTypeHints::Never,
         closure_capture_hints: false,
         adjustment_hints: AdjustmentHints::Never,
+        adjustment_hints_disable_reborrows: false,
         adjustment_hints_mode: AdjustmentHintsMode::Prefix,
         adjustment_hints_hide_outside_unsafe: false,
         binding_mode_hints: false,
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 e39a5f8889a..0fd587a7284 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
@@ -47,7 +47,22 @@ pub(super) fn hints(
 
     let descended = sema.descend_node_into_attributes(expr.clone()).pop();
     let desc_expr = descended.as_ref().unwrap_or(expr);
-    let adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
+    let mut adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
+
+    if config.adjustment_hints_disable_reborrows {
+        // Remove consecutive deref-ref, i.e. reborrows.
+        let mut i = 0;
+        while i < adjustments.len().saturating_sub(1) {
+            let [current, next, ..] = &adjustments[i..] else { unreachable!() };
+            if matches!(current.kind, Adjust::Deref(None))
+                && matches!(next.kind, Adjust::Borrow(AutoBorrow::Ref(_)))
+            {
+                adjustments.splice(i..i + 2, []);
+            } else {
+                i += 1;
+            }
+        }
+    }
 
     if let ast::Expr::BlockExpr(_) | ast::Expr::IfExpr(_) | ast::Expr::MatchExpr(_) = desc_expr {
         // Don't show unnecessary reborrows for these, they will just repeat the inner ones again
@@ -719,4 +734,36 @@ fn hello(it: &&[impl T]) {
 "#,
         );
     }
+
+    #[test]
+    fn disable_reborrows() {
+        check_with_config(
+            InlayHintsConfig {
+                adjustment_hints: AdjustmentHints::Always,
+                adjustment_hints_disable_reborrows: true,
+                ..DISABLED_CONFIG
+            },
+            r#"
+#![rustc_coherence_is_core]
+
+trait ToOwned {
+    type Owned;
+    fn to_owned(&self) -> Self::Owned;
+}
+
+struct String;
+impl ToOwned for str {
+    type Owned = String;
+    fn to_owned(&self) -> Self::Owned { String }
+}
+
+fn a(s: &String) {}
+
+fn main() {
+    let s = "".to_owned();
+    a(&s)
+}
+"#,
+        );
+    }
 }
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 14b6529c61f..8c3275df1ba 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -169,6 +169,7 @@ impl StaticIndex<'_> {
                     closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
                     lifetime_elision_hints: crate::LifetimeElisionHints::Never,
                     adjustment_hints: crate::AdjustmentHints::Never,
+                    adjustment_hints_disable_reborrows: true,
                     adjustment_hints_mode: AdjustmentHintsMode::Prefix,
                     adjustment_hints_hide_outside_unsafe: false,
                     implicit_drop_hints: false,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index 6c0aa19f574..b17186f8d7b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -1137,6 +1137,7 @@ impl flags::AnalysisStats {
                     },
                     chaining_hints: true,
                     adjustment_hints: ide::AdjustmentHints::Always,
+                    adjustment_hints_disable_reborrows: true,
                     adjustment_hints_mode: ide::AdjustmentHintsMode::Postfix,
                     adjustment_hints_hide_outside_unsafe: false,
                     closure_return_type_hints: ide::ClosureReturnTypeHints::Always,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index d4cd56dc55b..c2252185a3a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -226,6 +226,14 @@ config_data! {
         inlayHints_discriminantHints_enable: DiscriminantHintsDef =
             DiscriminantHintsDef::Never,
 
+        /// Disable reborrows in expression adjustments inlay hints.
+        ///
+        /// Reborrows are a pair of a builtin deref then borrow, i.e. `&*`. They are inserted by the compiler but are mostly useless to the programmer.
+        ///
+        /// Note: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed.
+        inlayHints_expressionAdjustmentHints_disableReborrows: bool =
+            true,
+
         /// Show inlay hints for type adjustments.
         inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef =
             AdjustmentHintsDef::Never,
@@ -1888,12 +1896,14 @@ impl Config {
                 AdjustmentHintsDef::Always => ide::AdjustmentHints::Always,
                 AdjustmentHintsDef::Never => match self.inlayHints_reborrowHints_enable() {
                     ReborrowHintsDef::Always | ReborrowHintsDef::Mutable => {
-                        ide::AdjustmentHints::ReborrowOnly
+                        ide::AdjustmentHints::BorrowsOnly
                     }
                     ReborrowHintsDef::Never => ide::AdjustmentHints::Never,
                 },
-                AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly,
+                AdjustmentHintsDef::Borrows => ide::AdjustmentHints::BorrowsOnly,
             },
+            adjustment_hints_disable_reborrows: *self
+                .inlayHints_expressionAdjustmentHints_disableReborrows(),
             adjustment_hints_mode: match self.inlayHints_expressionAdjustmentHints_mode() {
                 AdjustmentHintsModeDef::Prefix => ide::AdjustmentHintsMode::Prefix,
                 AdjustmentHintsModeDef::Postfix => ide::AdjustmentHintsMode::Postfix,
@@ -2822,7 +2832,8 @@ enum ReborrowHintsDef {
 #[derive(Serialize, Deserialize, Debug, Clone)]
 #[serde(rename_all = "snake_case")]
 enum AdjustmentHintsDef {
-    Reborrow,
+    #[serde(alias = "Reborrow")]
+    Borrows,
     #[serde(with = "true_or_always")]
     #[serde(untagged)]
     Always,
diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
index 6ee956fe0db..9a51212462d 100644
--- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
+++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
@@ -959,6 +959,17 @@ Default: `"never"`
 Show enum variant discriminant hints.
 
 
+## rust-analyzer.inlayHints.expressionAdjustmentHints.disableReborrows {#inlayHints.expressionAdjustmentHints.disableReborrows}
+
+Default: `true`
+
+Disable reborrows in expression adjustments inlay hints.
+
+Reborrows are a pair of a builtin deref then borrow, i.e. `&*`. They are inserted by the compiler but are mostly useless to the programmer.
+
+Note: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed.
+
+
 ## rust-analyzer.inlayHints.expressionAdjustmentHints.enable {#inlayHints.expressionAdjustmentHints.enable}
 
 Default: `"never"`
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 4975ca85867..2b2e25e11c8 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -2212,6 +2212,16 @@
             {
                 "title": "Inlay Hints",
                 "properties": {
+                    "rust-analyzer.inlayHints.expressionAdjustmentHints.disableReborrows": {
+                        "markdownDescription": "Disable reborrows in expression adjustments inlay hints.\n\nReborrows are a pair of a builtin deref then borrow, i.e. `&*`. They are inserted by the compiler but are mostly useless to the programmer.\n\nNote: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed.",
+                        "default": true,
+                        "type": "boolean"
+                    }
+                }
+            },
+            {
+                "title": "Inlay Hints",
+                "properties": {
                     "rust-analyzer.inlayHints.expressionAdjustmentHints.enable": {
                         "markdownDescription": "Show inlay hints for type adjustments.",
                         "default": "never",