diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2025-03-21 14:15:06 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-21 14:15:06 +0000 |
| commit | ccefc5ab1bb64419d2e55def97d070ec11274058 (patch) | |
| tree | 3500034d34b9734befdb3d9e07f90dc5cddc92c2 | |
| parent | ceb8425a8205d16def371e68c383c012b2238a20 (diff) | |
| parent | caff951a1cc90130b07d3a0a4caaae24989d36e6 (diff) | |
| download | rust-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.rs | 10 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs | 30 |
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 { |
