Merge pull request #20520 from ChayimFriedman2/reborrow

feat: Add an option to remove reborrows from adjustment inlay hints
This commit is contained in:
Shoyu Vanilla (Flint) 2025-08-26 05:48:34 +00:00 committed by GitHub
commit 25adf3464c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 88 additions and 5 deletions

View file

@ -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,

View file

@ -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
@ -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)
}
"#,
);
}

View file

@ -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,

View file

@ -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,

View file

@ -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,