Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #19348 from jnyfah/some-branch
Add text edit support for return type hints on non-block body closures
Lukas Wirth 2025-03-21
parent d305b0b · parent a0638e5 · commit 3edfbcd
-rw-r--r--crates/ide/src/inlay_hints/bind_pat.rs10
-rw-r--r--crates/ide/src/inlay_hints/closure_ret.rs30
2 files changed, 34 insertions, 6 deletions
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index 10cb91713d..632893a025 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -1140,12 +1140,11 @@ fn test() {
#[test]
fn no_edit_for_closure_return_without_body_block() {
- // We can lift this limitation; see FIXME in closure_ret module.
let config = InlayHintsConfig {
closure_return_type_hints: ClosureReturnTypeHints::Always,
..TEST_CONFIG
};
- check_no_edit(
+ check_edit(
config,
r#"
struct S<T>(T);
@@ -1154,6 +1153,13 @@ fn test() {
let f = |a: S<usize>| S(a);
}
"#,
+ expect![[r#"
+ struct S<T>(T);
+ fn test() {
+ let f = || -> i32 { 3 };
+ let f = |a: S<usize>| -> S<S<usize>> { S(a) };
+ }
+ "#]],
);
}
diff --git a/crates/ide/src/inlay_hints/closure_ret.rs b/crates/ide/src/inlay_hints/closure_ret.rs
index 16551b64f7..0014c8127d 100644
--- a/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/crates/ide/src/inlay_hints/closure_ret.rs
@@ -1,8 +1,8 @@
//! Implementation of "closure return type" inlay hints.
//!
//! Tests live in [`bind_pat`][super::bind_pat] module.
-use hir::DisplayTarget;
-use ide_db::famous_defs::FamousDefs;
+use hir::{DisplayTarget, HirDisplay};
+use ide_db::{famous_defs::FamousDefs, text_edit::TextEdit};
use syntax::ast::{self, AstNode};
use crate::{
@@ -48,7 +48,6 @@ pub(super) fn hints(
if arrow.is_none() {
label.prepend_str(" -> ");
}
- // FIXME?: We could provide text edit to insert braces for closures with non-block body.
let text_edit = if has_block_body {
ty_to_text_edit(
sema,
@@ -62,7 +61,30 @@ pub(super) fn hints(
if arrow.is_none() { " -> " } else { "" },
)
} else {
- None
+ Some(config.lazy_text_edit(|| {
+ let body = closure.body();
+ let body_range = match body {
+ Some(body) => body.syntax().text_range(),
+ None => return TextEdit::builder().finish(),
+ };
+ let mut builder = TextEdit::builder();
+ let insert_pos = param_list.syntax().text_range().end();
+
+ let rendered = match sema.scope(closure.syntax()).and_then(|scope| {
+ ty.display_source_code(scope.db, scope.module().into(), false).ok()
+ }) {
+ Some(rendered) => rendered,
+ None => return TextEdit::builder().finish(),
+ };
+
+ let arrow_text = if arrow.is_none() { " -> ".to_owned() } else { "".to_owned() };
+ builder.insert(insert_pos, arrow_text);
+ builder.insert(insert_pos, rendered);
+ builder.insert(body_range.start(), "{ ".to_owned());
+ builder.insert(body_range.end(), " }".to_owned());
+
+ builder.finish()
+ }))
};
acc.push(InlayHint {