Going from reference of inner data to reference of enum

If I have

enum Thing {
    A(Data)
}

and I have a &Data, is there any way to get a &Thing::A?

With a one variant enum it could be possible using unsafe, with a #[repr(transparent)] on the enum to ensure it is sound (zero-sized discriminant).

But currently such attribute cannot be applied to an enum, and generally when the enum has multiple variants (the only point of a non-empty enum, to be honest), it wouldn’t be possible since nothing guarantees that from an address to Data you can have an address to discriminant + Data.

What if I had something like this:

enum Thing {
    A(Box<Data1>)
    B(Box<Data2>)
}

and I have a &Box<Data1>?

This isn’t possible. Because we can’t know that it is safe to go from &Box<Data1> to &Thing because of the discriminant.
What problem are you trying to solve?

2 Likes

I hope this Playground manages to illustrate why such conversion is not possible:

[0, 0]   	-> None
[0, 106]   	-> None
[1, 105]   	-> Some(105)
[0, 105]   	-> None
[0, 66]   	-> None
[2, 66]   	-> [2, 66]

Given [2, 66], and a reference to its second byte, 66, how could we possibly have a reference to one of the Option's discriminants (1 for Some, 0 for None) followed by 66?

2 Likes

One example would be implementation of the Index trait, which returns a reference to the data. In the meanwhile, the actual enum variant might need to be computed in the index function.