Length of array prevents compilation?

If I have a small buffer, I can open a Cursor on it. This code works:

use bytes::Buf;
use std::io::Cursor;

const BUF_SIZE: usize = 32;

fn main() {
   let mut b = [0u8; BUF_SIZE];
   b[1] = 1;

   let mut c = Cursor::new(b);

   assert_eq!(0, c.get_u8());
   assert_eq!(1, c.get_u8());
}

If, however, I increase BUF_SIZE to 128, the code will not compile:

error[E0599]: no method named `get_u8` found for type `std::io::Cursor<[u8; 128]>` in the current scope
  --> src/main.rs:12:20
   |
12 |    assert_eq!(0, c.get_u8());
   |                    ^^^^^^ help: there is a method with a similar name: `get_mut`
   |
   = note: the method `get_u8` exists but the following trait bounds were not satisfied:
           `std::io::Cursor<[u8; 128]> : bytes::buf::buf::Buf`

Why?

Thanks in advance,
Aaron

Looking into the doc, guides us that &b[..] works.

The reason 32 works while 128 doesn’t is that std implements AsRef<[T]> for [T; from 0 upto 32 only].

Hopefully, const-generic will land soon to resolve these cases.

1 Like

Well, if we track down the error, using the error message, we can see that it occurs because Buf isn’t implemented on [u8;128]. Following through, on the types that impl Buf, we can see that this is impled for Curstor<T>:

impl<T: AsRef<[u8]>> Buf for Cursor<T>

But, not every array implements AsRef<[u8]>, as can be seen here. It only included arrays of sizes [T; 0..=32]


Please bear in mind that in the future, this will be alot more easy to deal with, as though const generics will be available, and make dealing with generic implementations on arrays easier.

2 Likes