Closed
Description
The conversion traits, in my books, serve one primary role: convenient generic one-time conversions to a concrete type to make APIs "just work". For instance, fn foo<P: AsRef<Path>>(path: P)
"just works" for the various kinds of string.
Invoking them in this kind of generic context is pretty much guaranteed to work because of the magic of trait resolution in generic contexts. However outside of this context, they can and will behave in wild and uncontrolled ways. There are two major issues I see:
- In concrete contexts, the pervasiveness of implementations of this trait means it will basically always do something, but deref coercions and inference mean that it's unlikely to be the thing you want, nor is it likely to do it in a stable manner. So for instance,
let x = y.as_ref()
may plausibly yield y
, &y
, &*y
, &**y
, or some particular concrete impl depending on the type of y (and x?).
- You can't trust traits. Just because something implements AsRef and AsMut, doesn't mean they agree. Just because you called AsRef once before, doesn't mean the next call will yield the same result. These traits are for conversions -- not for building some kind of generic polymorphism framework on top of.