@@ -62,7 +62,7 @@ use hir_ty::{
62
62
consteval:: { try_const_usize, unknown_const_as_generic, ConstEvalError , ConstExt } ,
63
63
diagnostics:: BodyValidationDiagnostic ,
64
64
display:: HexifiedConst ,
65
- layout:: { Layout , LayoutError , RustcEnumVariantIdx , TagEncoding } ,
65
+ layout:: { Layout as TyLayout , LayoutError , RustcEnumVariantIdx , TagEncoding } ,
66
66
method_resolution:: { self , TyFingerprint } ,
67
67
mir:: { self , interpret_mir} ,
68
68
primitive:: UintTy ,
@@ -961,8 +961,8 @@ impl Field {
961
961
Type :: new ( db, var_id, ty)
962
962
}
963
963
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 )
966
966
}
967
967
968
968
pub fn parent_def ( & self , _db : & dyn HirDatabase ) -> VariantDef {
@@ -1135,10 +1135,10 @@ impl Enum {
1135
1135
self . variants ( db) . iter ( ) . any ( |v| !matches ! ( v. kind( db) , StructKind :: Unit ) )
1136
1136
}
1137
1137
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 > {
1139
1139
let layout = Adt :: from ( self ) . layout ( db) ?;
1140
1140
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 {
1142
1142
match tag_encoding {
1143
1143
TagEncoding :: Direct => {
1144
1144
let target_data_layout = db
@@ -1219,11 +1219,11 @@ impl Variant {
1219
1219
let parent_enum = self . parent_enum ( db) ;
1220
1220
let ( parent_layout, tag_size) = parent_enum. layout ( db) ?;
1221
1221
Ok ( (
1222
- match & parent_layout. variants {
1222
+ match & parent_layout. 0 . variants {
1223
1223
layout:: Variants :: Multiple { variants, .. } => {
1224
- variants[ RustcEnumVariantIdx ( self . id ) ] . clone ( )
1224
+ Layout ( Arc :: new ( variants[ RustcEnumVariantIdx ( self . id ) ] . clone ( ) ) )
1225
1225
}
1226
- _ => ( * parent_layout) . clone ( ) ,
1226
+ _ => parent_layout,
1227
1227
} ,
1228
1228
tag_size,
1229
1229
) )
@@ -1255,11 +1255,11 @@ impl Adt {
1255
1255
} )
1256
1256
}
1257
1257
1258
- pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Arc < Layout > , LayoutError > {
1258
+ pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
1259
1259
if db. generic_params ( self . into ( ) ) . iter ( ) . count ( ) != 0 {
1260
1260
return Err ( LayoutError :: HasPlaceholder ) ;
1261
1261
}
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 )
1263
1263
}
1264
1264
1265
1265
/// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -4243,8 +4243,8 @@ impl Type {
4243
4243
. collect ( )
4244
4244
}
4245
4245
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 )
4248
4248
}
4249
4249
}
4250
4250
@@ -4355,6 +4355,35 @@ fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option<ast::Closu
4355
4355
}
4356
4356
}
4357
4357
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
+
4358
4387
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
4359
4388
pub enum BindingMode {
4360
4389
Move ,
@@ -4506,6 +4535,12 @@ impl HasCrate for Union {
4506
4535
}
4507
4536
}
4508
4537
4538
+ impl HasCrate for Enum {
4539
+ fn krate ( & self , db : & dyn HirDatabase ) -> Crate {
4540
+ self . module ( db) . krate ( )
4541
+ }
4542
+ }
4543
+
4509
4544
impl HasCrate for Field {
4510
4545
fn krate ( & self , db : & dyn HirDatabase ) -> Crate {
4511
4546
self . parent_def ( db) . module ( db) . krate ( )
0 commit comments