Code
Given this type FwRuleSet
#[repr(C)]
#[derive(Clone, PartialEq, Debug)]
pub struct FwRuleSet {
pub rules: [Option<FwRule>; MAX_FW_RULES],
}
pub const MAX_FW_RULES: usize = 10;
pub const MAX_PREDICATES_PER_FW_RULE: usize = 2;
#[repr(C)]
#[derive(Default, Debug, PartialEq, Clone)]
pub struct FwRule {
pub predicates: [Option<FwPredicate>; MAX_PREDICATES_PER_FW_RULE],
}
#[repr(C, u32)]
#[derive(Debug, PartialEq, Clone)]
pub enum FwPredicate {
// We manually set the enum discriminant to facilitate interop
InnerDstIpv4(u32) = 1,
InnerSrcIpv4(u32) = 2,
InnerDstIpv6(u64) = 3,
InnerSrcIpv6(u64) = 4,
InnerIpProto(u8) = 5,
InnerDstUdp(u32) = 6,
InnerSrcUdp(u32) = 7,
InnerDstTcp(u32) = 8,
InnerSrcTcp(u32) = 9,
InnerIcmpv4(u32) = 10,
}
The memory representation of the values which contains None changed
let rs = FwRuleSet {
rules: [const { None }; MAX_FW_RULES],
};
From
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
To
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
In nightly-2026-04-27 and latter
Version it worked on
It most recently worked on: nightly-2026-04-26 or the current stable version
Version with regression
nightly-2026-04-27
More details
I think this is due to #155473
But I'm surprised the memory layout of #[repr(C)] struct can change like that between compiler version
To quickly reproduce you can run the following
git clone git@github.com:aureliar8/memory-layout-bug-reproduction.git
cd memory-layout-bug-reproduction
./run.sh cargo +nightly-2026-04-26 run
./run.sh cargo +nightly-2026-04-27 run
./run.sh cargo run
@rustbot modify labels: +regression-from-stable-to-nightly -regression-untriaged
Code
Given this type
FwRuleSetThe memory representation of the values which contains
NonechangedFrom
To
In nightly-2026-04-27 and latter
Version it worked on
It most recently worked on: nightly-2026-04-26 or the current stable version
Version with regression
nightly-2026-04-27
More details
I think this is due to #155473
But I'm surprised the memory layout of
#[repr(C)]struct can change like that between compiler versionTo quickly reproduce you can run the following
@rustbot modify labels: +regression-from-stable-to-nightly -regression-untriaged