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.rs50
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::*;