Reputation: 11
https://doc.rust-lang.org/src/core/ops/range.rs.html#979-986
impl<T> RangeBounds<T> for Range<&T> {
fn start_bound(&self) -> Bound<&T> {
Included(self.start)
}
fn end_bound(&self) -> Bound<&T> {
Excluded(self.end)
}
}
As you can see, T
is not marked with ?Sized
, which is preventing me from passing a Range<&[u8]>
into an argument requires impl RangeBounds<[u8]>
.
Are there some design considerations behind it? If this is intended, which is the proper way to pass a range of [u8]
?
Upvotes: 1
Views: 1299
Reputation: 28025
It's rather unfortunate, but adding the T: ?Sized
bound breaks type inference in code like btreemap.range("from".."to")
because the compiler can't choose between T = str
and T = &str
, both of which satisfy the bounds on range
.
Some discussion of this has taken place on PR #64327. As far as I know there are no plans to relax the bounds on these impl
s in the future.
Instead of a Range<T>
, you can use a tuple of Bound<T>
s; for example, instead of takes_range("from".."to")
, you can write the following instead:
use std::ops::Bound;
takes_range((Bound::Included("from"), Bound::Excluded("to"))
This will work because (Bound<&T>, Bound<&T>)
does implement RangeBounds<T>
even when T
is !Sized
.
Upvotes: 2