In Rust 1.14, the Index
trait is defined as follows:
pub trait Index<Idx> where Idx: ?Sized {
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
The implicit Sized
bound of the Output
type is relaxed with ?Sized
here. Which makes sense, because the index()
method returns a reference to Output
. Thus, unsized types can be used, which is useful; example:
impl<T> Index<Range<usize>> for Vec<T> {
type Output = [T]; // unsized!
fn index(&self, index: Range<usize>) -> &[T] { … } // no problem: &[T] is sized!
}
The Idx
type parameter's implicit bound is also relaxed and can be unsized. But Idx
is used by value as method argument and using unsized types as arguments is not possible AFAIK. Why is Idx
allowed to be unsized?
I'm pretty sure this is just an accident of history. That looser bound was introduced in 2014. At that time, the trait looked a bit different:
// Syntax predates Rust 1.0!
pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Result;
}
Note that at this point in time, the Index
type was passed by reference. Later on the renamed Idx
type changed to pass by value:
fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
However, note that both forms coexisted in the different compiler bootstrap stages. That's probably why the optional Sized
bound couldn't be immediately removed. It's my guess that it basically was forgotten due to more important changes, and now we are where we are.
It's an interesting thought experiment to decide if restricting the bound (by removing ?Sized
) would break anything... maybe someone should submit a PR... ^_^
Thought experiment over! Lukas submitted a PR! There's been discussion that it might break downstream code that creates subtraits of Index
like:
use std::ops::Index;
trait SubIndex<I: ?Sized>: Index<I> { }
There's also talk that someday, we might want to pass dynamically-sized types (DSTs) by value, although I don't understand how.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With