Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub struct HirFormatter<'a, 'db> {
pub entity_limit: Option<usize>,
/// When rendering functions, whether to show the constraint from the container
show_container_bounds: bool,
render_private_fields: bool,
omit_verbose_types: bool,
closure_style: ClosureStyle,
display_lifetimes: DisplayLifetime,
Expand Down Expand Up @@ -263,6 +264,7 @@ pub trait HirDisplay<'db> {
display_kind,
closure_style,
show_container_bounds,
render_private_fields: true,
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
}
}
Expand All @@ -287,6 +289,7 @@ pub trait HirDisplay<'db> {
display_target,
display_kind: DisplayKind::Diagnostics,
show_container_bounds: false,
render_private_fields: true,
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
}
}
Expand All @@ -312,6 +315,7 @@ pub trait HirDisplay<'db> {
display_target,
display_kind: DisplayKind::Diagnostics,
show_container_bounds: false,
render_private_fields: true,
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
}
}
Expand All @@ -337,6 +341,7 @@ pub trait HirDisplay<'db> {
display_target,
display_kind: DisplayKind::Diagnostics,
show_container_bounds: false,
render_private_fields: true,
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
}
}
Expand Down Expand Up @@ -364,6 +369,7 @@ pub trait HirDisplay<'db> {
display_target: DisplayTarget::from_crate(db, module_id.krate(db)),
display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
show_container_bounds: false,
render_private_fields: true,
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
currently_formatting_bounds: Default::default(),
trait_bounds_need_parens: false,
Expand Down Expand Up @@ -394,6 +400,7 @@ pub trait HirDisplay<'db> {
display_target,
display_kind: DisplayKind::Test,
show_container_bounds: false,
render_private_fields: true,
display_lifetimes: DisplayLifetime::Always,
}
}
Expand All @@ -419,6 +426,7 @@ pub trait HirDisplay<'db> {
display_target,
display_kind: DisplayKind::Diagnostics,
show_container_bounds,
render_private_fields: true,
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
}
}
Expand Down Expand Up @@ -495,6 +503,10 @@ impl<'db> HirFormatter<'_, 'db> {
pub fn show_container_bounds(&self) -> bool {
self.show_container_bounds
}

pub fn render_private_fields(&self) -> bool {
self.render_private_fields
}
}

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -566,6 +578,7 @@ pub struct HirDisplayWrapper<'a, 'db, T> {
display_kind: DisplayKind,
display_target: DisplayTarget,
show_container_bounds: bool,
render_private_fields: bool,
display_lifetimes: DisplayLifetime,
}

Expand Down Expand Up @@ -601,6 +614,7 @@ impl<'db, T: HirDisplay<'db>> HirDisplayWrapper<'_, 'db, T> {
display_target: self.display_target,
closure_style: self.closure_style,
show_container_bounds: self.show_container_bounds,
render_private_fields: self.render_private_fields,
display_lifetimes: self.display_lifetimes,
currently_formatting_bounds: Default::default(),
trait_bounds_need_parens: false,
Expand All @@ -616,6 +630,11 @@ impl<'db, T: HirDisplay<'db>> HirDisplayWrapper<'_, 'db, T> {
self.display_lifetimes = l;
self
}

pub fn with_private_fields(mut self, render: bool) -> Self {
self.render_private_fields = render;
self
}
}

impl<'db, T> fmt::Display for HirDisplayWrapper<'_, 'db, T>
Expand Down
44 changes: 34 additions & 10 deletions crates/hir/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use hir_def::{
TraitSignature, TypeAliasSignature,
},
type_ref::{TypeBound, TypeRef, TypeRefId},
visibility::Visibility,
};
use hir_expand::name::Name;
use hir_ty::{
Expand Down Expand Up @@ -363,28 +364,31 @@ impl<'db> HirDisplay<'db> for Struct {
let def_id = GenericDefId::AdtId(AdtId::StructId(self.id));
write_generic_params(def_id, f)?;

let variant_data = self.variant_fields(f.db);
match self.kind(f.db) {
StructKind::Tuple => {
f.write_char('(')?;
let mut it = variant_data.fields().iter().peekable();
let (fields, hidden_fields) = visible_fields(self.fields(f.db), f);
let mut it = fields.iter().peekable();

while let Some((id, _)) = it.next() {
let field = Field { parent: (*self).into(), id };
while let Some(field) = it.next() {
write_visibility(module_id, field.visibility(f.db), f)?;
field.ty(f.db).hir_fmt(f)?;
if it.peek().is_some() {
if it.peek().is_some() || hidden_fields {
f.write_str(", ")?;
}
}
if hidden_fields {
f.write_str("/* … */")?;
}

f.write_char(')')?;
write_where_clause(def_id, f)?;
}
StructKind::Record => {
let has_where_clause = write_where_clause(def_id, f)?;
if let Some(limit) = f.entity_limit {
write_fields(&self.fields(f.db), has_where_clause, limit, false, f)?;
let (fields, hidden_fields) = visible_fields(self.fields(f.db), f);
write_fields(&fields, hidden_fields, has_where_clause, limit, false, f)?;
}
}
StructKind::Unit => _ = write_where_clause(def_id, f)?,
Expand Down Expand Up @@ -421,14 +425,33 @@ impl<'db> HirDisplay<'db> for Union {

let has_where_clause = write_where_clause(def_id, f)?;
if let Some(limit) = f.entity_limit {
write_fields(&self.fields(f.db), has_where_clause, limit, false, f)?;
let (fields, hidden_fields) = visible_fields(self.fields(f.db), f);
write_fields(&fields, hidden_fields, has_where_clause, limit, false, f)?;
}
Ok(())
}
}

fn visible_fields<'db>(fields: Vec<Field>, f: &mut HirFormatter<'_, 'db>) -> (Vec<Field>, bool) {
if f.render_private_fields() {
return (fields, false);
}

let mut hidden_fields = false;
let fields = fields
.into_iter()
.filter(|field| {
let is_public = field.visibility(f.db) == Visibility::Public;
hidden_fields |= !is_public;
is_public
})
.collect();
(fields, hidden_fields)
}

fn write_fields<'db>(
fields: &[Field],
hidden_fields: bool,
has_where_clause: bool,
limit: usize,
in_line: bool,
Expand All @@ -438,7 +461,7 @@ fn write_fields<'db>(
let (indent, separator) = if in_line { ("", ' ') } else { (" ", '\n') };
f.write_char(if !has_where_clause { ' ' } else { separator })?;
if count == 0 {
f.write_str(if fields.is_empty() { "{}" } else { "{ /* … */ }" })?;
f.write_str(if fields.is_empty() && !hidden_fields { "{}" } else { "{ /* … */ }" })?;
} else {
f.write_char('{')?;

Expand All @@ -450,7 +473,7 @@ fn write_fields<'db>(
write!(f, ",{separator}")?;
}

if fields.len() > count {
if fields.len() > count || hidden_fields {
write!(f, "{indent}/* … */{separator}")?;
}
}
Expand Down Expand Up @@ -542,7 +565,8 @@ impl<'db> HirDisplay<'db> for EnumVariant {
}
FieldsShape::Record => {
if let Some(limit) = f.entity_limit {
write_fields(&self.fields(f.db), false, limit, true, f)?;
let (fields, hidden_fields) = visible_fields(self.fields(f.db), f);
write_fields(&fields, hidden_fields, false, limit, true, f)?;
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions crates/ide/src/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,10 @@ pub(crate) fn hover_for_definition(
};
let notable_traits = def_ty.map(|ty| notable_traits(db, &ty)).unwrap_or_default();
let subst_types = subst.map(|subst| subst.types(db));
let render_private_fields = sema.scope(scope_node).is_some_and(|scope| {
def.krate(db)
.is_some_and(|def_crate| should_render_private_fields(db, def_crate, scope.krate()))
});

let (markup, range_map) = render::definition(
sema.db,
Expand All @@ -489,6 +493,7 @@ pub(crate) fn hover_for_definition(
&notable_traits,
macro_arm,
render_extras,
render_private_fields,
subst_types.as_ref(),
config,
edition,
Expand All @@ -508,6 +513,27 @@ pub(crate) fn hover_for_definition(
}
}

/// | Hover location | Definition location | Render private fields? |
/// |---|---:|---:|
/// | Workspace crate | Workspace crate | Yes |
/// | Workspace crate | External/library crate | No |
/// | External/library crate | Same external/library crate | Yes |
/// | External/library crate | Different external/library crate | No |
/// | Anywhere | Same crate as definition | Yes |
fn should_render_private_fields(
db: &RootDatabase,
def_crate: hir::Crate,
hover_crate: hir::Crate,
) -> bool {
let is_workspace_crate = |db: &RootDatabase, krate: hir::Crate| {
let origin = krate.origin(db);
!origin.is_lib() && !origin.is_lang()
};

def_crate == hover_crate
|| is_workspace_crate(db, def_crate) && is_workspace_crate(db, hover_crate)
}

fn notable_traits<'db>(
db: &'db RootDatabase,
ty: &hir::Type<'db>,
Expand Down
30 changes: 18 additions & 12 deletions crates/ide/src/hover/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ pub(super) fn definition(
notable_traits: &[(Trait, Vec<(Option<Type<'_>>, Name)>)],
macro_arm: Option<u32>,
render_extras: bool,
render_private_fields: bool,
subst_types: Option<&Vec<(Symbol, Type<'_>)>>,
config: &HoverConfig<'_>,
edition: Edition,
Expand All @@ -466,22 +467,27 @@ pub(super) fn definition(
let label = match def {
Definition::Trait(trait_) => trait_
.display_limited(db, config.max_trait_assoc_items_count, display_target)
.with_private_fields(render_private_fields)
.to_string(),
Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => adt
.display_limited(db, config.max_fields_count, display_target)
.with_private_fields(render_private_fields)
.to_string(),
Definition::EnumVariant(variant) => variant
.display_limited(db, config.max_fields_count, display_target)
.with_private_fields(render_private_fields)
.to_string(),
Definition::Adt(adt @ Adt::Enum(_)) => adt
.display_limited(db, config.max_enum_variants_count, display_target)
.with_private_fields(render_private_fields)
.to_string(),
Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => {
adt.display_limited(db, config.max_fields_count, display_target).to_string()
}
Definition::EnumVariant(variant) => {
variant.display_limited(db, config.max_fields_count, display_target).to_string()
}
Definition::Adt(adt @ Adt::Enum(_)) => {
adt.display_limited(db, config.max_enum_variants_count, display_target).to_string()
}
Definition::SelfType(impl_def) => {
let self_ty = &impl_def.self_ty(db);
match self_ty.as_adt() {
Some(adt) => {
adt.display_limited(db, config.max_fields_count, display_target).to_string()
}
Some(adt) => adt
.display_limited(db, config.max_fields_count, display_target)
.with_private_fields(render_private_fields)
.to_string(),
None => self_ty.display(db, display_target).to_string(),
}
}
Expand Down
Loading
Loading