Isn't the error message saying the opposite? You have a type impl Deref<Target = Path>, and passing it somewhere that requires the bound AsRef<Path>. Here's an example playground, you can fix the error by adding a &* in front of the foo() call.
I think that implies there needs to be
impl<T, U> AsRef<T> for U where U: Deref<Target = T> {
fn as_ref(&self) -> &T {
&**self
}
}
which definitely looks likely to cause coherence issues.
The problem is I have a function like the following
struct MyWrapper(RefCell<String>);
impl MyWrapper {
/// A function which read-borrows the ref-cell without leaking the `Ref` type
/// (this should be an implementation detail).
fn get_a_string_ref(&self) -> AsRef<str> {
self.borrow()
}
}
@broken-pen: I want it the other way round, Deref -> AsRef.
EDIT my motivation is to allow myself to switch to Mutex, or RwLock etc. making "MyWrapper" Sync, without it being a breaking change.
struct DerefAsRef<D: Deref>(D);
impl<D: Deref> AsRef<D::Target> for DerefAsRef<D> {
fn as_ref(&self) -> &D::Target {
self.0.deref()
}
}
pub struct MyWrapper(RefCell<String>);
impl MyWrapper {
/// A function which read-borrows the ref-cell without leaking the `Ref` type
/// (this should be an implementation detail).
pub fn get_a_string_ref<'a>(&'a self) -> impl AsRef<String> + 'a {
DerefAsRef(self.0.borrow())
}
}
You can, e.g., switch in a Mutex and then it'll be DerefAsRef(self.0.lock().unwrap()). DerefAsRef stays private and hidden behind impl Trait.
What I'm trying to do is allow for complex ownership, but where everything is cleaned up when MyWrapper goes out of scope (no leaks, since MyWrapper owns everything). If I used Rc I could do what I want more easily, buit at the risk of leaks.
I think I agree with you at this point that the closure approach might be more sensible.
But I want to get this working, to help me understand the type system. Now I'm trying to write my own version of RefCell where the Ref is generic over the type of reference, but I'm struggling because &T doesn't impl AsRef<T>