diff options
-rw-r--r-- | crates/assists/src/utils.rs | 13 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 32 |
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 | ||
4 | use std::{iter, ops}; | 4 | use std::{iter, ops}; |
5 | 5 | ||
6 | use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type}; | 6 | use hir::{Adt, Crate, Enum, Module, ScopeDef, Semantics, Trait, Type}; |
7 | use ide_db::RootDatabase; | 7 | use ide_db::RootDatabase; |
8 | use itertools::Itertools; | 8 | use itertools::Itertools; |
9 | use rustc_hash::FxHashSet; | 9 | use 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 @@ | |||
1 | use assists::utils::FamousDefs; | 1 | use assists::utils::FamousDefs; |
2 | use hir::{known, Adt, AssocItem, Callable, HirDisplay, Semantics, Type}; | 2 | use hir::{known, HirDisplay, Semantics}; |
3 | use ide_db::RootDatabase; | 3 | use ide_db::RootDatabase; |
4 | use stdx::to_lower_snake_case; | 4 | use stdx::to_lower_snake_case; |
5 | use syntax::{ | 5 | use 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( | |||
208 | fn hint_iterator( | 208 | fn 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 | ||
251 | fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &Type) -> bool { | 247 | fn 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 | |||
264 | fn should_not_display_type_hint( | 260 | fn 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 | ||
317 | fn should_show_param_name_hint( | 313 | fn 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 | ||
387 | fn get_callable(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<Callable> { | 383 | fn 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), |