rust-lang / unsafe-code-guidelines

Forum for discussion about what unsafe code can and can't do
https://rust-lang.github.io/unsafe-code-guidelines
Apache License 2.0
667 stars 58 forks source link

How transitive is repr(transparent)? #486

Open Manishearth opened 10 months ago

Manishearth commented 10 months ago

Context: https://github.com/hyperium/hyper/issues/3500

repr(transparent) makes types have the same representation/ABI. Does it have the same effect on generic types containing it?

For example, in the following case:

enum Generic<T> {
   Type(T),
   TwoType(T, T),
   String(String),
   Nothing
}

#[repr(transparent)]
struct Wrapper<T>(T);

is it safe to transmute between Generic<T> and Generic<Wrapper<T>>? Do they have the same ABI? I'm thinking about things like -Zrandomize-layout.

RalfJung commented 10 months ago

Do they have the same ABI?

No.

is it safe to transmute between Generic\ and Generic<Wrapper\>?

I think that s the intention; I don't know if it actually follows from anything we document. I also don't know what -Zrandomize-layout does here.

Manishearth commented 10 months ago

Probably worth documenting somewhere.

I suspect -Zrandomize-layout doesn't respect this, but that's fine, it's not a perfect representation of the rules.

RalfJung commented 10 months ago

That would make randomize-layout unsound though, which is clearly a bug. So I don't think it's "fine".

digama0 commented 10 months ago

I don't think we promise that Generic<T> and Generic<Wrapper<T>> are the same. In general we can't do this, because of associated types. Maybe we can carve out some subset of cases for which it is okay, but I don't think that -Zrandomize-layout is doing anything unsound currently.

RalfJung commented 10 months ago

The question (as I understood it) was for this specific type, which doesn't use associated types. Obviously there are limits to this.

digama0 commented 10 months ago

We definitely don't promise this, and randomize-layout may be laying them out differently. I don't think this is particularly desirable, but repr(Rust) structs have basically no layout guarantees.

Manishearth commented 10 months ago

That would make randomize-layout unsound though, which is clearly a bug. So I don't think it's "fine".

Oh sure I meant that I wouldn't be surprised and I wouldn't treat it as a strong expectation of what the semantics should be.

FeldrinH commented 7 months ago

Do they have the same ABI?

No.

I read through the linked document and could not find anything that states that the answer is no. What am I missing?

RalfJung commented 7 months ago

The answer is always "no" except when the linked document states otherwise. So the fact that none of the cases there says they are compatible implies that they are not compatible.

FeldrinH commented 7 months ago

The answer is always "no" except when the linked document states otherwise. So the fact that none of the cases there says they are compatible implies that they are not compatible.

The document does not seem to discuss ABI compatibility of structs at all. Does that mean that two different structs are never ABI compatible?

RalfJung commented 7 months ago

It mentions repr(transparent). But structs without that attribute are indeed not ABI compatible with anything else.