diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index aced39059f6ba..413bc835e50ab 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -188,10 +188,27 @@ pub enum VariantsShape { tag: Scalar, tag_encoding: TagEncoding, tag_field: usize, - variants: Vec, + variants: Vec, }, } +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] +pub struct VariantFields { + /// Offsets for the first byte of each field, + /// ordered to match the source definition order. + /// I.e.: It follows the same order as [super::ty::VariantDef::fields()]. + /// This vector does not go in increasing order. + pub offsets: Vec, +} + +impl VariantFields { + pub fn fields_by_offset_order(&self) -> Vec { + let mut indices = (0..self.offsets.len()).collect::>(); + indices.sort_by_key(|idx| self.offsets[*idx]); + indices + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum TagEncoding { /// The tag directly stores the discriminant, but possibly with a smaller layout diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index 03328d084ee94..f6b750f75aeaa 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -11,7 +11,7 @@ use rustc_target::callconv; use crate::abi::{ AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar, - TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange, + TagEncoding, TyAndLayout, ValueAbi, VariantFields, VariantsShape, WrappingRange, }; use crate::compiler_interface::BridgeTys; use crate::target::MachineSize as Size; @@ -212,7 +212,15 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants VariantFields { + offsets: offsets.iter().as_slice().stable(tables, cx), + }, + _ => panic!("variant layout should be Arbitrary"), + }) + .collect(), } } }