# Semantics of AsRef

**URL:** <https://internals.rust-lang.org/t/semantics-of-asref/17016>\
**Category:** language design\
**Created:** [July 15, 2022, 10:46am UTC](https://internals.rust-lang.org/t/semantics-of-asref/17016 "2022-07-15T10:46:19Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://internals.rust-lang.org/u/jbe)\
**Post date:** [July 16, 2022, 10:01am UTC](https://internals.rust-lang.org/t/semantics-of-asref/17016/7 "2022-07-16T10:01:42Z")

</div>

> [@steffahn](#):
>
> (On the other hand, and slightly related: maybe `AsMut<Vec<T>> for Vec<T>` _ **is** _ useful though, because other types could also contain a `Vec<T>` and you want to mutate it by pushing elements or the like.)

If I understand it right, then a blanket implementation like in [this other FIXME](https://github.com/rust-lang/rust/blob/1.62.0/library/core/src/convert/mod.rs#L530-L536) (note that the `DerefMut` bound is missing there) would (in stable Rust) be incompatible with an implementation of `AsMut<P> for P` for some type `P` that is also `DerefMut` (which includes `AsMut<Vec<T>> for Vec<T>`).

Thus, while the [first FIXME](https://github.com/rust-lang/rust/blob/1.62.0/library/core/src/convert/mod.rs#L509-L515) (for `AsRef` and `Deref`) could (theoretically, i.e. disregarding backward-compatibility) be implemented in stable Rust to create a consistent `AsRef` implementation, doing that for `AsMut` and `DerefMut` would not work unless useful implementations like [`AsMut<Vec<T>> for Vec<T>`](https://github.com/rust-lang/rust/blob/1.62.0/library/alloc/src/vec/mod.rs#L2910-L2915) would be removed.

* * *

Of course, it would still be possible to manually add such "auto-dereferencing" implementations like in the FIXME for _generic_ smart pointers such as `Rc`, `Arc`, etc. while providing a trivial implementation that just returns `&mut self` for non-generic \[1\] smart pointers such as `String`, `Vec<T>`, etc.

* * *

I created a Playground to illustrate that:

```rust
/* … */

// This blanket implementation works fine
impl<T, U> MyAsRef<U> for T
where
    T: ?Sized + MyDeref,
    U: ?Sized,
    <T as MyDeref>::Target: MyAsRef<U>,
{
    fn my_as_ref(&self) -> &U {
        self.my_deref().my_as_ref()
    }
}

// This blanket implementation conflicts with the following 6 implementations
/*
impl<T, U> MyAsMut<U> for T
where
    T: ?Sized + MyDerefMut,
    U: ?Sized,
    <T as MyDeref>::Target: MyAsMut<U>,
{
    fn my_as_mut(&mut self) -> &mut U {
        self.my_deref_mut().my_as_mut()
    }
}
*/

// Would be covered by blanket implementation
impl<'a, T, U> MyAsMut<U> for &'a mut T
where
    T: ?Sized + MyAsMut<U>,
    U: ?Sized,
{
    fn my_as_mut(&mut self) -> &mut U {
        self.my_deref_mut().my_as_mut()
    }
}

// Would be covered by blanket implementation
impl<T, U> MyAsMut<U> for Box<T>
where
    T: ?Sized + MyAsMut<U>,
    U: ?Sized,
{
    fn my_as_mut(&mut self) -> &mut U {
        self.my_deref_mut().my_as_mut()
    }
}

// Would NOT covered by blanket implementation
// because `<String as Deref>::Target` is `str` and not `String`
impl MyAsMut<String> for String {
    fn my_as_mut(&mut self) -> &mut String {
        self
    }
}

// Would be covered by blanket implementation
// because `<String as Deref>::Target` is `str`
// and `str` implements `AsMut<str>`
impl MyAsMut<str> for String {
    fn my_as_mut(&mut self) -> &mut str {
        self
    }
}

// Would NOT covered by blanket implementation
// because `<Vec<T> as Deref>::Target` is `[T]` and not `Vec<T>`
impl<T> MyAsMut<Vec<T>> for Vec<T> {
    fn my_as_mut(&mut self) -> &mut Vec<T> {
        self
    }
}

// Would be covered by blanket implementation
// because `<Vec<T> as Deref>::Target` is `[T]`
// and `[T]` implements `AsMut<[T]>`
impl<T> MyAsMut<[T]> for Vec<T> {
    fn my_as_mut(&mut self) -> &mut [T] {
        self
    }
}

/* … */

```

([Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1003cf9d3f1817b96f790637c3a540b7))

This is just to experiment with these traits a bit to see what's possible to do without features like coherence-impacting negative bounds or specialization with the goal to get a better understanding for `AsRef` and `AsMut`, and to be able to deduce whether these features could help in future. Due to the conflicting implementations (that are all desirable), I assume that coherence-impacting negative bounds are not sufficient here ~~, but that specialization is needed~~ to provide such an "auto-dereferencing" blanket implementation for `AsMut` _(edit: under the premise that `AsMut<String> for String`, `AsMut<Vec<T>> for Vec<T>`, etc. shall be implemented)_.

I do not want to imply that any of this could currently (or even with specialization) be implemented, as it would break existent code anyway (if I understand it right, especially where `.as_ref()` is used to dereference generic smart pointers as [demonstrated](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c087e3b9eff50cb131afcee0ccb24efe) in my [previous post](https://internals.rust-lang.org/t/semantics-of-asref/17016/6)).

* * *

I tested whether the "auto-dereferencing" blanket implementation for `AsMut` in combination with `impl AsMut<String> for String` and `impl<T> AsMut<Vec<T>> for Vec<T>` compiles with specialization, but it doesn't ([Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=6d3b4130faf765d88d493719c3cdd792)).

* * *

1. `Vec<T>` in this context isn't entirely generic because even if being generic over `T` it always points to a slice, i.e. `Deref::Target = [T]` and not `Deref::Target = T`.

---

_[View the full topic](https://internals.rust-lang.org/t/semantics-of-asref/17016)._
