Rust considers indexing expressions like [0..8] to be entirely runtime-calculated index values. You might as well have used two random values x and y and written self.array[x..y], so the size of this part of the array is completely unknown; hence it’s represented as the slice type [u8] which can only be interacted with in Rust if its kept behind some indirection.
So the expression &self.array[0..8] works fine. (Don’t think of the self.array[0..8] part of this expression as evaluating to it’s own thing, on a first approximation, the &foo[ix] syntax stands for a single step/operation at run-time).
Iterating over &[T] with a for loop works, too, due to its IntoIterator implementation. The items i will be of type &T, in this case &u8. If you’d like to have them by-value, you might as well write for &i in &self.array[0..8] to pattern match the level of reference away.
Analogous operations are possible with mutable references, too, so something like
I'm curious, why does Rust consider self.array[0..8] as a unknown sized slice? Is there a reason why the compiler cannot see the range mentioned? Or are there some design reasons for this?
I'm also still unsure why does the indirection via reference works. Why would the compiler let you do that?
I tried to explain everything above. Try to ask a more specific question, what part you don’t understand
I assume your question is why the compiler isn’t “smart enough” so see the compile-time-known indices here. The answer is: It’s hard to offer this via the same API without potentially getting some confusing or inconsistent behavior. Whether something is or isn’t “compile-time-known” would presumably be more of a heuristic result than a clear rule, on the other hand the return type ([T] vs [T; N]) would depend on that, and types should be more predictable.
Also, changing it now could lead to breakage as [T] and [T; N] are – though usable interchangably in many contexts – distinct types. The only reasonably action would be to introduce a new syntax or method for constant-indexing arrays. In fact some work in this direction is being done with this or this method, and on stable rust, you can also convert &[T] back to fixed-sized &[T; 8] (or other lengths) with the relevant TryFrom implementation and an unwrap.