Why do I get the error E0277: the size for values of type `[{integer}]` cannot be known at compilation time?

Viewed 4585

In the following code I am getting the error:

error[E0277]: the size for values of type `[{integer}]` cannot be
known at compilation time at the line `for n in numbers[1..] {`

I did some searching around, but found nothing.

fn main() {
    let mut numbers = Vec::new();
    numbers.push(1);
    numbers.push(32);
    numbers.push(43);
    numbers.push(42);
    // ... And many more
    println!("{:?}", numbers); // Sanity

    let mut sum = 0;

    // Problem code area
    for n in numbers[1..] {
        sum = sum + n;
    } 
    // Problem code area

    println!("{}", sum);
}

Also, the problem lines work if I replace them with following (adding & and * for ownership/borrowing and dereferencing)

for n in &numbers[1..] {
    sum = sum + *n;
}

Why is the compilation failing in the former way?

1 Answers

numbers[1..] doesn't have a size because it is a bare¹ slice of numbers. Slices can only be used behind some kind of pointer, e.g. &[T], Box<[T]>, or Arc<[T]>. The following questions have more information about slices:

Because it is unsized, [T] cannot implement IntoIterator, which is the trait used for iterating over things in for loops. (See Why can I iterate over a slice twice, but not a vector?) IntoIterator::into_iter has the following prototype:

fn into_iter(self) -> Self::IntoIter;

Self cannot be an unsized type because into_iter takes self by value.

&numbers[1..] is a reference (type &[T]), which both has a size and implements IntoIterator, so it works fine.

The full compiler output also gives an error message about IntoIterator, and helpfully suggests using numbers[1..].iter() instead. Because .iter() takes &self, it can be called on an unsized type, so this is another way to fix the problem.


¹In many places, including the official documentation, the unqualified term "slice" is used to refer to the reference type &[T]. I call numbers[1..] a bare slice because it is not a reference; its type is just [T].

Related