[][src]Enum lain::types::UnsafeEnum

pub enum UnsafeEnum<T, I> {
    Valid(T),
    Invalid(I),
}

Represents an enum that can contain unsafe values.

These are enums which may potentially be used as indices, offsets, or used in some other calculation. This wrapper type exists since the Rust compiler makes strong assumptions about how enums are used, and if you attempt to unsafely (either through a union or pointers) set the value of an enum to an indiscriminant value, you will regularly hit issues with illegal instructions being executed while in debug mode. See, Rust will emit certain LLVM IR code like unreachable; to give LLVM certain hints. The problem is that Rust believes (and rightfully so) that enums have discrete values unless they are programmed to contain custom discriminant values. So if you have ane num like:

enum MyEnum {
    Foo = 1,
    Bar,
    Baz, // ...
}

Rust expects in some scenarios that all possible values have been accounted for so the following is emitted:

This example deliberately fails to compile
let my_enum_instance = MyEnum::Foo;
match my_enum_instance {
    MyEnum::Foo | MyEnum::Bar | MyEnum::Baz => println!("All possibilities accounted for :)"), // your code
    _ => unreachable(), // the compiler will insert this branch in some scenarios
}

But what if you set the value of your instance to something other than 1, 2, or 3 via unsafe code? That unreachable() block is hit in debug builds only and suddenly your code doesn't work. In release mode, sometimes the _ (default) path is actually used to hold the first item of the enum, so your "all other values" code path actually represents a very real value.

TL;DR Rust makes too many assumptions about how enums are used to make doing unsafe things with them worthwhile. This wrapper enum works around that.

Variants

Valid(T)
Invalid(I)

Trait Implementations

impl<T, I> BinarySerialize for UnsafeEnum<T, I> where
    T: BinarySerialize,
    I: BinarySerialize + Clone
[src]

impl<T: Clone, I: Clone> Clone for UnsafeEnum<T, I>[src]

impl<T: Copy, I: Copy> Copy for UnsafeEnum<T, I>[src]

impl<T: Debug, I: Debug> Debug for UnsafeEnum<T, I>[src]

impl<T, I> Default for UnsafeEnum<T, I> where
    T: Default
[src]

impl<T, I> Mutatable for UnsafeEnum<T, I> where
    T: ToPrimitive<Output = I>,
    I: BitXor<Output = I> + NumCast + Bounded + Copy + Debug + Default + DangerousNumber<I> + Display + WrappingAdd + WrappingSub
[src]

type RangeType = I

impl<T, I> NewFuzzed for UnsafeEnum<T, I> where
    T: NewFuzzed,
    I: NewFuzzed<RangeType = I> + Bounded + Debug + Default
[src]

type RangeType = I

impl<E, T> ToPrimitive for UnsafeEnum<E, T> where
    E: ToPrimitive<Output = T>,
    T: Copy
[src]

type Output = T

Auto Trait Implementations

impl<T, I> RefUnwindSafe for UnsafeEnum<T, I> where
    I: RefUnwindSafe,
    T: RefUnwindSafe

impl<T, I> Send for UnsafeEnum<T, I> where
    I: Send,
    T: Send

impl<T, I> Sync for UnsafeEnum<T, I> where
    I: Sync,
    T: Sync

impl<T, I> Unpin for UnsafeEnum<T, I> where
    I: Unpin,
    T: Unpin

impl<T, I> UnwindSafe for UnsafeEnum<T, I> where
    I: UnwindSafe,
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Fixup for T[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> SerializedSize for T where
    T: ToPrimitive<Output = U>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

impl<T> VariableSizeObject for T[src]