Full code: https://is.gd/hZ9nqK
Given a smart pointer, which only works on types implementing the trait Bar or on Bar trait objects, such that Pointer<T> is allowed to coerce to Pointer<Bar>, and the corresponding PartialEq implementation :
trait Bar {}
struct Foo;
impl Bar for Foo {}
struct Pointer<T: ?Sized>
where T: Bar + Unsize<Bar> {
value: *mut T,
}
impl <T: ?Sized> CoerceUnsized<Pointer<Bar>> for Pointer<T>
where T: Bar + Unsize<Bar> {}
impl <T: ?Sized, U: ?Sized> PartialEq<Pointer<U>> for Pointer<T>
where T: Bar + Unsize<Bar>,
U: Bar + Unsize<Bar> {
fn eq(&self, _other: &Pointer<U>) -> bool {
true
}
}
Applying the == operator on two Pointer<Foo> will try to coerce them to Pointer<Bar>, even though this isn't needed. This is an issue since coercion moves the original pointer.
fn cmp(x: Pointer<Foo>, y: Pointer<Foo>) {
x == y;
x == y; // use of moved value: `y`
}
Removing the CoerceUnsized implementation lets the code build, which means that the coercion is not needed.
As @Diggsey pointed out on reddit, if the PartialEq is restricted to pointers with identical types (PartialEq for Pointer<T>), then no coercion occurs.
Full code: https://is.gd/hZ9nqK
Given a smart pointer, which only works on types implementing the trait
Baror onBartrait objects, such thatPointer<T>is allowed to coerce toPointer<Bar>, and the correspondingPartialEqimplementation :Applying the
==operator on twoPointer<Foo>will try to coerce them toPointer<Bar>, even though this isn't needed. This is an issue since coercion moves the original pointer.Removing the
CoerceUnsizedimplementation lets the code build, which means that the coercion is not needed.As @Diggsey pointed out on reddit, if the
PartialEqis restricted to pointers with identical types (PartialEq for Pointer<T>), then no coercion occurs.