Change:
Links: , . Those docs have plenty of text. I've read it dozens of times and felt "uhhh, what" every single time. Well, the text sort of makes sense, but, in the end, it doesn't help me in deciding between and . So I just had to dig myself through the APIs and try figuring the mystery by myself. :) Here are some notes I've collected afterwards. I wonder if we could get at least some of the following stuff into the official docs... () should be 'borrows', but cannot be implemented yet due to coherence issues (I believe?) Key takeaways: is simple and strict. The hash of the borrowed reference must stay the same. converts to a wider range of different types. The hash of the new reference is allowed to change. We want to implement a function that creates a directory. It must accept both and as the argument. Which signature are we looking for? Answer: In order to go from to , we have to create a value of different type ( is more primitive - it cannot be borrowed as ). Since can borrow and convert, it is the correct option here. We want to check whether a value exists in a . Even if we have a set of type , we'd like to be able to just do (passing a ). Which one of the four method signatures is the right one? Answer: We don't want to convert between totally different types, so the hash and structural equality of the value must be preserved after reference conversion. In other words, we only want simple borrowing. Conversion to a different type might potentially change the hash and is thus out of the question. So is the right one here. But is it or ? Well, if is and we're passing a to the method, we want to borrow as . So the right bound is .
Possibly redundant with or or
I'm willing to work on this soon, updating both the book and the rustdoc. I think that the main thing that isn't conveyed right now is the fact that requires that the data be functionally the same (providing the same trait impls) whereas reinterprets the data differently (e.g. str -Path).
I’ve been planning to write some text for the documentation of and . In particular, I think what is currently lacking is a one-sentence summary of the purpose of the two. This seems important to me because if one reads a type implementing a trait as ‘being something,’ is backwards: can intuitively be read as is a borrow of when in fact it is the other way around. This had me seriously confused when looking at the signature of . So, for my proposal would be something along the line of: ‘If a type implements , it signals that the type acts as a kind of pointer to the type.’ (Pointer may not be the right word here, but I feel that using ‘borrow’ to explain is a bit weird.) Conversely, perhaps: ‘By implementing , a type signals that it can provide a view of itself as .’ (That one probably needs some work.)
are you still planning on working on this or do you mind if I give it a shot?
I completely forgot! Go ahead and I can still offer to review it after. :)
This is documentation on these conversions so far, I've found. As someone else is working on the docs, at the very least - I'd link to this discussion, on the book.
I continuously get confused between and . I think the mental rule to remember is that is really . Then it all becomes a lot clearer. Of course, we can't actually rename the trait at this point. A related discussion to this (I think) is what a user should do if they want to take any type that can be borrowed into an including . In that case you must use , since there is no .
we’ve tried to build this sort of mental model for in . If you haven’t yet, could you perhaps check if it feels more clear? As for the missing blanket , I haven’t found that to be all that much of an issue in practice, since in most cases I use for some concrete – and come to mind, and those types so far have always had that impl anyway. You can’t use in these cases, necessarily, since it comes with additional restrictions. The new documentation has the example of a newtype for a string that compares without considering ASCII case. While that newtype can , it mustn’t have as that would break hash maps and the like.
The new documentation is certainly better! I think the confusion stems mostly from the name of the trait though. When I read , I instinctively think "I can borrow from a ", whereas the reality is the other way around. Even reading the example it seems pretty weird: my intuition would be that we need to satisfy some bound for it to be usable as a key, whereas it's phrased as a bound on . It's almost like is "backwards"? I think one thing the documentation could use is an explicit "which should I implement and why" section. It's currently mixed in with the example, but I think it could use being called out. I also found the statement "For instance, a can be borrowed as while a can be borrowed as " somewhat weird. I understand that it's technically correct, but I'd probably be more inclined to say that can be borrowed as (and similarly ). For the lack of a , I think this is where some libraries use , and maybe that's worth referencing here too?
I've taken a stab at this at It seems like explicitly mentioning that every impl of Borrow must maintain Eq, Ord, Hash would do the trick.
I wanted to say that despite this issue being closed and the docs presumably improved, I still found the table, explanation and examples here to be clearer and more illuminating than any of the material in the docs.
I agree, and it took me a while to find this thread. I'd argue the docs should be updated with a lot of the information here. I didn't get from the docs that is meant to be read as "borrow as" and maintain the original semantics of the value (which is a more intuitive but possibly less accurate way of saying , , and are preserved), whereas is applicable for conversions between related reference types (or something like that). As a Rust newbie, this also leaves me wondering why I shouldn't just use or for conversions instead of . I'm guessing it has something to do with being generally more expensive, but I don't have a strong grasp of the reasoning for this, or when I'd use either at all. So now I'm going to have to spend a bit of time that too.
I think that regardless, "this needs better documentation" is a pretty hard issue to track. Documentation can pretty much always be improved, and without concrete things that need to be done, it's better to just encourage people to do further revisions until everyone is satisfied rather than keeping an issue open to track it.

Discussion:
/// on the identical behavior of these additional trait implementations. /// These traits will likely appear as additional trait bounds. /// <ins> /// In particular `Eq`, `Ord` and `Hash` must be equivalent for /// borrowed and owned values: `x.borrow() == y.borrow()` should give the /// same result as `x == y`. /// </ins> /// If generic code merely needs to work for all types that can /// provide a reference to related type `T`, it is often better to use /// [`AsRef<T>`] as more types can safely implement it.

/// `&T` or write a custom function. /// /// <del> /// `AsRef` is very similar to, but serves a slightly different purpose than [`Borrow`]: </del> <ins> /// `AsRef` has the same signature as [`Borrow`], but `Borrow` is different in few aspects: </ins> /// <del> /// - Use `AsRef` when the goal is to simply convert into a reference /// - Use `Borrow` when the goal is related to writing code that is agnostic to ///   the type of borrow and whether it is a reference or value </del> <ins> /// - Unlike `AsRef`, `Borrow` has a blanket impl for any `T`, and can be used to accept either ///   a reference or a value. /// - `Borrow` also requires that `Hash`, `Eq` and `Ord` for borrowed value are ///   equivalent to those of the owned value. For this reason, if you want to ///   borrow only a single field of a struct you can implement `AsRef`, but not `Borrow`. </ins> /// /// [`Borrow`]: ../../std/borrow/trait.Borrow.html ///