Stream: general

Topic: tuple layout guarantees


Jake Goulding (Jun 10 2019 at 18:20, on Zulip):

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)?

RalfJ (Jun 10 2019 at 18:23, on Zulip):

not having guarantees does not mean we dont want to, it just means nobody pushed through an RFC ;)

RalfJ (Jun 10 2019 at 18:23, on Zulip):

also see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/structs-and-tuples.md

RalfJ (Jun 10 2019 at 18:24, on Zulip):

but generally, given that tuples are repr(Rust), they are unlikely to get a lot of guarnatees

Jake Goulding (Jun 10 2019 at 18:25, on Zulip):

Oh sure. And the current layout might become the guaranteed layout at some point as well, so code today might just work by luck.

Jake Goulding (Jun 10 2019 at 18:25, on Zulip):

Context: How to convert a tuple of references to a reference of a tuple?

RalfJ (Jun 10 2019 at 18:27, on Zulip):

we certainly don't guarantee that fields are laid out in order

RalfJ (Jun 10 2019 at 18:27, on Zulip):

AFAIK tuples are subject to field reordering except for the last field (due to unsizing)

Jake Goulding (Jun 10 2019 at 18:28, on Zulip):

Looks like it touches on "Homogeneous structs" and "(T1..Tn) would be compatible with TupleN<T1..Tn>"

RalfJ (Jun 10 2019 at 18:28, on Zulip):

homogeneous tuples are a special topic and it seems reasonable to say more there

RalfJ (Jun 10 2019 at 18:29, on Zulip):

it's probably invalid to rely on this

not just probably, it is invalid :)

Jake Goulding (Jun 10 2019 at 18:29, on Zulip):

The general question that OP asked is an easy answer: no, you can't go from (&A, &B) to &(A, B) (right?)

RalfJ (Jun 10 2019 at 18:31, on Zulip):

no you cannot, how would you even know they point to the same thing?

Jake Goulding (Jun 10 2019 at 18:31, on Zulip):

@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

RalfJ (Jun 10 2019 at 18:31, on Zulip):

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?

RalfJ (Jun 10 2019 at 18:31, on Zulip):

seems like XY problem to me TBH^^

RalfJ (Jun 10 2019 at 18:32, on Zulip):

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

Jake Goulding (Jun 10 2019 at 18:32, on Zulip):

explicitly specified as unspecified ;-)

Jake Goulding (Jun 10 2019 at 18:32, on Zulip):

This page deliberately left blank

Jake Goulding (Jun 10 2019 at 18:33, on Zulip):

XY problem: absolutely

RalfJ (Jun 10 2019 at 18:33, on Zulip):

that is invalid by any measure I know of ;) it "happens to work" is the best you can say about it

Jake Goulding (Jun 10 2019 at 18:36, on Zulip):

@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.

Jake Goulding (Jun 10 2019 at 18:36, on Zulip):

I understand that's not true, but I do think that's a likely thing for people to think.

Jake Goulding (Jun 10 2019 at 18:36, on Zulip):

And I think I've started from that assumption once or twice.

RalfJ (Jun 10 2019 at 19:47, on Zulip):

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

Jake Goulding (Jun 10 2019 at 20:49, on Zulip):

isn't that kind of a half-truth? The behavior is undefined, by definition even.

RalfJ (Jun 10 2019 at 21:16, on Zulip):

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.

RalfJ (Jun 10 2019 at 21:17, on Zulip):

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.

RalfJ (Jun 10 2019 at 21:19, on Zulip):

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.

Last update: Nov 22 2019 at 00:35UTC