Purpose of ?Sized in Index

pub trait Index<Idx: ?Sized> {
    type Output: ?Sized;

    fn index(&self, index: Idx) -> &Self::Output;
}

When I implement Index for some type and use ?Sized because why not

impl<Idx: ?Sized> Index<Idx> for Field {
    type Output;

    fn index(&self, index: Idx) -> &Self::Output {
        todo!()
    }
}

I get an error

the size for values of type `Idx` cannot be known at compilation time [E0277]

main.rs(113, 6): this type parameter needs to be `std::marker::Sized`

main.rs(113, 9): consider removing the `?Sized` bound to make the type parameter `Sized`

main.rs(116, 28): function arguments must have a statically known size, borrowed types always have a known size: `&`

So given that arguments must be Sized, what's the purpose of ?Sized in Index?
(Don't know if this really goes in the Help category since this is just me being curious)

Help category is correct. When posting error messages, make sure to not copy stuff from IDEs but use the error message from cargo check in the terminal instead, since that's way more readable.

Why the index is allowed to be ?Sized, I'm not entirely sure, it's certainly nor really useful at the moment - on the other hand, apart from possibly causing confusion for the reader, there shouldn't be any downsides either.

There are developments to allow unsized values as function parameters eventually, IIRC, so with that in mind it might eventually become useful, at least in principle? Though even then, I think that relaxing the bound to ?Sized at a later point wouldn't have been problematic either.

Accident of history, looks like. The index used to be passed as &Idx.

3 Likes