diff options
| -rw-r--r-- | crates/assists/src/handlers/fill_match_arms.rs | 2 | ||||
| -rw-r--r-- | crates/assists/src/handlers/generate_from_impl_for_enum.rs | 2 | ||||
| -rw-r--r-- | crates/assists/src/utils.rs | 25 | ||||
| -rw-r--r-- | crates/ide/src/inlay_hints.rs | 19 |
4 files changed, 29 insertions, 19 deletions
diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs index 676f5ad92..eda45f5b3 100644 --- a/crates/assists/src/handlers/fill_match_arms.rs +++ b/crates/assists/src/handlers/fill_match_arms.rs | |||
| @@ -59,7 +59,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
| 59 | .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat)) | 59 | .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat)) |
| 60 | .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) | 60 | .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) |
| 61 | .collect::<Vec<_>>(); | 61 | .collect::<Vec<_>>(); |
| 62 | if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() { | 62 | if Some(enum_def) == FamousDefs(&ctx.sema, Some(module.krate())).core_option_Option() { |
| 63 | // Match `Some` variant first. | 63 | // Match `Some` variant first. |
| 64 | mark::hit!(option_order); | 64 | mark::hit!(option_order); |
| 65 | variants.reverse() | 65 | variants.reverse() |
diff --git a/crates/assists/src/handlers/generate_from_impl_for_enum.rs b/crates/assists/src/handlers/generate_from_impl_for_enum.rs index 7f04b9572..674e5a175 100644 --- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs | |||
| @@ -75,7 +75,7 @@ fn existing_from_impl( | |||
| 75 | let enum_ = variant.parent_enum(sema.db); | 75 | let enum_ = variant.parent_enum(sema.db); |
| 76 | let krate = enum_.module(sema.db).krate(); | 76 | let krate = enum_.module(sema.db).krate(); |
| 77 | 77 | ||
| 78 | let from_trait = FamousDefs(sema, krate).core_convert_From()?; | 78 | let from_trait = FamousDefs(sema, Some(krate)).core_convert_From()?; |
| 79 | 79 | ||
| 80 | let enum_type = enum_.ty(sema.db); | 80 | let enum_type = enum_.ty(sema.db); |
| 81 | 81 | ||
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 4e89a7aed..1a6b48b45 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
| @@ -275,7 +275,7 @@ impl TryEnum { | |||
| 275 | /// somewhat similar to the known paths infra inside hir, but it different; We | 275 | /// somewhat similar to the known paths infra inside hir, but it different; We |
| 276 | /// want to make sure that IDE specific paths don't become interesting inside | 276 | /// want to make sure that IDE specific paths don't become interesting inside |
| 277 | /// the compiler itself as well. | 277 | /// the compiler itself as well. |
| 278 | pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Crate); | 278 | pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option<Crate>); |
| 279 | 279 | ||
| 280 | #[allow(non_snake_case)] | 280 | #[allow(non_snake_case)] |
| 281 | impl FamousDefs<'_, '_> { | 281 | impl FamousDefs<'_, '_> { |
| @@ -362,6 +362,10 @@ pub mod prelude { | |||
| 362 | pub use prelude::*; | 362 | pub use prelude::*; |
| 363 | "#; | 363 | "#; |
| 364 | 364 | ||
| 365 | pub fn core(&self) -> Option<Crate> { | ||
| 366 | self.find_crate("core") | ||
| 367 | } | ||
| 368 | |||
| 365 | pub(crate) fn core_convert_From(&self) -> Option<Trait> { | 369 | pub(crate) fn core_convert_From(&self) -> Option<Trait> { |
| 366 | self.find_trait("core:convert:From") | 370 | self.find_trait("core:convert:From") |
| 367 | } | 371 | } |
| @@ -399,21 +403,20 @@ pub use prelude::*; | |||
| 399 | } | 403 | } |
| 400 | } | 404 | } |
| 401 | 405 | ||
| 406 | fn find_crate(&self, name: &str) -> Option<Crate> { | ||
| 407 | let krate = self.1?; | ||
| 408 | let db = self.0.db; | ||
| 409 | let res = | ||
| 410 | krate.dependencies(db).into_iter().find(|dep| dep.name.to_string() == name)?.krate; | ||
| 411 | Some(res) | ||
| 412 | } | ||
| 413 | |||
| 402 | fn find_def(&self, path: &str) -> Option<ScopeDef> { | 414 | fn find_def(&self, path: &str) -> Option<ScopeDef> { |
| 403 | let db = self.0.db; | 415 | let db = self.0.db; |
| 404 | let mut path = path.split(':'); | 416 | let mut path = path.split(':'); |
| 405 | let trait_ = path.next_back()?; | 417 | let trait_ = path.next_back()?; |
| 406 | let std_crate = path.next()?; | 418 | let std_crate = path.next()?; |
| 407 | let std_crate = if self | 419 | let std_crate = self.find_crate(std_crate)?; |
| 408 | .1 | ||
| 409 | .display_name(db) | ||
| 410 | .map(|name| name.to_string() == std_crate) | ||
| 411 | .unwrap_or(false) | ||
| 412 | { | ||
| 413 | self.1 | ||
| 414 | } else { | ||
| 415 | self.1.dependencies(db).into_iter().find(|dep| dep.name.to_string() == std_crate)?.krate | ||
| 416 | }; | ||
| 417 | let mut module = std_crate.root_module(db); | 420 | let mut module = std_crate.root_module(db); |
| 418 | for segment in path { | 421 | for segment in path { |
| 419 | module = module.children(db).find_map(|child| { | 422 | module = module.children(db).find_map(|child| { |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 56b985e80..cccea129a 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
| @@ -99,6 +99,9 @@ fn get_chaining_hints( | |||
| 99 | return None; | 99 | return None; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | let krate = sema.scope(expr.syntax()).module().map(|it| it.krate()); | ||
| 103 | let famous_defs = FamousDefs(&sema, krate); | ||
| 104 | |||
| 102 | let mut tokens = expr | 105 | let mut tokens = expr |
| 103 | .syntax() | 106 | .syntax() |
| 104 | .siblings_with_tokens(Direction::Next) | 107 | .siblings_with_tokens(Direction::Next) |
| @@ -128,7 +131,7 @@ fn get_chaining_hints( | |||
| 128 | acc.push(InlayHint { | 131 | acc.push(InlayHint { |
| 129 | range: expr.syntax().text_range(), | 132 | range: expr.syntax().text_range(), |
| 130 | kind: InlayKind::ChainingHint, | 133 | kind: InlayKind::ChainingHint, |
| 131 | label: hint_iterator(sema, config, &ty).unwrap_or_else(|| { | 134 | label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| { |
| 132 | ty.display_truncated(sema.db, config.max_length).to_string().into() | 135 | ty.display_truncated(sema.db, config.max_length).to_string().into() |
| 133 | }), | 136 | }), |
| 134 | }); | 137 | }); |
| @@ -188,6 +191,9 @@ fn get_bind_pat_hints( | |||
| 188 | return None; | 191 | return None; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| 194 | let krate = sema.scope(pat.syntax()).module().map(|it| it.krate()); | ||
| 195 | let famous_defs = FamousDefs(&sema, krate); | ||
| 196 | |||
| 191 | let ty = sema.type_of_pat(&pat.clone().into())?; | 197 | let ty = sema.type_of_pat(&pat.clone().into())?; |
| 192 | 198 | ||
| 193 | if should_not_display_type_hint(sema, &pat, &ty) { | 199 | if should_not_display_type_hint(sema, &pat, &ty) { |
| @@ -196,7 +202,7 @@ fn get_bind_pat_hints( | |||
| 196 | acc.push(InlayHint { | 202 | acc.push(InlayHint { |
| 197 | range: pat.syntax().text_range(), | 203 | range: pat.syntax().text_range(), |
| 198 | kind: InlayKind::TypeHint, | 204 | kind: InlayKind::TypeHint, |
| 199 | label: hint_iterator(sema, config, &ty) | 205 | label: hint_iterator(sema, &famous_defs, config, &ty) |
| 200 | .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string().into()), | 206 | .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string().into()), |
| 201 | }); | 207 | }); |
| 202 | 208 | ||
| @@ -206,6 +212,7 @@ fn get_bind_pat_hints( | |||
| 206 | /// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`. | 212 | /// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`. |
| 207 | fn hint_iterator( | 213 | fn hint_iterator( |
| 208 | sema: &Semantics<RootDatabase>, | 214 | sema: &Semantics<RootDatabase>, |
| 215 | famous_defs: &FamousDefs, | ||
| 209 | config: &InlayHintsConfig, | 216 | config: &InlayHintsConfig, |
| 210 | ty: &hir::Type, | 217 | ty: &hir::Type, |
| 211 | ) -> Option<SmolStr> { | 218 | ) -> Option<SmolStr> { |
| @@ -214,11 +221,11 @@ fn hint_iterator( | |||
| 214 | .last() | 221 | .last() |
| 215 | .and_then(|strukt| strukt.as_adt())?; | 222 | .and_then(|strukt| strukt.as_adt())?; |
| 216 | let krate = strukt.krate(db)?; | 223 | let krate = strukt.krate(db)?; |
| 217 | if krate.display_name(db).as_deref() != Some("core") { | 224 | if krate != famous_defs.core()? { |
| 218 | return None; | 225 | return None; |
| 219 | } | 226 | } |
| 220 | let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; | 227 | let iter_trait = famous_defs.core_iter_Iterator()?; |
| 221 | let iter_mod = FamousDefs(sema, krate).core_iter()?; | 228 | let iter_mod = famous_defs.core_iter()?; |
| 222 | // assert this struct comes from `core::iter` | 229 | // assert this struct comes from `core::iter` |
| 223 | iter_mod.visibility_of(db, &strukt.into()).filter(|&vis| vis == hir::Visibility::Public)?; | 230 | iter_mod.visibility_of(db, &strukt.into()).filter(|&vis| vis == hir::Visibility::Public)?; |
| 224 | if ty.impls_trait(db, iter_trait, &[]) { | 231 | if ty.impls_trait(db, iter_trait, &[]) { |
| @@ -230,7 +237,7 @@ fn hint_iterator( | |||
| 230 | const LABEL_START: &str = "impl Iterator<Item = "; | 237 | const LABEL_START: &str = "impl Iterator<Item = "; |
| 231 | const LABEL_END: &str = ">"; | 238 | const LABEL_END: &str = ">"; |
| 232 | 239 | ||
| 233 | let ty_display = hint_iterator(sema, config, &ty) | 240 | let ty_display = hint_iterator(sema, famous_defs, config, &ty) |
| 234 | .map(|assoc_type_impl| assoc_type_impl.to_string()) | 241 | .map(|assoc_type_impl| assoc_type_impl.to_string()) |
| 235 | .unwrap_or_else(|| { | 242 | .unwrap_or_else(|| { |
| 236 | ty.display_truncated( | 243 | ty.display_truncated( |
