Closed oli-obk closed 8 years ago
pointers to different zst values will compare equal, but comparing pointers to different types is probably forbidden anyway
I'm worried about allowing this from a correctness standpoint. They could be the same type:
let x = ();
let y = 1;
let z = ();
assert_eq!(&x as *const (), &z as *const ());
This (probably) fails in rustc and currently does in miri but wouldn't with the suggested change. I'm not sure what is or should be guaranteed here.
@ubsan Any thoughts?
On the other hand, this is probably a major low-hanging fruit optimization, and it would be nice to make these faster one way or another. I have some vague thoughts about passing around PrimVal
instead of Pointer
for some of miri's operations to reduce the number of allocations created which might help here, too. I need some more time to investigate that.
By the way, ZST Allocation
s themselves don't require any heap allocation in the interpreter, aside from the space used in the HashMap
in Memory
. Another idea is to have fake Pointer
s for ZSTs which somehow preserve distinctness but don't actually key into the HashMap
.
Another idea is to have fake Pointers for ZSTs which somehow preserve distinctness but don't actually key into the HashMap.
Easy, just increase the alloc_id counter without allocating and make sure that miri doesn't actually deref ZST pointers. There'd be no way to detect dangling zst pointers, but I don't think that's an issue.
@solson I don't believe we make any guarantees about the uniqueness of ZST pointers (or, to be honest, any of the other pointer types), and we do not guarantee the ordering of stack variables.
@ubsan we do make guarantees for &mut T
when T
is not ZST
@oli-obk I don't think so... I can't imagine an implementation which would break that though (i.e., I can't imagine an implementation that requires what Rust does, and still would be able to do that). I believe we do specifically want to be able to do this:
{
let x = 0;
let y = 0;
&x as *const _ == &y as *const _ // true
}
We guarantee noalias semantics, but nothing about pointer comparisons, actually. So... if someone wanted to make an entirely completely ridiculous implementation, they could do something like optimizing
fn doop (ptr1: *const u32, ptr2: *const u32) -> bool {
ptr1 == ptr2
}
// to
fn doop (ptr1: *const u32, ptr2: *const u32) -> bool {
true
}
Easy, just increase the alloc_id counter without allocating and make sure that miri doesn't actually deref ZST pointers. There'd be no way to detect dangling zst pointers, but I don't think that's an issue.
@oli-obk I'd like to at least be able to tell a dangling pointer deref apart from a ZST deref (after being casted to a different pointer type, say).
@oli-obk Based on @ubsan's comments, I think it would be fine to implement your original suggestion of a single ZST allocation. This would remove the problem of my previous comment.
I'm not sure, but I think simply reserving a single allocation to be used for all zst should work (pointers to different zst values will compare equal, but comparing pointers to different types is probably forbidden anyway).