-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Extend and stabilize the FixedSizeArray trait #1915
Conversation
Can we somehow make it so that a fn example<Array: FixedSizeArray<Item=Foo>>(array: Array) -> Foo {
array[42]
} If so, I suggest a little syntax sugar: fn example<Array: [Foo]>(array: Array) -> Foo {
array[42]
} I.e., |
@glaebhoerl Arrays don’t implement use std::ops::*;
fn a<T: Index<usize>>(_: &T) {}
fn main() {
a(&[0_u8; 10])
} error[E0277]: the trait bound `[u8; 10]: std::ops::Index<usize>` is not satisfied
--> a.rs:6:5
|
6 | a(&[0_u8; 10])
| ^ the trait `std::ops::Index<usize>` is not implemented for `[u8; 10]`
|
= note: the type `[u8; 10]` cannot be indexed by `usize`
= note: required by `a`
error: aborting due to previous error I think that what happens when you use the |
Interesting. Together with the observation that the original formulation of the (To be clear what I'm interested in is indexing syntax working once you have a |
This compiles: #![feature(unsize)]
fn foo<T, A: ::std::marker::Unsize<[T]>>(a: &A) {
&(a as &[T])[0];
} But |
Humbug. I still think it'd be nice if it could be made to work somehow. :) |
If I understand, you could not write |
@burdges There are two problems to solve, rust-lang/rust#40008 makes |
If the (Separately, I don’t know if an associated type is preferable over a type parameter in this case. Any opinion?) |
I think we should mention that this only enables a limited set of generic code in the drawbacks. For example, A slightly more concrete example which is similar to something we do in Diesel would be if you have a trait where you want to take ownership, and abstract over single/multiple values. You might write something like this: fn insert<T: Insertable>(records: T) -> IncompleteInsertStatement<T> {
// ...
}
impl<T: Insertable> Insertable for Vec<T> {
// ...
} You would not be able to write |
@sgrif |
@plietar That would fix the impl<ST, T: FixedSizedArray> AsExpression<Array<ST>> for T where {
} But that would conflict with impl<ST, T: Expression<SqlType=ST>> AsExpression<ST> for T {
} regardless of whether |
If we're making the trait work through "compiler magic" anyways, as proposed in the RFC, implemented only by the built-in array types, we might as well let the compiler's left hand know what its right hand is doing and use this information for coherence as well. |
As an aside, the
often enough to consider writing a macro like
except it's not quite that homogeneous. |
Additionally, it does not prevent a more general solution from also happening in the future. | ||
|
||
Arrays are the only case where integers occur in types, in current Rust. | ||
Therefore a solution specifically for arrays |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just handling arrays doesn't enable things like C++'s std::chrono, so it's definitely not "all". Maybe scope the claim to "std's current trait implementations for arrays" or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain what C++’s std::chrono
is and how it relates to arrays?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On re-reading you comment it sounds like it doesn’t involve arrays, but it might involve type-level integers? Yes, this RFC does not entirely remove the need for type-level integers, but it doesn’t prevent adding them later either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, apparently I put this comment on a poor choice of line; I thought it had the next one in the context too.
I agree with your comment, just think the motivation is over-selling itself by talking about covering "many (all?) of the use cases for type-level integers". Probably an ignorable nitpick.
Hmm, are associated constants const
enough to be used in type checking? Would this enable fn pop_array<T:Array>(x : T) -> [T::Item; T::LENGTH - 1] { ... }
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I asked this up thread and @eddyb answered : #1915 (comment) This now works when T
is some fixed type, but it does not yet work if T
is a type parameter like in your question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where "now" is whenever rust-lang/rust#40008 gets merged.
Remove ≥496 I think there are two trait impls on array this can't replace, though: Maybe also have this function on the trait: Then Could even be useful elsewhere for initialization. Silly example: And, bikeshedding, I like |
I think that |
I suppose that could be done roughly as follows :
|
I found the line "doing this shouldn’t be necessary if we assume that Rust is going to have type-level integers .. eventually" kinda tricky. I think it's true because you can do type equality tests like Also, I suspect he associated type
would usually be preferable to
even if you have type-level integers. |
Right now, I suppose the cleanest way to get
|
I’ve toned down the wording of this RFC. Also, #1931 has since been submitted and https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090 gives a very positive signal:
Since proper const generic now have a much clearer path forward than it seemed when I submitted this RFC, I hereby rescind it. |
Extend and stabilize the
FixedSizeArray
trait, as a stop-gap solution for integer parameters in generics.Rendered