@@ -8,10 +8,12 @@ use rustc_hir as hir;
88use rustc_hir:: def:: CtorKind ;
99use rustc_hir:: def_id:: DefId ;
1010use rustc_middle:: middle:: stability;
11+ use rustc_middle:: span_bug;
1112use rustc_middle:: ty:: layout:: LayoutError ;
12- use rustc_middle:: ty:: TyCtxt ;
13+ use rustc_middle:: ty:: { Adt , TyCtxt } ;
1314use rustc_span:: hygiene:: MacroKind ;
1415use rustc_span:: symbol:: { kw, sym, Symbol } ;
16+ use rustc_target:: abi:: { Layout , Primitive , TagEncoding , Variants } ;
1517
1618use super :: {
1719 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) {
16211623}
16221624
16231625fn 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+
16241635 if !cx. shared . show_type_layout {
16251636 return ;
16261637 }
@@ -1642,16 +1653,40 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
16421653 <a href=\" https://doc.rust-lang.org/reference/type-layout.html\" >“Type Layout”</a> \
16431654 chapter for details on type layout guarantees.</p></div>"
16441655 ) ;
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+ }
16551690 }
16561691 }
16571692 // This kind of layout error can occur with valid code, e.g. if you try to
0 commit comments