-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fat pointers with same data part, but different vtables #48795
Comments
We don't guarantee that vtables are unique. For example, a separate copy could be generated in multiple codegen units, or multiple crates. |
OK. In that case, shouldn't |
Two fat pointers may point to the same data, but with different vtables (the compiler do not guarantee that vtables are unique). Such pointers should be considered equal by std::ptr::eq(), so cast them to thin pointers to compare only their data part. See <rust-lang#48795>.
This also affects slices: use std::ptr;
fn main() {
let array = [1, 2, 3, 4];
let slice1 = &array[0..1];
let slice2 = &array[0..3];
println!("{:p} == {:p} ? {}", slice1, slice2, ptr::eq(slice1, slice2));
}
|
Here is the smallest sample I managed to find to demonstrate this on my system using rustups's 1.27.0-nightly. It appears this is only reproducible with incremental builds, which is why it won't show up when trying it with Rust Playground. use std::path::Path;
pub trait Block { }
struct Inner {
data: i32,
}
impl Block for Inner { }
impl Inner {
fn new_box(data: i32) -> Box<Inner> {
Box::new(Inner {
data: data,
})
}
}
pub struct Outer {
inner: Box<Inner>,
block: *mut Block,
}
impl Outer {
pub fn new_box<P: AsRef<Path>>() -> Box<Outer> {
let mut inner = Inner::new_box(123);
let block = &mut *inner as *mut _;
Box::new(Outer {
inner: inner,
block: block,
})
}
pub fn get_inner(&mut self) -> &mut Block {
&mut *self.inner
}
}
fn main() {
let mut outer = Outer::new_box::<&str>();
let b = outer.block;
let a = outer.get_inner() as *mut Block;
println!("{:p} == {:p}: {}", a, b, a == b);
} Result:
|
I'm being bit by this problem also. It's causing |
Closing as duplicate of #46139. |
I did not manage to reproduce in a minimal sample, but in my application, I ended up with:
printing:
After investigations (and discussion on freenode/##rust), it appeared that
x
andy
were fat pointers having the same data part (the 64 first bits), but a different vtable (the last 64 bits).I applied this patch to my application, which solves the reported issue: Genymobile/gnirehtet@c36fa4d
But I can't understand how two fat pointers for the same objects may have different vtables. Is it expected?
The text was updated successfully, but these errors were encountered: