@@ -8,10 +8,12 @@ use rustc_hir as hir;
8
8
use rustc_hir:: def:: CtorKind ;
9
9
use rustc_hir:: def_id:: DefId ;
10
10
use rustc_middle:: middle:: stability;
11
+ use rustc_middle:: span_bug;
11
12
use rustc_middle:: ty:: layout:: LayoutError ;
12
- use rustc_middle:: ty:: TyCtxt ;
13
+ use rustc_middle:: ty:: { Adt , TyCtxt } ;
13
14
use rustc_span:: hygiene:: MacroKind ;
14
15
use rustc_span:: symbol:: { kw, sym, Symbol } ;
16
+ use rustc_target:: abi:: { Layout , Primitive , TagEncoding , Variants } ;
15
17
16
18
use super :: {
17
19
collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl,
@@ -1621,6 +1623,15 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) {
1621
1623
}
1622
1624
1623
1625
fn document_type_layout ( w : & mut Buffer , cx : & Context < ' _ > , ty_def_id : DefId ) {
1626
+ fn write_size_of_layout ( w : & mut Buffer , layout : & Layout , tag_size : u64 ) {
1627
+ if layout. abi . is_unsized ( ) {
1628
+ write ! ( w, "(unsized)" ) ;
1629
+ } else {
1630
+ let bytes = layout. size . bytes ( ) - tag_size;
1631
+ write ! ( w, "{size} byte{pl}" , size = bytes, pl = if bytes == 1 { "" } else { "s" } , ) ;
1632
+ }
1633
+ }
1634
+
1624
1635
if !cx. shared . show_type_layout {
1625
1636
return ;
1626
1637
}
@@ -1642,16 +1653,40 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
1642
1653
<a href=\" https://doc.rust-lang.org/reference/type-layout.html\" >“Type Layout”</a> \
1643
1654
chapter for details on type layout guarantees.</p></div>"
1644
1655
) ;
1645
- if ty_layout. layout . abi . is_unsized ( ) {
1646
- writeln ! ( w, "<p><strong>Size:</strong> (unsized)</p>" ) ;
1647
- } else {
1648
- let bytes = ty_layout. layout . size . bytes ( ) ;
1649
- writeln ! (
1650
- w,
1651
- "<p><strong>Size:</strong> {size} byte{pl}</p>" ,
1652
- size = bytes,
1653
- pl = if bytes == 1 { "" } else { "s" } ,
1654
- ) ;
1656
+ w. write_str ( "<p><strong>Size:</strong> " ) ;
1657
+ write_size_of_layout ( w, ty_layout. layout , 0 ) ;
1658
+ writeln ! ( w, "</p>" ) ;
1659
+ if let Variants :: Multiple { variants, tag, tag_encoding, .. } =
1660
+ & ty_layout. layout . variants
1661
+ {
1662
+ if !variants. is_empty ( ) {
1663
+ w. write_str (
1664
+ "<p><strong>Size for each variant:</strong></p>\
1665
+ <ul>",
1666
+ ) ;
1667
+
1668
+ let adt = if let Adt ( adt, _) = ty_layout. ty . kind ( ) {
1669
+ adt
1670
+ } else {
1671
+ span_bug ! ( tcx. def_span( ty_def_id) , "not an adt" )
1672
+ } ;
1673
+
1674
+ let tag_size = if let TagEncoding :: Niche { .. } = tag_encoding {
1675
+ 0
1676
+ } else if let Primitive :: Int ( i, _) = tag. value {
1677
+ i. size ( ) . bytes ( )
1678
+ } else {
1679
+ span_bug ! ( tcx. def_span( ty_def_id) , "tag is neither niche nor int" )
1680
+ } ;
1681
+
1682
+ for ( index, layout) in variants. iter_enumerated ( ) {
1683
+ let ident = adt. variants [ index] . ident ;
1684
+ write ! ( w, "<li><code>{name}</code>: " , name = ident) ;
1685
+ write_size_of_layout ( w, layout, tag_size) ;
1686
+ writeln ! ( w, "</li>" ) ;
1687
+ }
1688
+ w. write_str ( "</ul>" ) ;
1689
+ }
1655
1690
}
1656
1691
}
1657
1692
// This kind of layout error can occur with valid code, e.g. if you try to
0 commit comments