@@ -45,7 +45,7 @@ use hir_def::{
4545 hir:: { BindingAnnotation , BindingId , ExprOrPatId , LabelId , Pat } ,
4646 item_tree:: ItemTreeNode ,
4747 lang_item:: LangItemTarget ,
48- layout:: ReprOptions ,
48+ layout:: { self , ReprOptions } ,
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_of_ty, Layout , LayoutError } ,
65+ layout:: { layout_of_ty, Layout , LayoutError , RustcEnumVariantIdx , TagEncoding } ,
6666 method_resolution:: { self , TyFingerprint } ,
6767 mir:: { self , interpret_mir} ,
6868 primitive:: UintTy ,
@@ -1089,28 +1089,28 @@ impl Enum {
10891089 Type :: new_for_crate (
10901090 self . id . lookup ( db. upcast ( ) ) . container . krate ( ) ,
10911091 TyBuilder :: builtin ( match db. enum_data ( self . id ) . variant_body_type ( ) {
1092- hir_def :: layout:: IntegerType :: Pointer ( sign) => match sign {
1092+ layout:: IntegerType :: Pointer ( sign) => match sign {
10931093 true => hir_def:: builtin_type:: BuiltinType :: Int (
10941094 hir_def:: builtin_type:: BuiltinInt :: Isize ,
10951095 ) ,
10961096 false => hir_def:: builtin_type:: BuiltinType :: Uint (
10971097 hir_def:: builtin_type:: BuiltinUint :: Usize ,
10981098 ) ,
10991099 } ,
1100- hir_def :: layout:: IntegerType :: Fixed ( i, sign) => match sign {
1100+ layout:: IntegerType :: Fixed ( i, sign) => match sign {
11011101 true => hir_def:: builtin_type:: BuiltinType :: Int ( match i {
1102- hir_def :: layout:: Integer :: I8 => hir_def:: builtin_type:: BuiltinInt :: I8 ,
1103- hir_def :: layout:: Integer :: I16 => hir_def:: builtin_type:: BuiltinInt :: I16 ,
1104- hir_def :: layout:: Integer :: I32 => hir_def:: builtin_type:: BuiltinInt :: I32 ,
1105- hir_def :: layout:: Integer :: I64 => hir_def:: builtin_type:: BuiltinInt :: I64 ,
1106- hir_def :: layout:: Integer :: I128 => hir_def:: builtin_type:: BuiltinInt :: I128 ,
1102+ layout:: Integer :: I8 => hir_def:: builtin_type:: BuiltinInt :: I8 ,
1103+ layout:: Integer :: I16 => hir_def:: builtin_type:: BuiltinInt :: I16 ,
1104+ layout:: Integer :: I32 => hir_def:: builtin_type:: BuiltinInt :: I32 ,
1105+ layout:: Integer :: I64 => hir_def:: builtin_type:: BuiltinInt :: I64 ,
1106+ layout:: Integer :: I128 => hir_def:: builtin_type:: BuiltinInt :: I128 ,
11071107 } ) ,
11081108 false => hir_def:: builtin_type:: BuiltinType :: Uint ( match i {
1109- hir_def :: layout:: Integer :: I8 => hir_def:: builtin_type:: BuiltinUint :: U8 ,
1110- hir_def :: layout:: Integer :: I16 => hir_def:: builtin_type:: BuiltinUint :: U16 ,
1111- hir_def :: layout:: Integer :: I32 => hir_def:: builtin_type:: BuiltinUint :: U32 ,
1112- hir_def :: layout:: Integer :: I64 => hir_def:: builtin_type:: BuiltinUint :: U64 ,
1113- hir_def :: layout:: Integer :: I128 => hir_def:: builtin_type:: BuiltinUint :: U128 ,
1109+ layout:: Integer :: I8 => hir_def:: builtin_type:: BuiltinUint :: U8 ,
1110+ layout:: Integer :: I16 => hir_def:: builtin_type:: BuiltinUint :: U16 ,
1111+ layout:: Integer :: I32 => hir_def:: builtin_type:: BuiltinUint :: U32 ,
1112+ layout:: Integer :: I64 => hir_def:: builtin_type:: BuiltinUint :: U64 ,
1113+ layout:: Integer :: I128 => hir_def:: builtin_type:: BuiltinUint :: U128 ,
11141114 } ) ,
11151115 } ,
11161116 } ) ,
@@ -1177,6 +1177,28 @@ impl Variant {
11771177 pub fn eval ( self , db : & dyn HirDatabase ) -> Result < i128 , ConstEvalError > {
11781178 db. const_eval_discriminant ( self . into ( ) )
11791179 }
1180+
1181+ /// Return layout of the variant and tag size of the parent enum.
1182+ pub fn layout ( & self , db : & dyn HirDatabase ) -> Result < ( Layout , usize ) , LayoutError > {
1183+ let parent_enum = self . parent_enum ( db) ;
1184+ let parent_layout = Adt :: from ( parent_enum) . layout ( db) ?;
1185+ if let layout:: Variants :: Multiple { variants, tag, tag_encoding, tag_field : _ } =
1186+ parent_layout. variants
1187+ {
1188+ let tag_size = match tag_encoding {
1189+ TagEncoding :: Direct => {
1190+ let target_data_layout = db
1191+ . target_data_layout ( parent_enum. module ( db) . krate ( ) . id )
1192+ . ok_or ( LayoutError :: TargetLayoutNotAvailable ) ?;
1193+ tag. size ( & * target_data_layout) . bytes_usize ( )
1194+ }
1195+ TagEncoding :: Niche { .. } => 0 ,
1196+ } ;
1197+ Ok ( ( variants[ RustcEnumVariantIdx ( self . id ) ] . clone ( ) , tag_size) )
1198+ } else {
1199+ Ok ( ( parent_layout, 0 ) )
1200+ }
1201+ }
11801202}
11811203
11821204/// Variants inherit visibility from the parent enum.
0 commit comments