From a3a8ad8bc45d87607493d3c07d7e89e54f7b8c11 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 20 Oct 2020 17:38:21 +0200 Subject: [PATCH] Don't rely on display names in inlay_hints --- .../assists/src/handlers/fill_match_arms.rs | 2 +- .../handlers/generate_from_impl_for_enum.rs | 2 +- crates/assists/src/utils.rs | 25 +++++++++++-------- 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 676f5ad9260..eda45f5b3fe 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< .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat)) .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) .collect::>(); - if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() { + if Some(enum_def) == FamousDefs(&ctx.sema, Some(module.krate())).core_option_Option() { // Match `Some` variant first. mark::hit!(option_order); 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 7f04b95725a..674e5a17571 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( let enum_ = variant.parent_enum(sema.db); let krate = enum_.module(sema.db).krate(); - let from_trait = FamousDefs(sema, krate).core_convert_From()?; + let from_trait = FamousDefs(sema, Some(krate)).core_convert_From()?; let enum_type = enum_.ty(sema.db); diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 4e89a7aedb2..1a6b48b4563 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -275,7 +275,7 @@ impl TryEnum { /// somewhat similar to the known paths infra inside hir, but it different; We /// want to make sure that IDE specific paths don't become interesting inside /// the compiler itself as well. -pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Crate); +pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option); #[allow(non_snake_case)] impl FamousDefs<'_, '_> { @@ -362,6 +362,10 @@ pub mod prelude { pub use prelude::*; "#; + pub fn core(&self) -> Option { + self.find_crate("core") + } + pub(crate) fn core_convert_From(&self) -> Option { self.find_trait("core:convert:From") } @@ -399,21 +403,20 @@ pub use prelude::*; } } + fn find_crate(&self, name: &str) -> Option { + let krate = self.1?; + let db = self.0.db; + let res = + krate.dependencies(db).into_iter().find(|dep| dep.name.to_string() == name)?.krate; + Some(res) + } + fn find_def(&self, path: &str) -> Option { let db = self.0.db; let mut path = path.split(':'); let trait_ = path.next_back()?; let std_crate = path.next()?; - let std_crate = if self - .1 - .display_name(db) - .map(|name| name.to_string() == std_crate) - .unwrap_or(false) - { - self.1 - } else { - self.1.dependencies(db).into_iter().find(|dep| dep.name.to_string() == std_crate)?.krate - }; + let std_crate = self.find_crate(std_crate)?; let mut module = std_crate.root_module(db); for segment in path { module = module.children(db).find_map(|child| { diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 56b985e80f0..cccea129af6 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -99,6 +99,9 @@ fn get_chaining_hints( return None; } + let krate = sema.scope(expr.syntax()).module().map(|it| it.krate()); + let famous_defs = FamousDefs(&sema, krate); + let mut tokens = expr .syntax() .siblings_with_tokens(Direction::Next) @@ -128,7 +131,7 @@ fn get_chaining_hints( acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::ChainingHint, - label: hint_iterator(sema, config, &ty).unwrap_or_else(|| { + label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| { ty.display_truncated(sema.db, config.max_length).to_string().into() }), }); @@ -188,6 +191,9 @@ fn get_bind_pat_hints( return None; } + let krate = sema.scope(pat.syntax()).module().map(|it| it.krate()); + let famous_defs = FamousDefs(&sema, krate); + let ty = sema.type_of_pat(&pat.clone().into())?; if should_not_display_type_hint(sema, &pat, &ty) { @@ -196,7 +202,7 @@ fn get_bind_pat_hints( acc.push(InlayHint { range: pat.syntax().text_range(), kind: InlayKind::TypeHint, - label: hint_iterator(sema, config, &ty) + label: hint_iterator(sema, &famous_defs, config, &ty) .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string().into()), }); @@ -206,6 +212,7 @@ fn get_bind_pat_hints( /// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator`. fn hint_iterator( sema: &Semantics, + famous_defs: &FamousDefs, config: &InlayHintsConfig, ty: &hir::Type, ) -> Option { @@ -214,11 +221,11 @@ fn hint_iterator( .last() .and_then(|strukt| strukt.as_adt())?; let krate = strukt.krate(db)?; - if krate.display_name(db).as_deref() != Some("core") { + if krate != famous_defs.core()? { return None; } - let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; - let iter_mod = FamousDefs(sema, krate).core_iter()?; + let iter_trait = famous_defs.core_iter_Iterator()?; + let iter_mod = famous_defs.core_iter()?; // assert this struct comes from `core::iter` iter_mod.visibility_of(db, &strukt.into()).filter(|&vis| vis == hir::Visibility::Public)?; if ty.impls_trait(db, iter_trait, &[]) { @@ -230,7 +237,7 @@ fn hint_iterator( const LABEL_START: &str = "impl Iterator