Unnamed repository; edit this file 'description' to name the repository.
Simplify bind pat filtering
Lukas Wirth 2023-05-13
parent 730286b · commit edd60f7
-rw-r--r--crates/ide/src/inlay_hints/bind_pat.rs103
1 files changed, 32 insertions, 71 deletions
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index f98cc129a9..3d5122a7cf 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -3,7 +3,7 @@
//! fn f(a: i32, b: i32) -> i32 { a + b }
//! let _x /* i32 */= f(4, 4);
//! ```
-use hir::{Semantics, TypeInfo};
+use hir::Semantics;
use ide_db::{base_db::FileId, famous_defs::FamousDefs, RootDatabase};
use itertools::Itertools;
@@ -28,11 +28,41 @@ pub(super) fn hints(
return None;
}
+ let parent = pat.syntax().parent()?;
+ let type_ascriptable = match_ast! {
+ match parent {
+ ast::Param(it) => {
+ if it.ty().is_some() {
+ return None;
+ }
+ Some(it.colon_token())
+ },
+ ast::LetStmt(it) => {
+ if config.hide_closure_initialization_hints {
+ if let Some(ast::Expr::ClosureExpr(closure)) = it.initializer() {
+ if closure_has_block_body(&closure) {
+ return None;
+ }
+ }
+ }
+ if it.ty().is_some() {
+ return None;
+ }
+ Some(it.colon_token())
+ },
+ _ => None
+ }
+ };
+
let descended = sema.descend_node_into_attributes(pat.clone()).pop();
let desc_pat = descended.as_ref().unwrap_or(pat);
let ty = sema.type_of_binding_in_pat(desc_pat)?;
- if should_not_display_type_hint(sema, config, pat, &ty) {
+ if ty.is_unknown() {
+ return None;
+ }
+
+ if sema.resolve_bind_pat_to_const(pat).is_some() {
return None;
}
@@ -44,11 +74,6 @@ pub(super) fn hints(
return None;
}
- let type_ascriptable = desc_pat.syntax().parent().and_then(|it| {
- ast::LetStmt::cast(it.clone())
- .map(|it| it.colon_token())
- .or_else(|| ast::Param::cast(it).map(|it| it.colon_token()))
- });
let text_edit = if let Some(colon_token) = &type_ascriptable {
ty_to_text_edit(
sema,
@@ -89,57 +114,6 @@ pub(super) fn hints(
Some(())
}
-fn should_not_display_type_hint(
- sema: &Semantics<'_, RootDatabase>,
- config: &InlayHintsConfig,
- bind_pat: &ast::IdentPat,
- pat_ty: &hir::Type,
-) -> bool {
- let db = sema.db;
-
- if pat_ty.is_unknown() {
- return true;
- }
-
- if sema.resolve_bind_pat_to_const(bind_pat).is_some() {
- return true;
- }
-
- for node in bind_pat.syntax().ancestors() {
- match_ast! {
- match node {
- ast::LetStmt(it) => {
- if config.hide_closure_initialization_hints {
- if let Some(ast::Expr::ClosureExpr(closure)) = it.initializer() {
- if closure_has_block_body(&closure) {
- return true;
- }
- }
- }
- return it.ty().is_some()
- },
- // FIXME: We might wanna show type hints in parameters for non-top level patterns as well
- ast::Param(it) => return it.ty().is_some(),
- ast::MatchArm(_) => return pat_is_enum_variant(db, bind_pat, pat_ty),
- ast::LetExpr(_) => return pat_is_enum_variant(db, bind_pat, pat_ty),
- ast::IfExpr(_) => return false,
- ast::WhileExpr(_) => return false,
- ast::ForExpr(it) => {
- // We *should* display hint only if user provided "in {expr}" and we know the type of expr (and it's not unit).
- // Type of expr should be iterable.
- return it.in_token().is_none() ||
- it.iterable()
- .and_then(|iterable_expr| sema.type_of_expr(&iterable_expr))
- .map(TypeInfo::original)
- .map_or(true, |iterable_ty| iterable_ty.is_unknown() || iterable_ty.is_unit())
- },
- _ => (),
- }
- }
- }
- false
-}
-
fn is_named_constructor(
sema: &Semantics<'_, RootDatabase>,
pat: &ast::IdentPat,
@@ -193,19 +167,6 @@ fn is_named_constructor(
(ctor_name == ty_name).then_some(())
}
-fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &hir::Type) -> bool {
- if let Some(hir::Adt::Enum(enum_data)) = pat_ty.as_adt() {
- let pat_text = bind_pat.to_string();
- enum_data
- .variants(db)
- .into_iter()
- .map(|variant| variant.name(db).to_smol_str())
- .any(|enum_name| enum_name == pat_text)
- } else {
- false
- }
-}
-
#[cfg(test)]
mod tests {
// This module also contains tests for super::closure_ret