@@ -5,15 +5,13 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5
5
use rustc_hir as hir;
6
6
use rustc_hir:: def:: CtorKind ;
7
7
use rustc_hir:: def_id:: DefId ;
8
- use rustc_index:: vec:: IndexVec ;
9
8
use rustc_middle:: middle:: stability;
10
9
use rustc_middle:: span_bug;
11
- use rustc_middle:: ty:: layout:: { LayoutError , TyAndLayout } ;
10
+ use rustc_middle:: ty:: layout:: LayoutError ;
12
11
use rustc_middle:: ty:: { self , Adt , TyCtxt } ;
13
12
use rustc_span:: hygiene:: MacroKind ;
14
13
use 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 } ;
17
15
use std:: cmp:: Ordering ;
18
16
use std:: fmt;
19
17
use std:: rc:: Rc ;
@@ -1940,9 +1938,9 @@ fn document_type_layout<'a, 'cx: 'a>(
1940
1938
) -> impl fmt:: Display + ' a + Captures < ' cx > {
1941
1939
#[ derive( Template ) ]
1942
1940
#[ 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 > > ,
1946
1944
}
1947
1945
1948
1946
#[ derive( Template ) ]
@@ -1953,62 +1951,61 @@ fn document_type_layout<'a, 'cx: 'a>(
1953
1951
size : u64 ,
1954
1952
}
1955
1953
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 ( ( ) ) ;
1970
1957
}
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
1987
1991
} else {
1988
- 0
1992
+ Vec :: new ( )
1989
1993
}
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 | {
1997
2001
let is_unsized = layout. abi . is_unsized ( ) ;
1998
2002
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 }
2002
2005
} )
2003
- }
2004
- }
2005
-
2006
- display_fn ( move |f| {
2007
- if !cx. shared . show_type_layout {
2008
- return Ok ( ( ) ) ;
2009
- }
2006
+ } ;
2010
2007
2011
- Ok ( TypeLayout { cx , ty_def_id } . render_into ( f) . unwrap ( ) )
2008
+ Ok ( TypeLayout { variants , type_layout_size } . render_into ( f) . unwrap ( ) )
2012
2009
} )
2013
2010
}
2014
2011
0 commit comments