-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustdoc: hide #[repr(transparent)]
if it isn't part of the public ABI
#115439
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -709,12 +709,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 | ||
|
@@ -735,20 +739,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; | ||
|
@@ -773,10 +795,9 @@ impl Item { | |
}; | ||
out.push(&int_s); | ||
} | ||
if out.is_empty() { | ||
return Vec::new(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The early return wasn't correct. It resulted in us not rendering some attributes like |
||
if !out.is_empty() { | ||
attrs.push(format!("#[repr({})]", out.join(", "))); | ||
} | ||
attrs.push(format!("#[repr({})]", out.join(", "))); | ||
} | ||
attrs | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ use rustdoc_json_types::*; | |
|
||
use crate::clean::{self, ItemId}; | ||
use crate::formats::item_type::ItemType; | ||
use crate::formats::FormatRenderer; | ||
use crate::json::JsonRenderer; | ||
use crate::passes::collect_intra_doc_links::UrlFragment; | ||
|
||
|
@@ -41,7 +42,7 @@ impl JsonRenderer<'_> { | |
}) | ||
.collect(); | ||
let docs = item.opt_doc_value(); | ||
let attrs = item.attributes(self.tcx, true); | ||
let attrs = item.attributes(self.tcx, self.cache(), true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that my patch doesn't affect Rustdoc JSON. We still pass through every inert attribute. Let me know if I that needs changing. |
||
let span = item.span(self.tcx); | ||
let visibility = item.visibility(self.tcx); | ||
let clean::Item { name, item_id, .. } = item; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// aux-crate:attributes=attributes.rs | ||
// edition:2021 | ||
#![crate_name = "user"] | ||
|
||
// @has 'user/struct.NonExhaustive.html' | ||
// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[non_exhaustive]' | ||
pub use attributes::NonExhaustive; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#[non_exhaustive] | ||
pub struct NonExhaustive; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Regression test for <https://github.com/rust-lang/rust/issues/90435>. | ||
// Check that we show `#[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. | ||
|
||
// @has 'repr/struct.ReprTransparentPrivField.html' | ||
// @!has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' | ||
#[repr(transparent)] // private | ||
pub struct ReprTransparentPrivField { | ||
field: u32, // non-1-ZST field | ||
} | ||
|
||
// @has 'repr/struct.ReprTransparentPriv1ZstFields.html' | ||
// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' | ||
#[repr(transparent)] // public | ||
pub struct ReprTransparentPriv1ZstFields { | ||
marker0: Marker, | ||
pub main: u64, // non-1-ZST field | ||
marker1: Marker, | ||
} | ||
|
||
// @has 'repr/struct.ReprTransparentPub1ZstField.html' | ||
// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' | ||
#[repr(transparent)] // public | ||
pub struct ReprTransparentPub1ZstField { | ||
marker0: Marker, | ||
pub marker1: Marker, | ||
} | ||
|
||
struct Marker; // 1-ZST |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure where to place this section, open to suggestions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably the best place to put it right now.