@@ -45,7 +45,7 @@ use hir_def::{
4545 hir:: { BindingAnnotation , BindingId , ExprOrPatId , LabelId , Pat } ,
4646 item_tree:: ItemTreeNode ,
4747 lang_item:: LangItemTarget ,
48- layout:: { self , ReprOptions } ,
48+ layout:: { self , ReprOptions , TargetDataLayout } ,
4949 macro_id_to_def_id,
5050 nameres:: { self , diagnostics:: DefDiagnostic , ModuleOrigin } ,
5151 per_ns:: PerNs ,
@@ -62,7 +62,7 @@ use hir_ty::{
6262 consteval:: { try_const_usize, unknown_const_as_generic, ConstEvalError , ConstExt } ,
6363 diagnostics:: BodyValidationDiagnostic ,
6464 display:: HexifiedConst ,
65- layout:: { Layout as TyLayout , LayoutError , RustcEnumVariantIdx , TagEncoding } ,
65+ layout:: { Layout as TyLayout , RustcEnumVariantIdx , TagEncoding } ,
6666 method_resolution:: { self , TyFingerprint } ,
6767 mir:: { self , interpret_mir} ,
6868 primitive:: UintTy ,
@@ -133,6 +133,7 @@ pub use {
133133 } ,
134134 hir_ty:: {
135135 display:: { ClosureStyle , HirDisplay , HirDisplayError , HirWrite } ,
136+ layout:: LayoutError ,
136137 mir:: MirEvalError ,
137138 PointerCast , Safety ,
138139 } ,
@@ -962,7 +963,8 @@ impl Field {
962963 }
963964
964965 pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
965- db. layout_of_ty ( self . ty ( db) . ty . clone ( ) , self . parent . module ( db) . krate ( ) . into ( ) ) . map ( Layout )
966+ db. layout_of_ty ( self . ty ( db) . ty . clone ( ) , self . parent . module ( db) . krate ( ) . into ( ) )
967+ . map ( |layout| Layout ( layout, db. target_data_layout ( self . krate ( db) . into ( ) ) . unwrap ( ) ) )
966968 }
967969
968970 pub fn parent_def ( & self , _db : & dyn HirDatabase ) -> VariantDef {
@@ -1135,23 +1137,8 @@ impl Enum {
11351137 self . variants ( db) . iter ( ) . any ( |v| !matches ! ( v. kind( db) , StructKind :: Unit ) )
11361138 }
11371139
1138- pub fn layout ( self , db : & dyn HirDatabase ) -> Result < ( Layout , usize ) , LayoutError > {
1139- let layout = Adt :: from ( self ) . layout ( db) ?;
1140- let tag_size =
1141- if let layout:: Variants :: Multiple { tag, tag_encoding, .. } = & layout. 0 . variants {
1142- match tag_encoding {
1143- TagEncoding :: Direct => {
1144- let target_data_layout = db
1145- . target_data_layout ( self . module ( db) . krate ( ) . id )
1146- . ok_or ( LayoutError :: TargetLayoutNotAvailable ) ?;
1147- tag. size ( & * target_data_layout) . bytes_usize ( )
1148- }
1149- TagEncoding :: Niche { .. } => 0 ,
1150- }
1151- } else {
1152- 0
1153- } ;
1154- Ok ( ( layout, tag_size) )
1140+ pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
1141+ Adt :: from ( self ) . layout ( db)
11551142 }
11561143}
11571144
@@ -1214,19 +1201,16 @@ impl Variant {
12141201 db. const_eval_discriminant ( self . into ( ) )
12151202 }
12161203
1217- /// Return layout of the variant and tag size of the parent enum.
1218- pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < ( Layout , usize ) , LayoutError > {
1204+ pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
12191205 let parent_enum = self . parent_enum ( db) ;
1220- let ( parent_layout, tag_size) = parent_enum. layout ( db) ?;
1221- Ok ( (
1222- match & parent_layout. 0 . variants {
1223- layout:: Variants :: Multiple { variants, .. } => {
1224- Layout ( Arc :: new ( variants[ RustcEnumVariantIdx ( self . id ) ] . clone ( ) ) )
1225- }
1226- _ => parent_layout,
1227- } ,
1228- tag_size,
1229- ) )
1206+ let parent_layout = parent_enum. layout ( db) ?;
1207+ Ok ( match & parent_layout. 0 . variants {
1208+ layout:: Variants :: Multiple { variants, .. } => Layout (
1209+ Arc :: new ( variants[ RustcEnumVariantIdx ( self . id ) ] . clone ( ) ) ,
1210+ db. target_data_layout ( parent_enum. krate ( db) . into ( ) ) . unwrap ( ) ,
1211+ ) ,
1212+ _ => parent_layout,
1213+ } )
12301214 }
12311215}
12321216
@@ -1259,7 +1243,9 @@ impl Adt {
12591243 if db. generic_params ( self . into ( ) ) . iter ( ) . count ( ) != 0 {
12601244 return Err ( LayoutError :: HasPlaceholder ) ;
12611245 }
1262- db. layout_of_adt ( self . into ( ) , Substitution :: empty ( Interner ) , self . krate ( db) . id ) . map ( Layout )
1246+ let krate = self . krate ( db) . id ;
1247+ db. layout_of_adt ( self . into ( ) , Substitution :: empty ( Interner ) , krate)
1248+ . map ( |layout| Layout ( layout, db. target_data_layout ( krate) . unwrap ( ) ) )
12631249 }
12641250
12651251 /// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -4244,7 +4230,8 @@ impl Type {
42444230 }
42454231
42464232 pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
4247- db. layout_of_ty ( self . ty . clone ( ) , self . env . krate ) . map ( Layout )
4233+ db. layout_of_ty ( self . ty . clone ( ) , self . env . krate )
4234+ . map ( |layout| Layout ( layout, db. target_data_layout ( self . env . krate ) . unwrap ( ) ) )
42484235 }
42494236}
42504237
@@ -4356,7 +4343,7 @@ fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option<ast::Closu
43564343}
43574344
43584345#[ derive( Clone , Debug , Eq , PartialEq ) ]
4359- pub struct Layout ( Arc < TyLayout > ) ;
4346+ pub struct Layout ( Arc < TyLayout > , Arc < TargetDataLayout > ) ;
43604347
43614348impl Layout {
43624349 pub fn size ( & self ) -> u64 {
@@ -4367,8 +4354,8 @@ impl Layout {
43674354 self . 0 . align . abi . bytes ( )
43684355 }
43694356
4370- pub fn niches ( & self , db : & dyn HirDatabase , krate : Crate ) -> Option < u128 > {
4371- Some ( self . 0 . largest_niche ?. available ( & * db . target_data_layout ( krate . id ) ? ) )
4357+ pub fn niches ( & self ) -> Option < u128 > {
4358+ Some ( self . 0 . largest_niche ?. available ( & * self . 1 ) )
43724359 }
43734360
43744361 pub fn field_offset ( & self , idx : usize ) -> Option < u64 > {
@@ -4382,6 +4369,19 @@ impl Layout {
43824369 layout:: FieldsShape :: Arbitrary { ref offsets, .. } => Some ( offsets. get ( idx) ?. bytes ( ) ) ,
43834370 }
43844371 }
4372+
4373+ pub fn enum_tag_size ( & self ) -> Option < usize > {
4374+ let tag_size =
4375+ if let layout:: Variants :: Multiple { tag, tag_encoding, .. } = & self . 0 . variants {
4376+ match tag_encoding {
4377+ TagEncoding :: Direct => tag. size ( & * self . 1 ) . bytes_usize ( ) ,
4378+ TagEncoding :: Niche { .. } => 0 ,
4379+ }
4380+ } else {
4381+ return None ;
4382+ } ;
4383+ Some ( tag_size)
4384+ }
43854385}
43864386
43874387#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
0 commit comments