pub enum UnsafeEnum<T, I> {
Valid(T),
Invalid(I),
}
Expand description
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:
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§
Trait Implementations§
Source§impl<T, I> BinarySerialize for UnsafeEnum<T, I>
impl<T, I> BinarySerialize for UnsafeEnum<T, I>
Source§impl<T: Clone, I: Clone> Clone for UnsafeEnum<T, I>
impl<T: Clone, I: Clone> Clone for UnsafeEnum<T, I>
Source§fn clone(&self) -> UnsafeEnum<T, I>
fn clone(&self) -> UnsafeEnum<T, I>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more