Today I’ve noticed that Index
is defined as follows:
pub trait Index<Idx: ?Sized> {
#[stable(feature = "rust1", since = "1.0.0")]
type Output: ?Sized;
#[stable(feature = "rust1", since = "1.0.0")]
fn index(&self, index: Idx) -> &Self::Output;
}
why do we need Idx: ?Sized
if we accept index by value anyway? Shouldn’t https://github.com/rust-lang/rust/pull/23601 removed this anti-bound as well?
One can use unsized_locals
for this… Here’s just an example to make it compile:
#![feature(unsized_locals)]
use core::ops::Index;
use core::fmt::Debug;
type A<'a> = &'a dyn Index<dyn Debug, Output = u8>;
fn main() {
let x: A<'_> = panic!();
let y: dyn Debug = *(&0 as &dyn Debug);
x.index(y);
}
If that is useful remains to be seen. However, it is a breaking change to enforce Idx: Sized
.
I wonder if there's real code that breaks. rust-lang/rust test suite passes if I remove the bound.
EDIT: which probably means that we either need to remove the bound, or to add a test for it.
Unlikely I think because of the lack of stable unsized_locals
. However, I rather leave the un-bound in for future-compat purposes. Is there a specific reason you want to remove ?Sized
?
I would happily r+ a PR that adds a test! Thank you for discovering the lack thereof.
1 Like
Consistency: we generally don't have ?Sized
bounds unless there's a strong reason to have one. For example, Add is defined as trait Add<RHS=Self>
.
I definitely think that we should not blindly add a test for this. I guess I'll send a PR for the libs team to review. It may be the case that we want this to be ?Sized
, but than we need to figure out if we can change over operators to follow the suite.
EDIT: PR is up https://github.com/rust-lang/rust/pull/59527
Hmm... I mostly was looking for a use-case. Consistency is valuable, but I wouldn't want to reduce future potential expressiveness just for that.
The test can easily be removed whenever, there's no problem in adding it now.
1 Like
That’s an extremely personal opinion, but I prefer to reduce expressiveness of things unless there’s a strong reason that expressiveness is required Expressiveness and “easy to understand” tend to oppose each other (https://www.tedinski.com/2018/01/30/the-one-ring-problem-abstraction-and-power.html is a good blog post on this topic).
In this particular cases, I imagine that, with by-value DSTs implemented, someone might accidentally write Index<[usize]>
instead of Index<&[usize]>
for multidimensional array indexes, and get an excessive stack usage.
1 Like
I think this is a case of "I cannot tell the future".
matklad:
In this particular cases, I imagine that, with by-value DSTs implemented, someone might accidentally write Index<[usize]>
instead of Index<&[usize]>
for multidimensional array indexes, and get an excessive stack usage.
Seems lintable? We can test this out and see if it actually becomes a problem.
qnighy
April 5, 2019, 2:32pm
9
I’d also make Add
a subtrait of Sized
then. Self
and RHS
are almost symmetric but only RHS
has the Sized
bound.
1 Like
matklad:
In this particular cases, I imagine that, with by-value DSTs implemented, someone might accidentally write Index<[usize]>
instead of Index<&[usize]>
for multidimensional array indexes, and get an excessive stack usage.
DSTs are always passed by pointer, I don't see how fn index(&self, a: [usize])
will cause excessive stack usage.
qnighy
April 6, 2019, 12:03am
11
The current implementation of unsized_locals
is naïve and may allocate unnecessary variable-length temporaries to move the slice into.
system
Closed
July 5, 2019, 12:05am
12
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.