-
Notifications
You must be signed in to change notification settings - Fork 15
What's the definition of mutable aliasing for ZSTs? #44
Comments
This is pretty easy to answer. Aliasing only occurs when memory regions, within which the objects are stored, overlap. Since the memory regions occupied by ZSTs are, obviously, zero-sized, there can never be any overlap, even for pointers with the same address. |
I agree with @nagisa. Moreover, this has no bearing on whether a private-constructor ZST can be used as an access token: If unsafe code forges such a private-constructor ZST, while no immediate UB is raised, that's still clearly misbehaving unsafe code. Compare this to a "What code is UB" and "What safe code can rely on unsafe code to (not) do" don't always have the same answer, though of course safe code can at least rely on unsafe code not triggering UB. |
In response specifically to the conclusion that all ZSTs can be safely copied; if this were true, it would spell very bad news for all existing Drop impls for ZSTs. |
@ExpHP I'm not convinced a ZST can have a sensible Drop impl (Just to be clear: I'm very much on the side that we can't copy things that are not Copy, that breaks type safety.. and we use type safety to have memory safety). |
@bluss A ZST can be used as a proxy for global state. For example, a |
I am not sure where you are getting this conclusion from. It is not correct. I specifically argue above that ZSTs may not be copied by unsafe Code! Copying them does not raise immediate UB, but that doesn't make it okay. Or are you just confirming that it should not be okay? In that case I agree :D |
Yes. 🙂 |
Does that mean, then, that the following function is well-defined? fn zst_index2<T>(x: &mut Vec<T>, (i, j): (usize, usize)) -> (&mut T, &mut T) {
assert_eq!(std::mem::size_of::<T>(), 0);
let ps = (
&mut x[i] as *mut _,
&mut x[j] as *mut _,
);
unsafe {
(
&mut* ps.0,
&mut* ps.1,
)
}
}
#[derive(Debug)]
struct MyZst;
fn main() {
let mut v = vec![MyZst];
let p = zst_index2(&mut v, (0, 0));
println!("{:?}", p);
} https://play.rust-lang.org/?gist=0ef8d9bbbbc8fd477f2e2fc1be0ccb1d&version=stable (Apologies for the distraction about cloning; I'll move that discussion elsewhere.) |
Yes it is well defined. If it helps your mental model, think of it like this: each memory address contains an infinite number of distinct ZSTs. Every time you dereference a ZST pointer, you are accessing a new, separate instance of a ZST. Therefore it is impossible to have aliasing with ZSTs: all ZST pointers point to a different ZST instance, even if they have the same address. |
Actually, let me clarify that. The code that you have given will not trigger any UB due to aliasing violations. However it may violate the semantics of the |
@scottmcm I agree with @Amanieu that your function does not preserve the ownership semantics of the |
Ok, so checking for aliasing is not enough to know that two |
I agree with @Amanieu and @bluss. And, in fact, I think my formal model in RustBelt also agrees: Owning an For private types or types with private fields, libraries get to pick what "owning |
Notice that this would be the case even without considering ZSTs. For example, there may never be two |
For
sizeof(T)>0
, I understand the rules: no two&mut
s can reference overlapping memory.What exactly are the rules for ZSTs, though?
For
x: ((),())
to be a ZST (which we want),&mut x.0
and&mut x.1
are allowed, but are NOP transformations of&mut x
, with the same value. But with unsafe code, I can take&mut x as *mut _
, perform two NOP transformations to it, cast itas *mut ()
, and dereference it, and I don't know how to determine whether I'm reading the "first" or "second" fields, and thus whether I'm violating aliasing. Similar arguments apply to things likesplit_at_mut
on a&mut [()]
, which is also creating multiple pointers of the same value.But if all ZST reads are legal, that means all ZSTs are effectivelyCopy
, which means a private-constructor ZST cannot safely be used as an access token, as it can be copied by ptr::read'ing it twice (legal because all ZST reads are legal, by premise).The text was updated successfully, but these errors were encountered: