Why is the return type of Deref::deref itself a reference?
that references don't implement
Deref
You can see all the types that implement Deref
, and &T
is in that list:
impl<'a, T> Deref for &'a T where T: ?Sized
The non-obvious thing is that there is syntactical sugar being applied when you use the *
operator with something that implements Deref
. Check out this small example:
use std::ops::Deref;
fn main() {
let s: String = "hello".into();
let _: () = Deref::deref(&s);
let _: () = *s;
}
error[E0308]: mismatched types
--> src/main.rs:5:17
|
5 | let _: () = Deref::deref(&s);
| ^^^^^^^^^^^^^^^^ expected (), found &str
|
= note: expected type `()`
found type `&str`
error[E0308]: mismatched types
--> src/main.rs:6:17
|
6 | let _: () = *s;
| ^^ expected (), found str
|
= note: expected type `()`
found type `str`
The explicit call to deref
returns a &str
, but the operator *
returns a str
. It's more like you are calling *Deref::deref(&s)
, ignoring the implied infinite recursion.
Xirdus is correct in saying
If
deref
returned a value, it would either be useless because it would always move out, or have semantics that drastically differ from every other function
Although "useless" is a bit strong; it would still be useful for types that implement Copy
.
See also:
- Why does asserting on the result of Deref::deref fail with a type mismatch?
Note that all of the above is effectively true for Index
and IndexMut
as well.
The compiler knows only how to dereference &-pointers - but it also knows that types that implement Deref
trait have a deref()
method that can be used to get an appropriate reference to something inside given object. If you dereference an object, what you actually do is first obtain the reference and only then dereference it.
If deref()
returned a value, it would either be useless because it would always move out, or have semantics that drastically differ from every other function which is not nice.