Skip to content
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

Fixed-length arrays implement no traits #7622

Closed
huonw opened this issue Jul 6, 2013 · 11 comments
Closed

Fixed-length arrays implement no traits #7622

huonw opened this issue Jul 6, 2013 · 11 comments
Labels
A-type-system Area: Type system

Comments

@huonw
Copy link
Member

huonw commented Jul 6, 2013

Currently fixed-length arrays (i.e. [f64, .. 3]) implement no traits, because each size needs to be implemented separately. It'd be nice to be able to parameterise the length.

One consequence is that #[deriving] doesn't work with them (and gives strange error messages):

#[deriving(Eq)]
struct SuDoku {
    map: [[uint, .. 9], .. 9]
}
$ rustc --lib sudoku.rs
sudoku.rs:1:11: 1:14 error: mismatched types: expected `&&[[uint, .. 9]]` but found `&[[uint, .. 9], .. 9]` ([] storage differs: expected & but found 9)
sudoku.rs:1 #[deriving(Eq)]
                       ^~~
sudoku.rs:1:11: 1:14 error: failed to find an implementation of trait core::cmp::Eq for [uint, .. 9]
sudoku.rs:1 #[deriving(Eq)]
                       ^~~
@huonw
Copy link
Member Author

huonw commented Jul 30, 2013

Nominating for feature-complete.

@catamorphism
Copy link
Contributor

Just a bug, de-nominating

@huonw huonw changed the title Fixed-length vectors implement no traits Fixed-length arrays implement no traits Apr 13, 2014
@yokto
Copy link

yokto commented Jul 2, 2014

The way Haskell has solved this (at least in the case of tuples) is to simply add instances for the first 10 cases. Since, in Haskell, instances need not be in the same module as the class or datatype declaration, a programmer can always add instances for higher numbers if he needs them. Also, for the implementation of higher numbers the programmer could probably just use the implementation of non-fixed sized arrays.

@huonw
Copy link
Member Author

huonw commented Aug 10, 2014

@yokto we do the same for tuples (mainly via macro generated trait implementions), however the main use case for fixed sized arrays is "large" homogeneous sequences, the ratio between small and large fixed sized vectors will be smaller than small/large tuples so the small implementations won't be as helpful (unfortunately).

Also, for the implementation of higher numbers the programmer could probably just use the implementation of non-fixed sized arrays.

Currently [T, .. n] "inherits" functions from &[T] (and &mut [T]), since it coerces automatically, e.g. fixed_array.foo() will work if foo is a method on &[T]; however, this is not usable in generlc code, e.g. a Vec<[T, .. n]> can't be treated as a Vec<&[T]> because the memory representations differ. Furthermore, the dynamic Vec<T> incurs an allocation and a pointer indirection (along with 2 words of metadata) while [T, .. n] is literally just n instances of T stored inline, with no overhead.

This is important for low-level programming (like writing an operating system) where allocations are impossible, and also for performance, since stack allocation is nicer for CPU caches (as well as just avoiding the cost of doing the allocation).

@ghost
Copy link

ghost commented Nov 10, 2014

Fixed in #18486. Closing.

@ghost ghost closed this as completed Nov 10, 2014
@thestinger thestinger reopened this Nov 10, 2014
@thestinger
Copy link
Contributor

It doesn't seem like #18486 is relevant to this issue. It's still not possible to implement traits for fixed-size arrays of any size. An especially awful case is the lack of a Clone implementation for [T, ..n] where T: Clone.

@gifnksm
Copy link
Contributor

gifnksm commented Dec 7, 2014

This seems to be fixed: http://is.gd/B7JN4n (rust playpen).

@martinraison
Copy link

It looks like it's only fixed for arrays up to size 32: http://is.gd/LHWkJK

@apasel422
Copy link
Contributor

It's still a problem that arrays only implement Clone when T: Copy.

@amluto
Copy link

amluto commented Sep 8, 2016

This is particularly problematic with rust-bindgen. rust-bindgen generates things like this:

pub struct Union_Unnamed11 {
    pub _bindgen_data_: [u8; 283usize],
}

for unions, and the resulting struct cannot be Copy at all and cannot derive Clone.

It looks like this could be very cleanly fixed if rust-lang/rfcs#1038 (types parametrized over numbers) happened.

@aturon
Copy link
Member

aturon commented Apr 15, 2017

Closing; this issue is really subsumed by the desire for const generics, and we've done all we can until those land. (And when they do come, we'll generalize the current trait impls accordingly.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

9 participants