Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/ide/src/inlay_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -430,7 +431,7 @@ pub enum LifetimeElisionHints {
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AdjustmentHints {
Always,
ReborrowOnly,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note this breaks user configs using the old key

Copy link
Contributor Author

@ChayimFriedman2 ChayimFriedman2 Sep 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the inlay hints parameter, the real config has #[serde(alias)] for this reason.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I just used the pre-release and got an error about unrecognized config though

BorrowsOnly,
Never,
}

Expand Down Expand Up @@ -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,
Expand Down
49 changes: 48 additions & 1 deletion crates/ide/src/inlay_hints/adjustment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -716,6 +731,38 @@ 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)
}
"#,
);
}
Expand Down
1 change: 1 addition & 0 deletions crates/ide/src/static_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions crates/rust-analyzer/src/cli/analysis_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
17 changes: 14 additions & 3 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2822,7 +2832,8 @@ enum ReborrowHintsDef {
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
enum AdjustmentHintsDef {
Reborrow,
#[serde(alias = "Reborrow")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh maybe this must be reborrow? Not sure if rename_all applies to aliases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not. I even thought about that, but somehow still wrote Reborrow. Created #20606 for that.

Borrows,
#[serde(with = "true_or_always")]
#[serde(untagged)]
Always,
Expand Down
11 changes: 11 additions & 0 deletions docs/book/src/configuration_generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
10 changes: 10 additions & 0 deletions editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2209,6 +2209,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": {
Expand Down
Loading