@@ -5,15 +5,13 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55use rustc_hir as hir;
66use rustc_hir:: def:: CtorKind ;
77use rustc_hir:: def_id:: DefId ;
8- use rustc_index:: vec:: IndexVec ;
98use rustc_middle:: middle:: stability;
109use rustc_middle:: span_bug;
11- use rustc_middle:: ty:: layout:: { LayoutError , TyAndLayout } ;
10+ use rustc_middle:: ty:: layout:: LayoutError ;
1211use rustc_middle:: ty:: { self , Adt , TyCtxt } ;
1312use rustc_span:: hygiene:: MacroKind ;
1413use rustc_span:: symbol:: { kw, sym, Symbol } ;
15- use rustc_target:: abi:: { LayoutS , Primitive , TagEncoding , VariantIdx , Variants } ;
16- use std:: borrow:: Borrow ;
14+ use rustc_target:: abi:: { Primitive , TagEncoding , Variants } ;
1715use std:: cmp:: Ordering ;
1816use std:: fmt;
1917use std:: rc:: Rc ;
@@ -1940,9 +1938,9 @@ fn document_type_layout<'a, 'cx: 'a>(
19401938) -> impl fmt:: Display + ' a + Captures < ' cx > {
19411939 #[ derive( Template ) ]
19421940 #[ template( path = "type_layout.html" ) ]
1943- struct TypeLayout < ' a , ' cx > {
1944- cx : & ' a Context < ' cx > ,
1945- ty_def_id : DefId ,
1941+ struct TypeLayout < ' cx > {
1942+ variants : Vec < ( Symbol , TypeLayoutSize ) > ,
1943+ type_layout_size : Result < TypeLayoutSize , LayoutError < ' cx > > ,
19461944 }
19471945
19481946 #[ derive( Template ) ]
@@ -1953,62 +1951,61 @@ fn document_type_layout<'a, 'cx: 'a>(
19531951 size : u64 ,
19541952 }
19551953
1956- impl < ' a , ' cx : ' a > TypeLayout < ' a , ' cx > {
1957- fn variants < ' b : ' a > ( & ' b self ) -> Option < & ' b IndexVec < VariantIdx , LayoutS > > {
1958- if let Variants :: Multiple { variants, .. } =
1959- self . type_layout ( ) . unwrap ( ) . layout . variants ( ) && !variants. is_empty ( ) {
1960- Some ( & variants)
1961- } else {
1962- None
1963- }
1964- }
1965- fn type_layout < ' b : ' a > ( & ' b self ) -> Result < TyAndLayout < ' cx > , LayoutError < ' cx > > {
1966- let tcx = self . cx . tcx ( ) ;
1967- let param_env = tcx. param_env ( self . ty_def_id ) ;
1968- let ty = tcx. type_of ( self . ty_def_id ) . subst_identity ( ) ;
1969- tcx. layout_of ( param_env. and ( ty) )
1954+ display_fn ( move |f| {
1955+ if !cx. shared . show_type_layout {
1956+ return Ok ( ( ) ) ;
19701957 }
1971- fn variant_name < ' b : ' a > ( & ' b self , index : VariantIdx ) -> Symbol {
1972- let Adt ( adt, _) = self . type_layout ( ) . unwrap ( ) . ty . kind ( ) else {
1973- span_bug ! ( self . cx. tcx( ) . def_span( self . ty_def_id) , "not an adt" )
1974- } ;
1975- adt. variant ( index) . name
1976- }
1977- fn tag_size < ' b : ' a > ( & ' b self ) -> u64 {
1978- if let Variants :: Multiple { variants, tag, tag_encoding, .. } =
1979- self . type_layout ( ) . unwrap ( ) . layout . variants ( ) && !variants. is_empty ( ) {
1980- if let TagEncoding :: Niche { .. } = tag_encoding {
1981- 0
1982- } else if let Primitive :: Int ( i, _) = tag. primitive ( ) {
1983- i. size ( ) . bytes ( )
1984- } else {
1985- span_bug ! ( self . cx. tcx( ) . def_span( self . ty_def_id) , "tag is neither niche nor int" )
1986- }
1958+
1959+ let variants = {
1960+ let tcx = cx. tcx ( ) ;
1961+ let param_env = tcx. param_env ( ty_def_id) ;
1962+ let ty = tcx. type_of ( ty_def_id) . subst_identity ( ) ;
1963+ let type_layout = tcx. layout_of ( param_env. and ( ty) ) ;
1964+ if let Ok ( type_layout) = type_layout &&
1965+ let Variants :: Multiple { variants, tag, tag_encoding, .. } =
1966+ type_layout. layout . variants ( ) &&
1967+ !variants. is_empty ( )
1968+ {
1969+ let tag_size =
1970+ if let TagEncoding :: Niche { .. } = tag_encoding {
1971+ 0
1972+ } else if let Primitive :: Int ( i, _) = tag. primitive ( ) {
1973+ i. size ( ) . bytes ( )
1974+ } else {
1975+ span_bug ! ( cx. tcx( ) . def_span( ty_def_id) , "tag is neither niche nor int" )
1976+ } ;
1977+ let variants = variants
1978+ . iter_enumerated ( )
1979+ . map ( |( variant_idx, variant_layout) | {
1980+ let Adt ( adt, _) = type_layout. ty . kind ( ) else {
1981+ span_bug ! ( cx. tcx( ) . def_span( ty_def_id) , "not an adt" )
1982+ } ;
1983+ let name = adt. variant ( variant_idx) . name ;
1984+ let is_unsized = variant_layout. abi . is_unsized ( ) ;
1985+ let is_uninhabited = variant_layout. abi . is_uninhabited ( ) ;
1986+ let size = variant_layout. size . bytes ( ) - tag_size;
1987+ let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size } ;
1988+ ( name, type_layout_size)
1989+ } ) . collect ( ) ;
1990+ variants
19871991 } else {
1988- 0
1992+ Vec :: new ( )
19891993 }
1990- }
1991- fn write_size < ' b : ' a > (
1992- & ' b self ,
1993- layout : & ' b LayoutS ,
1994- tag_size : u64 ,
1995- ) -> impl fmt :: Display + Captures < ' cx > + Captures < ' b > {
1996- display_fn ( move |f | {
1994+ } ;
1995+
1996+ let type_layout_size = {
1997+ let tcx = cx . tcx ( ) ;
1998+ let param_env = tcx . param_env ( ty_def_id ) ;
1999+ let ty = tcx . type_of ( ty_def_id ) . subst_identity ( ) ;
2000+ tcx . layout_of ( param_env . and ( ty ) ) . map ( |layout | {
19972001 let is_unsized = layout. abi . is_unsized ( ) ;
19982002 let is_uninhabited = layout. abi . is_uninhabited ( ) ;
1999- let size = layout. size . bytes ( ) - tag_size;
2000- TypeLayoutSize { is_unsized, is_uninhabited, size } . render_into ( f) . unwrap ( ) ;
2001- Ok ( ( ) )
2003+ let size = layout. size . bytes ( ) ;
2004+ TypeLayoutSize { is_unsized, is_uninhabited, size }
20022005 } )
2003- }
2004- }
2005-
2006- display_fn ( move |f| {
2007- if !cx. shared . show_type_layout {
2008- return Ok ( ( ) ) ;
2009- }
2006+ } ;
20102007
2011- Ok ( TypeLayout { cx , ty_def_id } . render_into ( f) . unwrap ( ) )
2008+ Ok ( TypeLayout { variants , type_layout_size } . render_into ( f) . unwrap ( ) )
20122009 } )
20132010}
20142011
0 commit comments