about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-03-21 14:15:06 +0000
committerGitHub <noreply@github.com>2025-03-21 14:15:06 +0000
commitccefc5ab1bb64419d2e55def97d070ec11274058 (patch)
tree3500034d34b9734befdb3d9e07f90dc5cddc92c2
parentceb8425a8205d16def371e68c383c012b2238a20 (diff)
parentcaff951a1cc90130b07d3a0a4caaae24989d36e6 (diff)
downloadrust-ccefc5ab1bb64419d2e55def97d070ec11274058.tar.gz
rust-ccefc5ab1bb64419d2e55def97d070ec11274058.zip
Merge pull request #19348 from jnyfah/some-branch
Add text edit support for return type hints on non-block body closures
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs30
2 files changed, 34 insertions, 6 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
index 10cb91713d2..632893a0252 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
index 16551b64f7e..0014c8127de 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/src/tools/rust-analyzer/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 {