I want to bound a type based on a function it can reach via deref coercions. Problem is bounding on Deref only works on one level of coercion.
struct A {}
impl A {
    fn foo(&self) {
        println!("foo");
    }
}
struct B {}
impl Deref for B {
    type Target = A;
    fn deref(&self) -> &Self::Target {
        &A{}
    }
}
struct C {}
impl Deref for C {
    type Target = B;
    fn deref(&self) -> &Self::Target {
        &B{}
    }
}
fn call_with_ref(obj: &A) {
    print!("call_with_ref: ");
    obj.foo();
}
fn checked_call_with_ref(obj: &A) {
    let ptr: *const A = obj;
    if !ptr.is_null() {
        print!("checked_call_with_ref: ");
        obj.foo();   
    } else {
        println!("checked_call_with_ref: null")
    }
}
fn call_with_pointer<T: Deref<Target = A>>(ptr: *const T) {
    if !ptr.is_null() {
        print!("call_with_pointer: ");
        unsafe { (*ptr).foo() };   
    }
}
fn main() {
    let c = C{};
    let ref_to_c = &c;
    let mut ptr_to_c: *const C = ref_to_c;
    ref_to_c.foo(); // works
    call_with_ref(ref_to_c); // works
    // call_with_pointer(ptr_to_C); // does not work bec. it derefs to B
    unsafe { checked_call_with_ref(&*ptr_to_c) }; // works on non-nulls
    ptr_to_c = std::ptr::null();
    unsafe { checked_call_with_ref(&*ptr_to_c) }; // undefined behavior on null pointers
    // have to put null check on each call site
    if let Some(ref_to_obj) = unsafe { ptr_to_c.as_ref() } {
        call_with_ref(ref_to_obj);
    }
}
The foo function here is only implemented by A. Refs to B can call it with a direct coerce while refs to C can still call it via deref-ing to B. Deref<Target = A> is not the proper bound as C implements Deref<Target = B>. Does Rust have some sort of Coercible trait?
 
     
    