Is BTreeMap::range incompletely defined?

If the key type isn't trivial (there's probably a better word for that), calling range(..) on a BTreeMap or BTreeSet makes the compiler cry E0283 "type annotations needed", forcing us to specify the collection's key type again, as in this playground example.

Is this a recurring issue with RangeFull in Rust or a weak spot in the definition of range? I don't know if or how T could default to the key type K.

It's definitely a limitation in some cases that RangeFull has no type parameter, but it wouldn't make your case easier if it did, only shift where the type needs to be annotated. Note that range::<[u8], _>() would also be valid for your example.

Defaults aren't allowed for type parameters on functions or methods:

shift where the type needs to be annotated

Well, apparently the type doesn't need to be annotated. if K is something like i32 or Option<u8>, but it needs to be if it's String or an array. How do types earn the privilege of passing through the range gate without showing their badge?

I believe the difference is whether the key has any Borrow besides the reflexive Borrow<T> for T. Arrays [T; N] also implement Borrow<[T]>, and String also implements Borrow<str>.

2 Likes

Right, Borrow definitely seems to be the culprit.

I don't know how the libs team would feel, but I think you could argue for a range_full() method to avoid this ambiguity.

range_full() kind of exists as iter(), although the type is wrapped - not sure if that ever makes a difference in practice.

I ran into this surprise for a range-based drain. So there's an argument to rename that to drain_range, as opposed to the range-based Vec::drain, and have a separate drain similar to HashMap::drain.