#RustQuiz: what will be the output?

A. false
B. true
C. Compilation error
D. unsafe block is missing

#rustlang #rust

@AstraKernel Ohhh, that's a tricky one. I honestly have no clue. I am even unsure if debug and release will yield the same result here.
@AstraKernel That said: I think the result is true. I don't know the actual reasoning behind this, but if I remember correctly, Rust does not create an actual in-memory representation of instances of types with cardinality 1, as those would all be identical anyhow...
One consequence - again iirc - is that all instances of a type with cardinality 1 have the same address.
@soulsource @AstraKernel
I'm a little unsure if there's actually a guarantee that taking two references to the same ZST will return the same pointer.

@hjvt @AstraKernel Interesting. I had it somehow stuck in my mind that this is defined, and getting the address always yields the same value (at least for the same type).

However, doing a quick web search yields no mention of this, so I probably misremembered.

@hjvt @soulsource @AstraKernel But what of two ZSTs composed together in another ZST?

The array here is itself zero-sized; is there no guarantee that a pointer to an array element must be pointing to an address inside the array? Which would necessitate that the array and the two elements all have the same address?

I am unreasonably fascinated by this problem ^_^

Rust Playground

A browser interface to the Rust compiler to experiment with the language

@AstraKernel @hjvt @soulsource Ha! But now I really wonder if there is a guarantee for that
@AstraKernel they’re pointers, so you’re comparing addresses. Those aren’t the same address.
@clf @AstraKernel except the types are ZSTs, so they actually are!

@AstraKernel

First I wasn't sure if it was a slam creeper, as I wasn't even sure the different initialization methods for the type would work.
Then I thougt compilation error anyway, as no Eq defined, but then I realized it can still compare the pointers, so I thought false. But then I realized the type is zero size, so maybe actually true?!?

In the end I had to check in the playground. So, cool quiz!

@AstraKernel 100 bucks on black false 😊

@AstraKernel I think the answer is unspecified (true or false.)

References to zero-sized types happen to use a dangling pointer equal to their alignment, but I don't think it's a guarantee, just a particular impl. Some other properly aligned address could be used instead.
Pointer identity in Rust is mostly useless.

@AstraKernel
I'll go with B.

Ferris and [Ferris; 2] are both ZSTs, so c is a zero-sized value composed of smaller (ha!) zero-sized values.

I have no idea what the address of a zero-sized value is, but they must have one. But then surely they must all have the same address. There's no space in a zero-sized value for them to differ :)

@AstraKernel But now I wonder what would happen if the Array was a mutable pair, and I took mutable references of the two Ferrises.

I'd have two mutable references with the same address, pointing to immutable zero-sized values. Would... would that be UB? It can't be, since this is safe Rust. But it must be, since I have to aliased mut refs. Fascinating conundrum.

@AstraKernel I tried it in playground and it compiled. Didn't run it in Miri, but I guess this means the "aliased mut refs are instant UB" rule must have an exception for ZSTs (which of course aren't mutable anyway).

Same for the borrow checker - so I guess semantically I'm borrowing different objects that just happen to be in the same physical place...?