aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/assists/src/utils.rs13
-rw-r--r--crates/ide/src/inlay_hints.rs32
2 files changed, 26 insertions, 19 deletions
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index c074b8d02..c1847f601 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -3,7 +3,7 @@ pub(crate) mod insert_use;
3 3
4use std::{iter, ops}; 4use std::{iter, ops};
5 5
6use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type}; 6use hir::{Adt, Crate, Enum, Module, ScopeDef, Semantics, Trait, Type};
7use ide_db::RootDatabase; 7use ide_db::RootDatabase;
8use itertools::Itertools; 8use itertools::Itertools;
9use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
@@ -373,6 +373,10 @@ pub use prelude::*;
373 self.find_trait("core:iter:traits:iterator:Iterator") 373 self.find_trait("core:iter:traits:iterator:Iterator")
374 } 374 }
375 375
376 pub fn core_iter(&self) -> Option<Module> {
377 self.find_module("core:iter")
378 }
379
376 fn find_trait(&self, path: &str) -> Option<Trait> { 380 fn find_trait(&self, path: &str) -> Option<Trait> {
377 match self.find_def(path)? { 381 match self.find_def(path)? {
378 hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), 382 hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
@@ -387,6 +391,13 @@ pub use prelude::*;
387 } 391 }
388 } 392 }
389 393
394 fn find_module(&self, path: &str) -> Option<Module> {
395 match self.find_def(path)? {
396 hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(it)) => Some(it),
397 _ => None,
398 }
399 }
400
390 fn find_def(&self, path: &str) -> Option<ScopeDef> { 401 fn find_def(&self, path: &str) -> Option<ScopeDef> {
391 let db = self.0.db; 402 let db = self.0.db;
392 let mut path = path.split(':'); 403 let mut path = path.split(':');
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 7540f56a4..7d716577e 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -1,5 +1,5 @@
1use assists::utils::FamousDefs; 1use assists::utils::FamousDefs;
2use hir::{known, Adt, AssocItem, Callable, HirDisplay, Semantics, Type}; 2use hir::{known, HirDisplay, Semantics};
3use ide_db::RootDatabase; 3use ide_db::RootDatabase;
4use stdx::to_lower_snake_case; 4use stdx::to_lower_snake_case;
5use syntax::{ 5use syntax::{
@@ -120,7 +120,7 @@ fn get_chaining_hints(
120 return None; 120 return None;
121 } 121 }
122 if matches!(expr, ast::Expr::PathExpr(_)) { 122 if matches!(expr, ast::Expr::PathExpr(_)) {
123 if let Some(Adt::Struct(st)) = ty.as_adt() { 123 if let Some(hir::Adt::Struct(st)) = ty.as_adt() {
124 if st.fields(sema.db).is_empty() { 124 if st.fields(sema.db).is_empty() {
125 return None; 125 return None;
126 } 126 }
@@ -208,7 +208,7 @@ fn get_bind_pat_hints(
208fn hint_iterator( 208fn hint_iterator(
209 sema: &Semantics<RootDatabase>, 209 sema: &Semantics<RootDatabase>,
210 config: &InlayHintsConfig, 210 config: &InlayHintsConfig,
211 ty: &Type, 211 ty: &hir::Type,
212) -> Option<SmolStr> { 212) -> Option<SmolStr> {
213 let db = sema.db; 213 let db = sema.db;
214 let strukt = std::iter::successors(Some(ty.clone()), |ty| ty.remove_ref()) 214 let strukt = std::iter::successors(Some(ty.clone()), |ty| ty.remove_ref())
@@ -218,17 +218,13 @@ fn hint_iterator(
218 if krate.declaration_name(db).as_deref() != Some("core") { 218 if krate.declaration_name(db).as_deref() != Some("core") {
219 return None; 219 return None;
220 } 220 }
221 // assert this type comes from `core::iter`
222 strukt
223 .module(db)
224 .path_to_root(db)
225 .into_iter()
226 .rev()
227 .find(|module| module.name(db) == Some(known::iter))?;
228 let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; 221 let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?;
222 let iter_mod = FamousDefs(sema, krate).core_iter()?;
223 // assert this type comes from `core::iter`
224 iter_mod.visibility_of(db, &iter_trait.into()).filter(|&vis| vis == hir::Visibility::Public)?;
229 if ty.impls_trait(db, iter_trait, &[]) { 225 if ty.impls_trait(db, iter_trait, &[]) {
230 let assoc_type_item = iter_trait.items(db).into_iter().find_map(|item| match item { 226 let assoc_type_item = iter_trait.items(db).into_iter().find_map(|item| match item {
231 AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias), 227 hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias),
232 _ => None, 228 _ => None,
233 })?; 229 })?;
234 if let Some(ty) = ty.normalize_trait_assoc_type(db, iter_trait, &[], assoc_type_item) { 230 if let Some(ty) = ty.normalize_trait_assoc_type(db, iter_trait, &[], assoc_type_item) {
@@ -248,8 +244,8 @@ fn hint_iterator(
248 None 244 None
249} 245}
250 246
251fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &Type) -> bool { 247fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &hir::Type) -> bool {
252 if let Some(Adt::Enum(enum_data)) = pat_ty.as_adt() { 248 if let Some(hir::Adt::Enum(enum_data)) = pat_ty.as_adt() {
253 let pat_text = bind_pat.to_string(); 249 let pat_text = bind_pat.to_string();
254 enum_data 250 enum_data
255 .variants(db) 251 .variants(db)
@@ -264,7 +260,7 @@ fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &Typ
264fn should_not_display_type_hint( 260fn should_not_display_type_hint(
265 sema: &Semantics<RootDatabase>, 261 sema: &Semantics<RootDatabase>,
266 bind_pat: &ast::IdentPat, 262 bind_pat: &ast::IdentPat,
267 pat_ty: &Type, 263 pat_ty: &hir::Type,
268) -> bool { 264) -> bool {
269 let db = sema.db; 265 let db = sema.db;
270 266
@@ -272,7 +268,7 @@ fn should_not_display_type_hint(
272 return true; 268 return true;
273 } 269 }
274 270
275 if let Some(Adt::Struct(s)) = pat_ty.as_adt() { 271 if let Some(hir::Adt::Struct(s)) = pat_ty.as_adt() {
276 if s.fields(db).is_empty() && s.name(db).to_string() == bind_pat.to_string() { 272 if s.fields(db).is_empty() && s.name(db).to_string() == bind_pat.to_string() {
277 return true; 273 return true;
278 } 274 }
@@ -316,7 +312,7 @@ fn should_not_display_type_hint(
316 312
317fn should_show_param_name_hint( 313fn should_show_param_name_hint(
318 sema: &Semantics<RootDatabase>, 314 sema: &Semantics<RootDatabase>,
319 callable: &Callable, 315 callable: &hir::Callable,
320 param_name: &str, 316 param_name: &str,
321 argument: &ast::Expr, 317 argument: &ast::Expr,
322) -> bool { 318) -> bool {
@@ -363,7 +359,7 @@ fn is_enum_name_similar_to_param_name(
363 param_name: &str, 359 param_name: &str,
364) -> bool { 360) -> bool {
365 match sema.type_of_expr(argument).and_then(|t| t.as_adt()) { 361 match sema.type_of_expr(argument).and_then(|t| t.as_adt()) {
366 Some(Adt::Enum(e)) => to_lower_snake_case(&e.name(sema.db).to_string()) == param_name, 362 Some(hir::Adt::Enum(e)) => to_lower_snake_case(&e.name(sema.db).to_string()) == param_name,
367 _ => false, 363 _ => false,
368 } 364 }
369} 365}
@@ -384,7 +380,7 @@ fn is_obvious_param(param_name: &str) -> bool {
384 param_name.len() == 1 || is_obvious_param_name 380 param_name.len() == 1 || is_obvious_param_name
385} 381}
386 382
387fn get_callable(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<Callable> { 383fn get_callable(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<hir::Callable> {
388 match expr { 384 match expr {
389 ast::Expr::CallExpr(expr) => sema.type_of_expr(&expr.expr()?)?.as_callable(sema.db), 385 ast::Expr::CallExpr(expr) => sema.type_of_expr(&expr.expr()?)?.as_callable(sema.db),
390 ast::Expr::MethodCallExpr(expr) => sema.resolve_method_call_as_callable(expr), 386 ast::Expr::MethodCallExpr(expr) => sema.resolve_method_call_as_callable(expr),