Reputation: 960
The line assigning arguably a slice literal
let integers: [i32] = [ 1, 2, 3 ][..];
gives a message that integers
“doesn't have a size known at compile-time”. Why is it not obvious that storage space is needed for three i32
and one usize
? Is my thinking wrong or why can the compiler not see this?
Probably related is https://doc.rust-lang.org/reference/types/slice.html saying “Slice types are generally used through pointer types.” My guess is that this general rule is enforced that the current compiler simply disallows uses of slice without indirection, but the associated compiler message is misleading; so type policy, not size is at the core of the problem here. (From @colonel-thirty-two's answer In Rust, why is '[T]' and 'str' slice type not a syntax error? I learn that this may possibly change in not so near future.)
I also note that https://doc.rust-lang.org/rust-by-example/primitives/array.html does not discuss [T], but &[T].
Upvotes: 1
Views: 642
Reputation: 8678
Rust uses types to convey information it has at compile time. Indeed, if you were to let Rust infer the type if [1, 2, 3]
, it would tell you it's a [i32; 3]
, and everything would work fine. By coercing [i32; 3]
into [i32]
, you force the compiler to lose the information about the size of the array.
Besides, note that [1, 2, 3]
does not store three i32
and a usize
, but just three i32
. Rust makes the (very reasonable) choice of storing the size of unsized types (as well as other information, if required) alongside pointers to that data, not within that data. This allows arbitrary slicing without copying any data. These pointers, in Rust, are called "fat pointers".
Finally, unsized types are not necessarily behind pointers. For instance, if you were to create a struct, its last field can be an unsized type:
struct A {
x: i32,
y: [i32],
}
the reason for this peculiar restriction is that unsized types is not a finished feature, and since there isn't much pressure for completing it, it will probably stay in this half-baked state for some time.
Besides, rust currently doesn't allow values stored on the stack (which includes variables) to have unsized types, but it's only a temporary limitation, and there is a WIP feature to remove this limitation.
Also, unsized types are somehow unique to Rust. In most other typed languages, there is no such thing. All types must have a size defined at compile time or (as in C, for instance), types whose size is not known cannot be instantiated at all.
Upvotes: 7