@@ -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 , LayoutError , RustcEnumVariantIdx , TagEncoding } ,
65+ layout:: { Layout as TyLayout , LayoutError , RustcEnumVariantIdx , TagEncoding } ,
6666 method_resolution:: { self , TyFingerprint } ,
6767 mir:: { self , interpret_mir} ,
6868 primitive:: UintTy ,
@@ -961,8 +961,8 @@ impl Field {
961961 Type :: new ( db, var_id, ty)
962962 }
963963
964- pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < Arc < Layout > , LayoutError > {
965- db. layout_of_ty ( self . ty ( db) . ty . clone ( ) , self . parent . module ( db) . krate ( ) . into ( ) )
964+ 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 )
966966 }
967967
968968 pub fn parent_def ( & self , _db : & dyn HirDatabase ) -> VariantDef {
@@ -1135,10 +1135,10 @@ impl Enum {
11351135 self . variants ( db) . iter ( ) . any ( |v| !matches ! ( v. kind( db) , StructKind :: Unit ) )
11361136 }
11371137
1138- pub fn layout ( self , db : & dyn HirDatabase ) -> Result < ( Arc < Layout > , usize ) , LayoutError > {
1138+ pub fn layout ( self , db : & dyn HirDatabase ) -> Result < ( Layout , usize ) , LayoutError > {
11391139 let layout = Adt :: from ( self ) . layout ( db) ?;
11401140 let tag_size =
1141- if let layout:: Variants :: Multiple { tag, tag_encoding, .. } = & layout. variants {
1141+ if let layout:: Variants :: Multiple { tag, tag_encoding, .. } = & layout. 0 . variants {
11421142 match tag_encoding {
11431143 TagEncoding :: Direct => {
11441144 let target_data_layout = db
@@ -1219,11 +1219,11 @@ impl Variant {
12191219 let parent_enum = self . parent_enum ( db) ;
12201220 let ( parent_layout, tag_size) = parent_enum. layout ( db) ?;
12211221 Ok ( (
1222- match & parent_layout. variants {
1222+ match & parent_layout. 0 . variants {
12231223 layout:: Variants :: Multiple { variants, .. } => {
1224- variants[ RustcEnumVariantIdx ( self . id ) ] . clone ( )
1224+ Layout ( Arc :: new ( variants[ RustcEnumVariantIdx ( self . id ) ] . clone ( ) ) )
12251225 }
1226- _ => ( * parent_layout) . clone ( ) ,
1226+ _ => parent_layout,
12271227 } ,
12281228 tag_size,
12291229 ) )
@@ -1255,11 +1255,11 @@ impl Adt {
12551255 } )
12561256 }
12571257
1258- pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Arc < Layout > , LayoutError > {
1258+ pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
12591259 if db. generic_params ( self . into ( ) ) . iter ( ) . count ( ) != 0 {
12601260 return Err ( LayoutError :: HasPlaceholder ) ;
12611261 }
1262- db. layout_of_adt ( self . into ( ) , Substitution :: empty ( Interner ) , self . krate ( db) . id )
1262+ db. layout_of_adt ( self . into ( ) , Substitution :: empty ( Interner ) , self . krate ( db) . id ) . map ( Layout )
12631263 }
12641264
12651265 /// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -4243,8 +4243,8 @@ impl Type {
42434243 . collect ( )
42444244 }
42454245
4246- pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < Arc < Layout > , LayoutError > {
4247- db. layout_of_ty ( self . ty . clone ( ) , self . env . krate )
4246+ pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
4247+ db. layout_of_ty ( self . ty . clone ( ) , self . env . krate ) . map ( Layout )
42484248 }
42494249}
42504250
@@ -4355,6 +4355,35 @@ fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option<ast::Closu
43554355 }
43564356}
43574357
4358+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
4359+ pub struct Layout ( Arc < TyLayout > ) ;
4360+
4361+ impl Layout {
4362+ pub fn size ( & self ) -> u64 {
4363+ self . 0 . size . bytes ( )
4364+ }
4365+
4366+ pub fn align ( & self ) -> u64 {
4367+ self . 0 . align . abi . bytes ( )
4368+ }
4369+
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 ) ?) )
4372+ }
4373+
4374+ pub fn field_offset ( & self , idx : usize ) -> Option < u64 > {
4375+ match self . 0 . fields {
4376+ layout:: FieldsShape :: Primitive => None ,
4377+ layout:: FieldsShape :: Union ( _) => Some ( 0 ) ,
4378+ layout:: FieldsShape :: Array { stride, count } => {
4379+ let i = u64:: try_from ( idx) . ok ( ) ?;
4380+ ( i < count) . then_some ( ( stride * i) . bytes ( ) )
4381+ }
4382+ layout:: FieldsShape :: Arbitrary { ref offsets, .. } => Some ( offsets. get ( idx) ?. bytes ( ) ) ,
4383+ }
4384+ }
4385+ }
4386+
43584387#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
43594388pub enum BindingMode {
43604389 Move ,
@@ -4506,6 +4535,12 @@ impl HasCrate for Union {
45064535 }
45074536}
45084537
4538+ impl HasCrate for Enum {
4539+ fn krate ( & self , db : & dyn HirDatabase ) -> Crate {
4540+ self . module ( db) . krate ( )
4541+ }
4542+ }
4543+
45094544impl HasCrate for Field {
45104545 fn krate ( & self , db : & dyn HirDatabase ) -> Crate {
45114546 self . parent_def ( db) . module ( db) . krate ( )
0 commit comments