diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index bd37ab88966..a7cb1a599f5 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -19,7 +19,7 @@ pub struct InlayHintsConfig { pub type_hints: bool, pub parameter_hints: bool, pub chaining_hints: bool, - pub reborrow_hints: bool, + pub reborrow_hints: ReborrowHints, pub closure_return_type_hints: bool, pub lifetime_elision_hints: LifetimeElisionHints, pub param_names_for_lifetime_elision_hints: bool, @@ -34,6 +34,13 @@ pub enum LifetimeElisionHints { Never, } +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ReborrowHints { + Always, + MutableOnly, + Never, +} + #[derive(Clone, Debug, PartialEq, Eq)] pub enum InlayKind { ChainingHint, @@ -372,18 +379,20 @@ fn reborrow_hints( config: &InlayHintsConfig, expr: &ast::Expr, ) -> Option<()> { - if !config.reborrow_hints { + if config.reborrow_hints == ReborrowHints::Never { return None; } let mutability = sema.is_implicit_reborrow(expr)?; + let label = match mutability { + hir::Mutability::Shared if config.reborrow_hints != ReborrowHints::MutableOnly => "&*", + hir::Mutability::Mut => "&mut *", + _ => return None, + }; acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::ImplicitReborrow, - label: match mutability { - hir::Mutability::Shared => SmolStr::new_inline("&*"), - hir::Mutability::Mut => SmolStr::new_inline("&mut *"), - }, + label: SmolStr::new_inline(label), }); Some(()) } @@ -848,6 +857,7 @@ mod tests { use syntax::{TextRange, TextSize}; use test_utils::extract_annotations; + use crate::inlay_hints::ReborrowHints; use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints}; const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig { @@ -858,7 +868,7 @@ mod tests { lifetime_elision_hints: LifetimeElisionHints::Never, hide_named_constructor_hints: false, closure_return_type_hints: false, - reborrow_hints: false, + reborrow_hints: ReborrowHints::Always, param_names_for_lifetime_elision_hints: false, max_length: None, }; @@ -866,7 +876,7 @@ mod tests { type_hints: true, parameter_hints: true, chaining_hints: true, - reborrow_hints: true, + reborrow_hints: ReborrowHints::Always, closure_return_type_hints: true, lifetime_elision_hints: LifetimeElisionHints::Always, ..DISABLED_CONFIG @@ -2146,7 +2156,11 @@ fn foo(&self, a: &()) -> &() {} #[test] fn hints_implicit_reborrow() { check_with_config( - InlayHintsConfig { reborrow_hints: true, parameter_hints: true, ..DISABLED_CONFIG }, + InlayHintsConfig { + reborrow_hints: ReborrowHints::Always, + parameter_hints: true, + ..DISABLED_CONFIG + }, r#" fn __() { let unique = &mut (); diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index e986331105d..da50a4b8ee5 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -80,7 +80,7 @@ macro_rules! eprintln { folding_ranges::{Fold, FoldKind}, highlight_related::{HighlightRelatedConfig, HighlightedRange}, hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult}, - inlay_hints::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints}, + inlay_hints::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints, ReborrowHints}, join_lines::JoinLinesConfig, markup::Markup, moniker::{MonikerKind, MonikerResult, PackageInformation}, diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index 7bc39c8d1ce..48159f5958d 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -12,12 +12,10 @@ use syntax::{AstNode, SyntaxKind::*, SyntaxToken, TextRange, T}; use crate::{ - hover::hover_for_definition, Analysis, Fold, HoverConfig, HoverDocFormat, HoverResult, - InlayHint, InlayHintsConfig, TryToNav, -}; -use crate::{ + hover::hover_for_definition, moniker::{crate_for_file, def_to_moniker, MonikerResult}, - LifetimeElisionHints, + Analysis, Fold, HoverConfig, HoverDocFormat, HoverResult, InlayHint, InlayHintsConfig, + TryToNav, }; /// A static representation of fully analyzed source code. @@ -112,8 +110,8 @@ fn add_file(&mut self, file_id: FileId) { parameter_hints: true, chaining_hints: true, closure_return_type_hints: true, - lifetime_elision_hints: LifetimeElisionHints::Never, - reborrow_hints: false, + lifetime_elision_hints: crate::LifetimeElisionHints::Never, + reborrow_hints: crate::ReborrowHints::Never, hide_named_constructor_hints: false, param_names_for_lifetime_elision_hints: false, max_length: Some(25), diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index d4257fb2066..f2fade9d487 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -12,8 +12,7 @@ use flycheck::FlycheckConfig; use ide::{ AssistConfig, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode, HighlightRelatedConfig, - HoverConfig, HoverDocFormat, InlayHintsConfig, JoinLinesConfig, LifetimeElisionHints, Snippet, - SnippetScope, + HoverConfig, HoverDocFormat, InlayHintsConfig, JoinLinesConfig, Snippet, SnippetScope, }; use ide_db::{ imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, @@ -268,7 +267,7 @@ struct ConfigData { /// site. inlayHints_parameterHints_enable: bool = "true", /// Whether to show inlay type hints for compiler inserted reborrows. - inlayHints_reborrowHints_enable: bool = "false", + inlayHints_reborrowHints_enable: ReborrowHintsDef = "\"never\"", /// Whether to render leading colons for type hints, and trailing colons for parameter hints. inlayHints_renderColons: bool = "true", /// Whether to show inlay type hints for variables. @@ -986,12 +985,16 @@ pub fn inlay_hints(&self) -> InlayHintsConfig { chaining_hints: self.data.inlayHints_chainingHints_enable, closure_return_type_hints: self.data.inlayHints_closureReturnTypeHints_enable, lifetime_elision_hints: match self.data.inlayHints_lifetimeElisionHints_enable { - LifetimeElisionDef::Always => LifetimeElisionHints::Always, - LifetimeElisionDef::Never => LifetimeElisionHints::Never, - LifetimeElisionDef::SkipTrivial => LifetimeElisionHints::SkipTrivial, + LifetimeElisionDef::Always => ide::LifetimeElisionHints::Always, + LifetimeElisionDef::Never => ide::LifetimeElisionHints::Never, + LifetimeElisionDef::SkipTrivial => ide::LifetimeElisionHints::SkipTrivial, }, hide_named_constructor_hints: self.data.inlayHints_typeHints_hideNamedConstructor, - reborrow_hints: self.data.inlayHints_reborrowHints_enable, + reborrow_hints: match self.data.inlayHints_reborrowHints_enable { + ReborrowHintsDef::Always => ide::ReborrowHints::Always, + ReborrowHintsDef::Never => ide::ReborrowHints::Never, + ReborrowHintsDef::Mutable => ide::ReborrowHints::MutableOnly, + }, param_names_for_lifetime_elision_hints: self .data .inlayHints_lifetimeElisionHints_useParameterNames, @@ -1293,6 +1296,7 @@ fn visit_str(self, value: &str) -> Result { mod de_unit_v { named_unit_variant!(all); named_unit_variant!(skip_trivial); + named_unit_variant!(mutable); } #[derive(Deserialize, Debug, Clone, Copy)] @@ -1404,6 +1408,17 @@ enum LifetimeElisionDef { SkipTrivial, } +#[derive(Deserialize, Debug, Clone)] +#[serde(untagged)] +enum ReborrowHintsDef { + #[serde(deserialize_with = "true_or_always")] + Always, + #[serde(deserialize_with = "false_or_never")] + Never, + #[serde(deserialize_with = "de_unit_v::mutable")] + Mutable, +} + #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "snake_case")] enum ImportPrefixDef { @@ -1675,6 +1690,15 @@ macro_rules! set { "Only show lifetime elision hints if a return type is involved." ], }, + "ReborrowHintsDef" => set! { + "type": ["string", "boolean"], + "enum": ["always", "never", "mutable"], + "enumDescriptions": [ + "Always show reborrow hints.", + "Never show reborrow hints.", + "Only show mutable reborrow hints." + ], + }, "CargoFeatures" => set! { "type": ["string", "array"], "items": { "type": "string" }, diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc index 61c5867e73a..c6fa55c05b3 100644 --- a/docs/user/generated_config.adoc +++ b/docs/user/generated_config.adoc @@ -375,7 +375,7 @@ Maximum length for inlay hints. Set to null to have an unlimited length. Whether to show function parameter name inlay hints at the call site. -- -[[rust-analyzer.inlayHints.reborrowHints.enable]]rust-analyzer.inlayHints.reborrowHints.enable (default: `false`):: +[[rust-analyzer.inlayHints.reborrowHints.enable]]rust-analyzer.inlayHints.reborrowHints.enable (default: `"never"`):: + -- Whether to show inlay type hints for compiler inserted reborrows. diff --git a/editors/code/package.json b/editors/code/package.json index c6f4bc6ce30..1cc510758f3 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -823,8 +823,21 @@ }, "rust-analyzer.inlayHints.reborrowHints.enable": { "markdownDescription": "Whether to show inlay type hints for compiler inserted reborrows.", - "default": false, - "type": "boolean" + "default": "never", + "type": [ + "string", + "boolean" + ], + "enum": [ + "always", + "never", + "mutable" + ], + "enumDescriptions": [ + "Always show reborrow hints.", + "Never show reborrow hints.", + "Only show mutable reborrow hints." + ] }, "rust-analyzer.inlayHints.renderColons": { "markdownDescription": "Whether to render leading colons for type hints, and trailing colons for parameter hints.",