Skip to content

Commit eaf7141

Browse files
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.
1 parent e6cd085 commit eaf7141

File tree

7 files changed

+88
-5
lines changed

7 files changed

+88
-5
lines changed

crates/ide/src/inlay_hints.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ pub struct InlayHintsConfig {
306306
pub generic_parameter_hints: GenericParameterHints,
307307
pub chaining_hints: bool,
308308
pub adjustment_hints: AdjustmentHints,
309+
pub adjustment_hints_disable_reborrows: bool,
309310
pub adjustment_hints_mode: AdjustmentHintsMode,
310311
pub adjustment_hints_hide_outside_unsafe: bool,
311312
pub closure_return_type_hints: ClosureReturnTypeHints,
@@ -430,7 +431,7 @@ pub enum LifetimeElisionHints {
430431
#[derive(Clone, Debug, PartialEq, Eq)]
431432
pub enum AdjustmentHints {
432433
Always,
433-
ReborrowOnly,
434+
BorrowsOnly,
434435
Never,
435436
}
436437

@@ -886,6 +887,7 @@ mod tests {
886887
closure_return_type_hints: ClosureReturnTypeHints::Never,
887888
closure_capture_hints: false,
888889
adjustment_hints: AdjustmentHints::Never,
890+
adjustment_hints_disable_reborrows: false,
889891
adjustment_hints_mode: AdjustmentHintsMode::Prefix,
890892
adjustment_hints_hide_outside_unsafe: false,
891893
binding_mode_hints: false,

crates/ide/src/inlay_hints/adjustment.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,22 @@ pub(super) fn hints(
4747

4848
let descended = sema.descend_node_into_attributes(expr.clone()).pop();
4949
let desc_expr = descended.as_ref().unwrap_or(expr);
50-
let adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
50+
let mut adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
51+
52+
if config.adjustment_hints_disable_reborrows {
53+
// Remove consecutive deref-ref, i.e. reborrows.
54+
let mut i = 0;
55+
while i < adjustments.len().saturating_sub(1) {
56+
let [current, next, ..] = &adjustments[i..] else { unreachable!() };
57+
if matches!(current.kind, Adjust::Deref(None))
58+
&& matches!(next.kind, Adjust::Borrow(AutoBorrow::Ref(_)))
59+
{
60+
adjustments.splice(i..i + 2, []);
61+
} else {
62+
i += 1;
63+
}
64+
}
65+
}
5166

5267
if let ast::Expr::BlockExpr(_) | ast::Expr::IfExpr(_) | ast::Expr::MatchExpr(_) = desc_expr {
5368
// Don't show unnecessary reborrows for these, they will just repeat the inner ones again
@@ -716,6 +731,38 @@ fn hello(it: &&[impl T]) {
716731
//^^(&**
717732
//^^)
718733
}
734+
"#,
735+
);
736+
}
737+
738+
#[test]
739+
fn disable_reborrows() {
740+
check_with_config(
741+
InlayHintsConfig {
742+
adjustment_hints: AdjustmentHints::Always,
743+
adjustment_hints_disable_reborrows: true,
744+
..DISABLED_CONFIG
745+
},
746+
r#"
747+
#![rustc_coherence_is_core]
748+
749+
trait ToOwned {
750+
type Owned;
751+
fn to_owned(&self) -> Self::Owned;
752+
}
753+
754+
struct String;
755+
impl ToOwned for str {
756+
type Owned = String;
757+
fn to_owned(&self) -> Self::Owned { String }
758+
}
759+
760+
fn a(s: &String) {}
761+
762+
fn main() {
763+
let s = "".to_owned();
764+
a(&s)
765+
}
719766
"#,
720767
);
721768
}

crates/ide/src/static_index.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ impl StaticIndex<'_> {
169169
closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
170170
lifetime_elision_hints: crate::LifetimeElisionHints::Never,
171171
adjustment_hints: crate::AdjustmentHints::Never,
172+
adjustment_hints_disable_reborrows: true,
172173
adjustment_hints_mode: AdjustmentHintsMode::Prefix,
173174
adjustment_hints_hide_outside_unsafe: false,
174175
implicit_drop_hints: false,

crates/rust-analyzer/src/cli/analysis_stats.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,7 @@ impl flags::AnalysisStats {
11371137
},
11381138
chaining_hints: true,
11391139
adjustment_hints: ide::AdjustmentHints::Always,
1140+
adjustment_hints_disable_reborrows: true,
11401141
adjustment_hints_mode: ide::AdjustmentHintsMode::Postfix,
11411142
adjustment_hints_hide_outside_unsafe: false,
11421143
closure_return_type_hints: ide::ClosureReturnTypeHints::Always,

crates/rust-analyzer/src/config.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,14 @@ config_data! {
226226
inlayHints_discriminantHints_enable: DiscriminantHintsDef =
227227
DiscriminantHintsDef::Never,
228228

229+
/// Disable reborrows in expression adjustments inlay hints.
230+
///
231+
/// 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.
232+
///
233+
/// Note: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed.
234+
inlayHints_expressionAdjustmentHints_disableReborrows: bool =
235+
true,
236+
229237
/// Show inlay hints for type adjustments.
230238
inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef =
231239
AdjustmentHintsDef::Never,
@@ -1888,12 +1896,14 @@ impl Config {
18881896
AdjustmentHintsDef::Always => ide::AdjustmentHints::Always,
18891897
AdjustmentHintsDef::Never => match self.inlayHints_reborrowHints_enable() {
18901898
ReborrowHintsDef::Always | ReborrowHintsDef::Mutable => {
1891-
ide::AdjustmentHints::ReborrowOnly
1899+
ide::AdjustmentHints::BorrowsOnly
18921900
}
18931901
ReborrowHintsDef::Never => ide::AdjustmentHints::Never,
18941902
},
1895-
AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly,
1903+
AdjustmentHintsDef::Borrows => ide::AdjustmentHints::BorrowsOnly,
18961904
},
1905+
adjustment_hints_disable_reborrows: *self
1906+
.inlayHints_expressionAdjustmentHints_disableReborrows(),
18971907
adjustment_hints_mode: match self.inlayHints_expressionAdjustmentHints_mode() {
18981908
AdjustmentHintsModeDef::Prefix => ide::AdjustmentHintsMode::Prefix,
18991909
AdjustmentHintsModeDef::Postfix => ide::AdjustmentHintsMode::Postfix,
@@ -2822,7 +2832,8 @@ enum ReborrowHintsDef {
28222832
#[derive(Serialize, Deserialize, Debug, Clone)]
28232833
#[serde(rename_all = "snake_case")]
28242834
enum AdjustmentHintsDef {
2825-
Reborrow,
2835+
#[serde(alias = "Reborrow")]
2836+
Borrows,
28262837
#[serde(with = "true_or_always")]
28272838
#[serde(untagged)]
28282839
Always,

docs/book/src/configuration_generated.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,17 @@ Default: `"never"`
959959
Show enum variant discriminant hints.
960960

961961

962+
## rust-analyzer.inlayHints.expressionAdjustmentHints.disableReborrows {#inlayHints.expressionAdjustmentHints.disableReborrows}
963+
964+
Default: `true`
965+
966+
Disable reborrows in expression adjustments inlay hints.
967+
968+
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.
969+
970+
Note: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed.
971+
972+
962973
## rust-analyzer.inlayHints.expressionAdjustmentHints.enable {#inlayHints.expressionAdjustmentHints.enable}
963974

964975
Default: `"never"`

editors/code/package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,6 +2209,16 @@
22092209
}
22102210
}
22112211
},
2212+
{
2213+
"title": "Inlay Hints",
2214+
"properties": {
2215+
"rust-analyzer.inlayHints.expressionAdjustmentHints.disableReborrows": {
2216+
"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.",
2217+
"default": true,
2218+
"type": "boolean"
2219+
}
2220+
}
2221+
},
22122222
{
22132223
"title": "Inlay Hints",
22142224
"properties": {

0 commit comments

Comments
 (0)