diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-10-14 19:22:16 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-14 19:22:16 +0200 |
| commit | 4dd4d9b489d71b8020eedea1001ad2b0904601be (patch) | |
| tree | 16026c52838f82fa41c454cb4759a71682c68e17 /src/librustdoc/clean | |
| parent | 0233608c67b1c89050b2aa0a30d6c5f703f325f4 (diff) | |
| parent | 64fa12a4fb1447e3368ae2cd08cf75ea576997ea (diff) | |
Rollup merge of #115439 - fmease:rustdoc-priv-repr-transparent-heuristic, r=GuillaumeGomez
rustdoc: hide `#[repr(transparent)]` if it isn't part of the public ABI Fixes #90435. This hides `#[repr(transparent)]` when the non-1-ZST field the struct is "transparent" over is private. CC `@RalfJung` Tentatively nominating it for the release notes, feel free to remove the nomination. `@rustbot` label needs-fcp relnotes A-rustdoc-ui
Diffstat (limited to 'src/librustdoc/clean')
| -rw-r--r-- | src/librustdoc/clean/types.rs | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 517a51867cf..2a54266676d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -713,12 +713,16 @@ impl Item { Some(tcx.visibility(def_id)) } - pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, keep_as_is: bool) -> Vec<String> { + pub(crate) fn attributes( + &self, + tcx: TyCtxt<'_>, + cache: &Cache, + keep_as_is: bool, + ) -> Vec<String> { const ALLOWED_ATTRIBUTES: &[Symbol] = - &[sym::export_name, sym::link_section, sym::no_mangle, sym::repr, sym::non_exhaustive]; + &[sym::export_name, sym::link_section, sym::no_mangle, sym::non_exhaustive]; use rustc_abi::IntegerType; - use rustc_middle::ty::ReprFlags; let mut attrs: Vec<String> = self .attrs @@ -739,20 +743,38 @@ impl Item { } }) .collect(); - if let Some(def_id) = self.def_id() && - !def_id.is_local() && - // This check is needed because `adt_def` will panic if not a compatible type otherwise... - matches!(self.type_(), ItemType::Struct | ItemType::Enum | ItemType::Union) + if !keep_as_is + && let Some(def_id) = self.def_id() + && let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_() { - let repr = tcx.adt_def(def_id).repr(); + let adt = tcx.adt_def(def_id); + let repr = adt.repr(); let mut out = Vec::new(); - if repr.flags.contains(ReprFlags::IS_C) { + if repr.c() { out.push("C"); } - if repr.flags.contains(ReprFlags::IS_TRANSPARENT) { - out.push("transparent"); + if repr.transparent() { + // Render `repr(transparent)` iff the non-1-ZST field is public or at least one + // field is public in case all fields are 1-ZST fields. + let render_transparent = cache.document_private + || adt + .all_fields() + .find(|field| { + let ty = + field.ty(tcx, ty::GenericArgs::identity_for_item(tcx, field.did)); + tcx.layout_of(tcx.param_env(field.did).and(ty)) + .is_ok_and(|layout| !layout.is_1zst()) + }) + .map_or_else( + || adt.all_fields().any(|field| field.vis.is_public()), + |field| field.vis.is_public(), + ); + + if render_transparent { + out.push("transparent"); + } } - if repr.flags.contains(ReprFlags::IS_SIMD) { + if repr.simd() { out.push("simd"); } let pack_s; @@ -777,10 +799,9 @@ impl Item { }; out.push(&int_s); } - if out.is_empty() { - return Vec::new(); + if !out.is_empty() { + attrs.push(format!("#[repr({})]", out.join(", "))); } - attrs.push(format!("#[repr({})]", out.join(", "))); } attrs } |
