Unnamed repository; edit this file 'description' to name the repository.
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.
Chayim Refael Friedman 8 months ago
parent e6cd085 · commit eaf7141
-rw-r--r--crates/ide/src/inlay_hints.rs4
-rw-r--r--crates/ide/src/inlay_hints/adjustment.rs49
-rw-r--r--crates/ide/src/static_index.rs1
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs1
-rw-r--r--crates/rust-analyzer/src/config.rs17
-rw-r--r--docs/book/src/configuration_generated.md11
-rw-r--r--editors/code/package.json10
7 files changed, 88 insertions, 5 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index d7d3171664..cc44ae8fc8 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/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/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index e39a5f8889..0fd587a728 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/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/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 14b6529c61..8c3275df1b 100644
--- a/crates/ide/src/static_index.rs
+++ b/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/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 6c0aa19f57..b17186f8d7 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/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/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index d4cd56dc55..c2252185a3 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/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/docs/book/src/configuration_generated.md b/docs/book/src/configuration_generated.md
index 6ee956fe0d..9a51212462 100644
--- a/docs/book/src/configuration_generated.md
+++ b/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/editors/code/package.json b/editors/code/package.json
index 4975ca8586..2b2e25e11c 100644
--- a/editors/code/package.json
+++ b/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",