Warning
This post was published 65 days ago. The information described in this article may have changed.
If we use trait object only by generic function, it's always safe. For example, in below case, self_compare always compare two same type object.
trait Comparable {
fn compare(&self, other: &Self) -> bool;
}
impl Comparable for i32 {
fn compare(&self, other: &Self) -> bool {
self == other
}
}
fn self_compare<T: Comparable>(a: &T) -> bool {
a.compare(a)
}
fn main() {
let x = 42;
println!("x == x: {}", self_compare(&x)); // true
/* cannot compile, but it should be ok
let a: &dyn Comparable = &x;
self_compare(a);
*/
}
Also, we can compile it like below c code:
#include <stdio.h>
#include <stdbool.h>
typedef bool (*CompareFn)(const void* a, const void* b);
typedef struct {
const void* obj;
CompareFn compare;
} ComparableObject;
bool compare_i32(const void* a, const void* b) {
return *(const int*)a == *(const int*)b;
}
bool self_compare(ComparableObject comp_obj) {
return comp_obj.compare(comp_obj.obj, comp_obj.obj);
}
int main() {
int x = 42;
ComparableObject a = { &x, compare_i32 };
printf("x == x: %s\n", self_compare(a) ? "true" : "false"); // true
return 0;
}
What's more, for existential type ∃α.T(α)≡∀β.(∀α.T(α)→β)→β, that means, for a trait object, if we pass ∀β.(∀α.T(α)→β), we can get a β value. (∀α.T(α)→β) is just a generic function. Every such type generic function should be ok for trait object.
So, why Rust have object safety and forbidden such usage?
9 posts - 5 participants
🏷️ rust_feed