-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Description
Decoding an enum alloc fails when the discriminant is negative typed value. Consider two programs (A and B) which are semantically equivalent:
Program A - passing
#[repr(i8)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AccountState {
Uninitialized = 0,
Initialized = 1,
Frozen = -1,
}
fn main() {
let lhs = unsafe { core::mem::transmute::<i8, AccountState>(0) };
let rhs = AccountState::Uninitialized;
assert_eq!(lhs, rhs);
}Program B - failing
#[repr(i8)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AccountState {
Uninitialized = 0,
Initialized = 1,
Frozen = -1,
}
fn main() {
unsafe {
assert_eq!(core::mem::transmute::<i8, AccountState>(0), AccountState::Uninitialized);
}
}A is passing and B is failing. The difference is that B has the attempts to decode the AccountState::Uninitialized from allocated bytes. It is not the transmute / lhs that is failing, that cast (#cast ( Integer ( 0 , 8 , true ) , castKindTransmute , ty ( 2 ) , ty ( 37 ) )) correctly evaluates into the enum value (Aggregate ( variantIdx ( 0 ) , .List )). It is the rhs / decoding the enum that fails... (ty(37) is AccountState)
thunk ( #decodeConstant ( constantKindAllocated ( allocation ( ... bytes: b"\x00\x00\x00\x00\x00\x00\x00\x00" , provenance: provenanceMap ( ... ptrs: provenanceMapEntry ( ... offset: 0 , allocId: allocId ( 0 ) ) .ProvenanceMapEntries ) , align: align ( 8 ) , mutability: mutabilityMut ) ) , ty ( 25 ) , typeInfoRefType ( ty ( 37 ) ) ) )
We need to look at the decoding rules for enums
Metadata
Metadata
Assignees
Labels
No labels