I've been working on modelling the PCI configuration space and would really like to be able to control the mapping of Option<SomeU8Enum> and Option<0..=254>.

Firstly, the PCI Interrupt Pin has 5 values:-

0x00 - None
0x01 to 0x04 - Something meaningful.

I can't use an enum to represent this as Option, even if enum SomethingMeaningful is repr(u8), as Rust maps None to a value of 0x05! This means one can't use an enum here that re-uses Rust's Option type. Is there anything experimental in the works?

Secondly, I have a number of types where the situation is reversed, and 0xFF is None. I'd really like a NonZeroFF type, but failing that, it would be nice to likewise have an enum. Using new type wrappers id, of course, quite do-able, but it doesn't exactly model the situation I want.

Anything in the works here? Anything the Rust lang has got experimentally?

Currently you have no other choice but to implement the OptionEnum yourself, without nesting. With macros the task can be automated:

derive_option! {
OptionMyNonZeroEnum for
#[non_null]
#[repr(u8)]
enum MyNonZeroEnum {
A,
B,
C,
D,
}
}
fn main ()
{
use self::MyNonZeroEnum::*;
assert_eq!(1, dbg!(A as u8));
assert_eq!(2, dbg!(B as u8));
assert_eq!(3, dbg!(C as u8));
assert_eq!(4, dbg!(D as u8));
assert_eq!(0, dbg!(OptionMyNonZeroEnum::None as u8));
assert_eq!(1, dbg!(OptionMyNonZeroEnum::Some(A) as u8));
assert_eq!(2, dbg!(OptionMyNonZeroEnum::Some(B) as u8));
assert_eq!(3, dbg!(OptionMyNonZeroEnum::Some(C) as u8));
assert_eq!(4, dbg!(OptionMyNonZeroEnum::Some(D) as u8));
assert_eq!(0, dbg!(OptionMyNonZeroEnum::from(None) as u8));
assert_eq!(1, dbg!(OptionMyNonZeroEnum::from(Some(A)) as u8));
assert_eq!(2, dbg!(OptionMyNonZeroEnum::from(Some(B)) as u8));
assert_eq!(3, dbg!(OptionMyNonZeroEnum::from(Some(C)) as u8));
assert_eq!(4, dbg!(OptionMyNonZeroEnum::from(Some(D)) as u8));
}

Nice to know! But since the OP's described enum does not reach 0xff, having an unused discriminant to force None into 0 breaks the point of using an enum to begin with, imho.

You're right and I think this could be changed IMHO, e.g. that None does not take the hightest available integer, but the lowest. Let's see if I'll open an issue
One could do something like

Here is the generalized version of the previous macro to also handle the maximum discriminant being free:

derive_option! {OptionMyNonMaxEnum for
#[non_max]
#[repr(u8)]
enum MyNonMaxEnum {
A,
B,
C,
D,
}
}
use self::MyNonMaxEnum::*;
fn main ()
{
assert_eq!(0, dbg!(A as u8));
assert_eq!(1, dbg!(B as u8));
assert_eq!(2, dbg!(C as u8));
assert_eq!(3, dbg!(D as u8));
assert_eq!(0xff, dbg!(OptionMyNonMaxEnum::None as u8));
assert_eq!(0, dbg!(OptionMyNonMaxEnum::Some(A) as u8));
assert_eq!(1, dbg!(OptionMyNonMaxEnum::Some(B) as u8));
assert_eq!(2, dbg!(OptionMyNonMaxEnum::Some(C) as u8));
assert_eq!(3, dbg!(OptionMyNonMaxEnum::Some(D) as u8));
assert_eq!(0xff, dbg!(OptionMyNonMaxEnum::from(None) as u8));
assert_eq!(0, dbg!(OptionMyNonMaxEnum::from(Some(A)) as u8));
assert_eq!(1, dbg!(OptionMyNonMaxEnum::from(Some(B)) as u8));
assert_eq!(2, dbg!(OptionMyNonMaxEnum::from(Some(C)) as u8));
assert_eq!(3, dbg!(OptionMyNonMaxEnum::from(Some(D)) as u8));
}