I was looking at the Allocator API that is currently being stabilized and noticed that it has an Allocator::by_ref method.
I don't really understand what that method is for. It seems to simply return a shared reference to the allocator, so how is it any different from a simple borrow? Also the documentation for by_ref talks about returning an adapter of some kind, which it clearly does not do.
I would appreciate any insight or further reading on why this method exists and what the documentation is talking about.
That doesn't really explain much. The iterator by_ref has all the same oddities. It seems to do nothing other than return a simple borrow and its documentation also talks about returning an adapter of some kind, which it does not seem to do.
Are these just convenience methods with oddly worded documentation?
yes, these are convenience methods.
the purpose i would think would be made clear by the example in the iterator case.
x.by_ref().other_method().yet_another() is meant to be a nicer way to write
(&mut x).other_method().yet_another()(yes the parentheses are necesary)
or for the Allocator case (&x).other_method().yet_another()
it is quite unclear to me why there is such a method on Allocator though
The documentation should maybe actually say this, because I could not for the life of me figure out what it was doing from the existing documentation, but this makes perfect sense.
That’s not a good reason to have it for Allocator, though. I can see that someone might want to pass &MyAllocator when constructing a container, but that will never be a method chain.
Iterator::by_ref is useful because many of the methods take self, especially when creating new adaptors, but there is also the blanket impl on &mut I so you can have those capture a reference instead via iter.by_ref().foo() -- or equally (&mut iter).foo(). io::Read::by_ref is similar since there are self methods for adaptors.
io::Write and Allocator also have similar blanket impls, but they don't have anyself-consuming methods AFAICS, so I don't know why we should want by_ref(). I only found two existing uses of Allocator::by_ref in Arc/Rc::from_box_in, and both would be more succinct to use &alloc.
Perhaps (in the case of Iterator) it's as simple as, it only makes sense for &mut. (OTOH it's a 1.0 method, there may not have been much conversation. I didn't dig.)
these are trait methods. (for example on Iterator), so as_ref is available on every iterator and only on iterators.
you cannot impl<I : Iterator> AsMut<Self> for I, that would be against the orphan rule.
AsMut ofc is not reflexive.
BorrowMut is relexive, but then it is on every type and can get noisy, as well as conflict with inherent methods.