6301: Don't rely on display names in inlay_hints r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-10-20 16:14:40 +00:00 committed by GitHub
commit 5dd99aa016
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 19 deletions

View file

@ -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::<Vec<_>>();
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()

View file

@ -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);

View file

@ -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<Crate>);
#[allow(non_snake_case)]
impl FamousDefs<'_, '_> {
@ -362,6 +362,10 @@ pub mod prelude {
pub use prelude::*;
"#;
pub fn core(&self) -> Option<Crate> {
self.find_crate("core")
}
pub(crate) fn core_convert_From(&self) -> Option<Trait> {
self.find_trait("core:convert:From")
}
@ -399,21 +403,20 @@ pub use prelude::*;
}
}
fn find_crate(&self, name: &str) -> Option<Crate> {
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<ScopeDef> {
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| {

View file

@ -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<Item = Ty>`.
fn hint_iterator(
sema: &Semantics<RootDatabase>,
famous_defs: &FamousDefs,
config: &InlayHintsConfig,
ty: &hir::Type,
) -> Option<SmolStr> {
@ -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<Item = ";
const LABEL_END: &str = ">";
let ty_display = hint_iterator(sema, config, &ty)
let ty_display = hint_iterator(sema, famous_defs, config, &ty)
.map(|assoc_type_impl| assoc_type_impl.to_string())
.unwrap_or_else(|| {
ty.display_truncated(