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)) .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
.map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
.collect::<Vec<_>>(); .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. // Match `Some` variant first.
mark::hit!(option_order); mark::hit!(option_order);
variants.reverse() variants.reverse()

View File

@ -75,7 +75,7 @@ fn existing_from_impl(
let enum_ = variant.parent_enum(sema.db); let enum_ = variant.parent_enum(sema.db);
let krate = enum_.module(sema.db).krate(); 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); 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 /// 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 /// want to make sure that IDE specific paths don't become interesting inside
/// the compiler itself as well. /// 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)] #[allow(non_snake_case)]
impl FamousDefs<'_, '_> { impl FamousDefs<'_, '_> {
@ -362,6 +362,10 @@ pub mod prelude {
pub use prelude::*; pub use prelude::*;
"#; "#;
pub fn core(&self) -> Option<Crate> {
self.find_crate("core")
}
pub(crate) fn core_convert_From(&self) -> Option<Trait> { pub(crate) fn core_convert_From(&self) -> Option<Trait> {
self.find_trait("core:convert:From") 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> { fn find_def(&self, path: &str) -> Option<ScopeDef> {
let db = self.0.db; let db = self.0.db;
let mut path = path.split(':'); let mut path = path.split(':');
let trait_ = path.next_back()?; let trait_ = path.next_back()?;
let std_crate = path.next()?; let std_crate = path.next()?;
let std_crate = if self let std_crate = self.find_crate(std_crate)?;
.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 mut module = std_crate.root_module(db); let mut module = std_crate.root_module(db);
for segment in path { for segment in path {
module = module.children(db).find_map(|child| { module = module.children(db).find_map(|child| {

View File

@ -99,6 +99,9 @@ fn get_chaining_hints(
return None; return None;
} }
let krate = sema.scope(expr.syntax()).module().map(|it| it.krate());
let famous_defs = FamousDefs(&sema, krate);
let mut tokens = expr let mut tokens = expr
.syntax() .syntax()
.siblings_with_tokens(Direction::Next) .siblings_with_tokens(Direction::Next)
@ -128,7 +131,7 @@ fn get_chaining_hints(
acc.push(InlayHint { acc.push(InlayHint {
range: expr.syntax().text_range(), range: expr.syntax().text_range(),
kind: InlayKind::ChainingHint, 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() ty.display_truncated(sema.db, config.max_length).to_string().into()
}), }),
}); });
@ -188,6 +191,9 @@ fn get_bind_pat_hints(
return None; 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())?; let ty = sema.type_of_pat(&pat.clone().into())?;
if should_not_display_type_hint(sema, &pat, &ty) { if should_not_display_type_hint(sema, &pat, &ty) {
@ -196,7 +202,7 @@ fn get_bind_pat_hints(
acc.push(InlayHint { acc.push(InlayHint {
range: pat.syntax().text_range(), range: pat.syntax().text_range(),
kind: InlayKind::TypeHint, 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()), .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>`. /// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`.
fn hint_iterator( fn hint_iterator(
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
famous_defs: &FamousDefs,
config: &InlayHintsConfig, config: &InlayHintsConfig,
ty: &hir::Type, ty: &hir::Type,
) -> Option<SmolStr> { ) -> Option<SmolStr> {
@ -214,11 +221,11 @@ fn hint_iterator(
.last() .last()
.and_then(|strukt| strukt.as_adt())?; .and_then(|strukt| strukt.as_adt())?;
let krate = strukt.krate(db)?; let krate = strukt.krate(db)?;
if krate.display_name(db).as_deref() != Some("core") { if krate != famous_defs.core()? {
return None; return None;
} }
let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; let iter_trait = famous_defs.core_iter_Iterator()?;
let iter_mod = FamousDefs(sema, krate).core_iter()?; let iter_mod = famous_defs.core_iter()?;
// assert this struct comes from `core::iter` // assert this struct comes from `core::iter`
iter_mod.visibility_of(db, &strukt.into()).filter(|&vis| vis == hir::Visibility::Public)?; iter_mod.visibility_of(db, &strukt.into()).filter(|&vis| vis == hir::Visibility::Public)?;
if ty.impls_trait(db, iter_trait, &[]) { if ty.impls_trait(db, iter_trait, &[]) {
@ -230,7 +237,7 @@ fn hint_iterator(
const LABEL_START: &str = "impl Iterator<Item = "; const LABEL_START: &str = "impl Iterator<Item = ";
const LABEL_END: &str = ">"; 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()) .map(|assoc_type_impl| assoc_type_impl.to_string())
.unwrap_or_else(|| { .unwrap_or_else(|| {
ty.display_truncated( ty.display_truncated(