-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Strange Arc::ptr_eq behaviour (duplicate vtables?) #63021
Comments
vtables are not unique. There can be, for example, a duplicate vtables in each codegen unit that needs one. |
Note also that the layout of trait objects is not specified. |
Seems odd to ever use the vtable pointer as part of a comparison then... |
The documentation for ptr::eq covers why vtable pointers are incorporated in one of the examples: https://doc.rust-lang.org/std/ptr/fn.eq.html. |
The net result is C++-level foot-gunnery. The documentation there says that different implementations may compare differently, but the problem here is that the same implementation is comparing differently depending on which compilation unit converted the concrete type to a trait object. What's worse is that this exposes an implementation detail. Let's say I have this code: fn identity(x: Box<dyn Trait>) -> Box<dyn Trait> { x } If the compiler is able to prove that the function is only called with It's difficult to see how |
Relabeling as T-lang as this does seem like a bit of an unfortunate result of compiler internals, ideally we'd not create different vtables for different codegen units. Maybe there's some sort of linker or LLVM attribute we could set to deduplicate those? |
Hi. We've just ran into this problem (cf. the bug referenced), it seems that, for example, turning off/on incremental compilation is enough to trigger a difference. This is definitely a footgun. IMO at least the documentation should be updated, it doesn't seem to mention this problem and the documentation for |
We sometimes generate duplicate vtables depending on the number of codegen units (rust-lang#46139), so we need to exclude the vtable part when comparing fat pointers. This is safe for the case of Rc, Arc, and Weak because these always point to an entire allocation. These methods can’t be used to compare, e.g., a struct with one of its fields, a slice with one of its subslices, or consecutive ZST fields. Fixes rust-lang#63021. Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Hello. This issue is simmilar to #48795 and #46139 but have more strange behaviour and suggestion.
The problem is located when we clone
Arc
toArc<Trait>
in one function, returnArc
and then cloneArc
toArc<Trait>
in "parent" function, butArc::ptr_eq
says, thatArc<Trait>
(called function) !=Arc<Trait>
(parent function).Where is example of this problem, but Arc::ptr_eq works!
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=95eef8742b08ab94f3fbf3048dc514b2
We see, that data pointer is equal, but vtables are different, but implementations are correct.
In my case I have more traits, etc, project in 14k lines, and Arc::ptr_eq do not works, but this objects/traits are located in same crate. Note this problem is still occured in build --release cause, and implementations of vtables eat memory.
So..
or
The text was updated successfully, but these errors were encountered: