Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/inlay_hints/closure_ret.rs')
| -rw-r--r-- | crates/ide/src/inlay_hints/closure_ret.rs | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/crates/ide/src/inlay_hints/closure_ret.rs b/crates/ide/src/inlay_hints/closure_ret.rs index 61c9c25fe7..9e600b5455 100644 --- a/crates/ide/src/inlay_hints/closure_ret.rs +++ b/crates/ide/src/inlay_hints/closure_ret.rs @@ -2,12 +2,12 @@ //! //! Tests live in [`bind_pat`][super::bind_pat] module. use hir::DisplayTarget; -use ide_db::famous_defs::FamousDefs; +use ide_db::{famous_defs::FamousDefs, text_edit::TextEditBuilder}; use syntax::ast::{self, AstNode}; use crate::{ - inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, ClosureReturnTypeHints, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, + inlay_hints::{closure_has_block_body, label_of_ty, ty_to_text_edit}, }; pub(super) fn hints( @@ -35,8 +35,9 @@ pub(super) fn hints( let param_list = closure.param_list()?; - let closure = sema.descend_node_into_attributes(closure).pop()?; - let ty = sema.type_of_expr(&ast::Expr::ClosureExpr(closure.clone()))?.adjusted(); + let resolve_parent = Some(closure.syntax().text_range()); + let descended_closure = sema.descend_node_into_attributes(closure.clone()).pop()?; + let ty = sema.type_of_expr(&ast::Expr::ClosureExpr(descended_closure.clone()))?.adjusted(); let callable = ty.as_callable(sema.db)?; let ty = callable.return_type(); if arrow.is_none() && ty.is_unit() { @@ -48,23 +49,30 @@ 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, - config, - closure.syntax(), - &ty, - arrow - .as_ref() - .map_or_else(|| param_list.syntax().text_range(), |t| t.text_range()) - .end(), - if arrow.is_none() { " -> " } else { "" }, - ) - } else { - None + + let offset_to_insert_ty = + arrow.as_ref().map_or_else(|| param_list.syntax().text_range(), |t| t.text_range()).end(); + + // Insert braces if necessary + let insert_braces = |builder: &mut TextEditBuilder| { + if !has_block_body { + if let Some(range) = closure.body().map(|b| b.syntax().text_range()) { + builder.insert(range.start(), "{ ".to_owned()); + builder.insert(range.end(), " }".to_owned()); + } + } }; + let text_edit = ty_to_text_edit( + sema, + config, + descended_closure.syntax(), + &ty, + offset_to_insert_ty, + &insert_braces, + if arrow.is_none() { " -> " } else { "" }, + ); + acc.push(InlayHint { range: param_list.syntax().text_range(), kind: InlayKind::Type, @@ -73,14 +81,14 @@ pub(super) fn hints( position: InlayHintPosition::After, pad_left: false, pad_right: false, - resolve_parent: Some(closure.syntax().text_range()), + resolve_parent, }); Some(()) } #[cfg(test)] mod tests { - use crate::inlay_hints::tests::{check_with_config, DISABLED_CONFIG}; + use crate::inlay_hints::tests::{DISABLED_CONFIG, check_with_config}; use super::*; |