Skip to content

Commit

Permalink
Rollup merge of rust-lang#86263 - fee1-dead:rustdoc-layout-variants, …
Browse files Browse the repository at this point in the history
…r=camelid

Rustdoc: Report Layout of enum variants

Followup of rust-lang#83501, Fixes rust-lang#86253.

cc `@camelid`

`@rustbot` label A-rustdoc
  • Loading branch information
jackh726 authored Sep 8, 2021
2 parents c9db3e0 + c0451f7 commit 2f2aed1
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
57 changes: 46 additions & 11 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ use rustc_hir as hir;
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::stability;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{Adt, TyCtxt};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants};

use super::{
collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl,
Expand Down Expand Up @@ -1621,6 +1623,15 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) {
}

fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
fn write_size_of_layout(w: &mut Buffer, layout: &Layout, tag_size: u64) {
if layout.abi.is_unsized() {
write!(w, "(unsized)");
} else {
let bytes = layout.size.bytes() - tag_size;
write!(w, "{size} byte{pl}", size = bytes, pl = if bytes == 1 { "" } else { "s" },);
}
}

if !cx.shared.show_type_layout {
return;
}
Expand All @@ -1642,16 +1653,40 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
<a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \
chapter for details on type layout guarantees.</p></div>"
);
if ty_layout.layout.abi.is_unsized() {
writeln!(w, "<p><strong>Size:</strong> (unsized)</p>");
} else {
let bytes = ty_layout.layout.size.bytes();
writeln!(
w,
"<p><strong>Size:</strong> {size} byte{pl}</p>",
size = bytes,
pl = if bytes == 1 { "" } else { "s" },
);
w.write_str("<p><strong>Size:</strong> ");
write_size_of_layout(w, ty_layout.layout, 0);
writeln!(w, "</p>");
if let Variants::Multiple { variants, tag, tag_encoding, .. } =
&ty_layout.layout.variants
{
if !variants.is_empty() {
w.write_str(
"<p><strong>Size for each variant:</strong></p>\
<ul>",
);

let adt = if let Adt(adt, _) = ty_layout.ty.kind() {
adt
} else {
span_bug!(tcx.def_span(ty_def_id), "not an adt")
};

let tag_size = if let TagEncoding::Niche { .. } = tag_encoding {
0
} else if let Primitive::Int(i, _) = tag.value {
i.size().bytes()
} else {
span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int")
};

for (index, layout) in variants.iter_enumerated() {
let ident = adt.variants[index].ident;
write!(w, "<li><code>{name}</code>: ", name = ident);
write_size_of_layout(w, layout, tag_size);
writeln!(w, "</li>");
}
w.write_str("</ul>");
}
}
}
// This kind of layout error can occur with valid code, e.g. if you try to
Expand Down
18 changes: 18 additions & 0 deletions src/test/rustdoc/type-layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,21 @@ pub struct Unsized([u8]);

// @!has type_layout/trait.MyTrait.html 'Size: '
pub trait MyTrait {}

// @has type_layout/enum.Variants.html 'Size: '
// @has - '2 bytes'
// @has - '<code>A</code>: 0 bytes'
// @has - '<code>B</code>: 1 byte'
pub enum Variants {
A,
B(u8),
}

// @has type_layout/enum.WithNiche.html 'Size: '
// @has - //p '4 bytes'
// @has - '<code>None</code>: 0 bytes'
// @has - '<code>Some</code>: 4 bytes'
pub enum WithNiche {
None,
Some(std::num::NonZeroU32),
}

0 comments on commit 2f2aed1

Please sign in to comment.