diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 98d5efb0f34d..bc44b71d6678 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -44,6 +44,7 @@ mod param_name; mod placeholders; mod ra_fixture; mod range_exclusive; +mod try_expr; // Feature: Inlay Hints // @@ -252,6 +253,7 @@ fn hints( file_id.edition(sema.db), ), ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, famous_defs, config, it), + ast::Expr::TryExpr(it) => try_expr::hints(hints, famous_defs, config, it), ast::Expr::Literal(it) => ra_fixture::hints(hints, famous_defs.0, file_id, config, it), _ => Some(()), } @@ -339,6 +341,7 @@ pub struct InlayHintsConfig<'a> { pub hide_closure_initialization_hints: bool, pub hide_closure_parameter_hints: bool, pub range_exclusive_hints: bool, + pub try_expr_hints: bool, pub closure_style: ClosureStyle, pub max_length: Option, pub closing_brace_hints_min_lines: Option, @@ -966,6 +969,7 @@ mod tests { implicit_drop_hints: false, implied_dyn_trait_hints: false, range_exclusive_hints: false, + try_expr_hints: false, ra_fixture: RaFixtureConfig::default(), }; pub(super) const TEST_CONFIG: InlayHintsConfig<'_> = InlayHintsConfig { diff --git a/crates/ide/src/inlay_hints/try_expr.rs b/crates/ide/src/inlay_hints/try_expr.rs new file mode 100644 index 000000000000..62bc7b4e3bf8 --- /dev/null +++ b/crates/ide/src/inlay_hints/try_expr.rs @@ -0,0 +1,62 @@ +//! Implementation of "try expr" inlay hints: +//! ```ignore +//! val.foo()/* .try */?.bar()/* .try */? +//! ``` +//! This can avoid try-expr not being obvious enough +use ide_db::famous_defs::FamousDefs; +use syntax::{SyntaxToken, ast}; + +use crate::{InlayHint, InlayHintsConfig}; + +pub(super) fn hints( + acc: &mut Vec, + FamousDefs(_sema, _): &FamousDefs<'_, '_>, + config: &InlayHintsConfig<'_>, + expr: ast::TryExpr, +) -> Option<()> { + config + .try_expr_hints + .then(|| { + expr.question_mark_token().map(|token| { + acc.push(inlay_hint(token)); + }) + }) + .flatten() +} + +fn inlay_hint(token: SyntaxToken) -> InlayHint { + InlayHint { + range: token.text_range(), + position: crate::InlayHintPosition::Before, + pad_left: false, + pad_right: false, + kind: crate::InlayKind::RangeExclusive, + label: crate::InlayHintLabel::from(".try"), + text_edit: None, + resolve_parent: None, + } +} + +#[cfg(test)] +mod tests { + use crate::{ + InlayHintsConfig, + inlay_hints::tests::{DISABLED_CONFIG, check_with_config}, + }; + + #[test] + fn basic_works() { + check_with_config( + InlayHintsConfig { try_expr_hints: true, ..DISABLED_CONFIG }, + r#" +fn main() { + foo.x()? + //^ .try + .bar()? + //^ .try + .await?; + //^ .try +}"#, + ); + } +} diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 073f2875f591..1ea0ca13e4d9 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -1416,6 +1416,7 @@ impl flags::AnalysisStats { closing_brace_hints_min_lines: Some(20), fields_to_resolve: InlayFieldsToResolve::empty(), range_exclusive_hints: true, + try_expr_hints: true, ra_fixture: RaFixtureConfig::default(), }, analysis.editioned_file_id_to_vfs(file_id), diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 3ba0e47f14bc..573e82f6b610 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -296,6 +296,9 @@ config_data! { /// Whether to render leading colons for type hints, and trailing colons for parameter hints. inlayHints_renderColons: bool = true, + /// Show try-expr inlay hints (e.g `foo()?;` -> `foo().try?;`). + inlayHints_tryExpressionHints_enable: bool = false, + /// Show inlay type hints for variables. inlayHints_typeHints_enable: bool = true, @@ -2173,6 +2176,7 @@ impl Config { implicit_drop_hints: self.inlayHints_implicitDrops_enable().to_owned(), implied_dyn_trait_hints: self.inlayHints_impliedDynTraitHints_enable().to_owned(), range_exclusive_hints: self.inlayHints_rangeExclusiveHints_enable().to_owned(), + try_expr_hints: self.inlayHints_tryExpressionHints_enable().to_owned(), ra_fixture: self.ra_fixture(minicore), } } diff --git a/docs/book/src/configuration_generated.md b/docs/book/src/configuration_generated.md index 4df17d77edfb..1e5f24e084e4 100644 --- a/docs/book/src/configuration_generated.md +++ b/docs/book/src/configuration_generated.md @@ -1150,6 +1150,13 @@ Default: `true` Whether to render leading colons for type hints, and trailing colons for parameter hints. +## rust-analyzer.inlayHints.tryExpressionHints.enable {#inlayHints.tryExpressionHints.enable} + +Default: `false` + +Show try-expr inlay hints (e.g `foo()?;` -> `foo().try?;`). + + ## rust-analyzer.inlayHints.typeHints.enable {#inlayHints.typeHints.enable} Default: `true` diff --git a/editors/code/package.json b/editors/code/package.json index d152cfb5861e..d333fe35e3b4 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -2531,6 +2531,16 @@ } } }, + { + "title": "Inlay Hints", + "properties": { + "rust-analyzer.inlayHints.tryExpressionHints.enable": { + "markdownDescription": "Show try-expr inlay hints (e.g `foo()?;` -> `foo().try?;`).", + "default": false, + "type": "boolean" + } + } + }, { "title": "Inlay Hints", "properties": {