Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: How to compare trait objects when user-defined types wrap
How to compare trait objects when user-defined types wrap
โ Rust ๐ 2025-09-08 ๐ค surdeus ๐๏ธ 2Iโm working on a library where I need to compare if two wrapped trait objects actually point to the same underlying value.
The tricky part is that users of the library can supply their own types (e.g. Qux
) that embed library types (like Bar
) while implementing the same traits.
Hereโs a reduced example:
use std::any::{Any};
use std::sync::{Arc, Mutex};
// types provided by the Library
pub trait IFoo: Any + Send + Sync {}
pub struct Foo {}
impl dyn IFoo {
pub fn as_any(&self) -> &dyn Any {
self
}
}
impl IFoo for Foo {}
pub trait IBar: Any + Send + Sync {}
pub struct Bar {}
impl dyn IBar {
pub fn as_any(&self) -> &dyn Any {
self
}
}
impl IBar for Bar {}
// Types from User of the Library (although defined in here to keep things simple)
struct Qux {
bar: Bar, // to forward invocations
}
impl IBar for Qux {}
// Library
pub struct Comparator {
left: Arc<dyn Any + Send + Sync>,
}
impl Comparator {
pub fn compare(&self, right: &Arc<dyn Any + Send + Sync>) -> bool {
if (*self.left).type_id() != (**right).type_id() {
return false;
}
// Compare underlying pointers
let left_ptr = Arc::as_ptr(&self.left) as *const ();
let right_ptr = Arc::as_ptr(right) as *const ();
left_ptr == right_ptr
}
}
fn main() {
let foo: Arc<dyn IFoo> = Arc::new(Foo {});
let foo_any: Arc<dyn Any + Send + Sync> = Arc::new(foo.clone());
let foo_any2: Arc<dyn Any + Send + Sync> = Arc::new(foo.clone());
let comparator = Comparator { left: foo_any.clone() };
println!("Compare foo -> foo: {}", comparator.compare(&foo_any)); // true
println!("Compare foo -> foo2: {}", comparator.compare(&foo_any2));
let bar: Arc<Mutex<dyn IBar>> = Arc::new(Mutex::new(Bar {}));
let bar_any: Arc<dyn Any + Send + Sync> = Arc::new(bar.clone());
let bar_any2: Arc<dyn Any + Send + Sync> = Arc::new(bar.clone());
let comparator = Comparator { left: bar_any.clone() };
println!("Compare bar -> bar: {}", comparator.compare(&bar_any)); // true
println!("Compare bar -> bar2: {}", comparator.compare(&bar_any2));
let qux: Arc<Mutex<dyn IBar>> = Arc::new(Mutex::new(Qux { bar: Bar {} }));
let qux_any: Arc<dyn Any + Send + Sync> = Arc::new(qux.clone());
let comparator = Comparator { left: qux_any.clone() };
println!("Compare qux -> qux: {}", comparator.compare(&qux_any)); // true
let qux_any2: Arc<dyn Any + Send + Sync> = Arc::new(qux.clone());
println!("Compare qux -> qux2: {}", comparator.compare(&qux_any2));
}
Standard Output
Compare foo -> foo: true
Compare foo -> foo2: false
Compare bar -> bar: true
Compare bar -> bar2: false
Compare qux -> qux: true
Compare qux -> qux2: false
Expectation should return true for all comparisons
Playground: Rust Playground
10 posts - 3 participants
๐ท๏ธ Rust_feed