The reference sez:
Tuples do not have any guarantees about their layout.
Is this still accurate? Do we not make any guarantees about the layout (except for the empty tuple)?
not having guarantees does not mean we dont want to, it just means nobody pushed through an RFC ;)
but generally, given that tuples are
repr(Rust), they are unlikely to get a lot of guarnatees
Oh sure. And the current layout might become the guaranteed layout at some point as well, so code today might just work by luck.
we certainly don't guarantee that fields are laid out in order
AFAIK tuples are subject to field reordering except for the last field (due to unsizing)
Looks like it touches on "Homogeneous structs" and "(T1..Tn) would be compatible with TupleN<T1..Tn>"
homogeneous tuples are a special topic and it seems reasonable to say more there
it's probably invalid to rely on this
not just probably, it is invalid :)
The general question that OP asked is an easy answer: no, you can't go from
(&A, &B) to
&(A, B) (right?)
no you cannot, how would you even know they point to the same thing?
@RalfJ nuances of the meaning of "invalid". The code compiles, produces the output you'd expect, and Miri doesn't complain, so it's "valid" in some sense. It's not valid in that it's UB
and if you do know that they point to the same thing, in which situation would you not also know the base address of the thing?
seems like XY problem to me TBH^^
RalfJ nuances of the meaning of "invalid". The code compiles, produces the output you'd expect, and Miri doesn't complain, so it's "valid" in some sense. It's not valid in that it's UB
to be precise: it relies on explicitly unspecified parts of the semantics
explicitly specified as unspecified ;-)
This page deliberately left blank
XY problem: absolutely
that is invalid by any measure I know of ;) it "happens to work" is the best you can say about it
@RalfJ this is where you realize the huge mistake you've participated in. Miri reports no issues with the code, that means that there's no UB. This is how it works.
I understand that's not true, but I do think that's a likely thing for people to think.
And I think I've started from that assumption once or twice.
RalfJ this is where you realize the huge mistake you've participated in. Miri reports no issues with the code, that means that there's no UB. This is how it works.
and indeed there is no UB -- with this version of Rust on this platform
isn't that kind of a half-truth? The behavior is undefined, by definition even.
well it's a matter of definition mostly. the way I see it, the Rust Abstract Machine is parameterized by how data structures are laid out. Miri tests for UB with a particular instance of that parameter, and there is no UB there.
the property we probably care about for programs is that they are UB-free under any instance. And now if we are a bit sloppy we might call that property "being UB-free" as well.
but you can arrange the words differently here of course ;)
writing the spec in a way that such a program has UB under any execution without having to resort to this "hidden parameter" is very non-trivial. that's akin to changing Miri such that it can detect such issues deterministically. so I'd argue that this is a more elegant way to set up the semantics.