1

I have a simple question. This program throws an error:

fn main() {

    let string_literal = "hello world";
    println!("Here is an invalid slice: {}", string_literal[..3]);

    // using &string_literal[..3] fixes this issue
}

That says the size for values of type `str` cannot be known at compilation time

I thought that because string_literal is immutable, Rust could know its size.

What is happening and why would adding the ampersand fix it immediately, as shown in the comment in my function?

Thanks :)

  • 1
    Have a look at [this](https://stackoverflow.com/a/57754902/11527076). – prog-fh Aug 25 '21 at 13:57
  • 1
    And [this](https://stackoverflow.com/questions/49393462/what-does-str-does-not-have-a-constant-size-known-at-compile-time-mean-and) – forgetso Aug 25 '21 at 13:58

1 Answers1

4

Types in Rust can be sized and unsized. Unsized types, do not have a size required which is known at compile time. For example, [u32] is an unsized array of u32s; because the number of elements is not specified anywhere, the compiler doesn't know its size.

Unsized types can be used through a pointer, because pointers always have a fixed and known size, they can be stored in local variables and be passed into or returned from functions.

Note that fat pointers int Rust can also carry additional information such as the length of available data for slices (&[u32]) or a pointer to a virtual table (Box).

Here, string_literal[..3] is an unsized type, and can not be passed to a function, but when you put an &, you are passing the pointer to that string, so it works.

Note that in your question the phrase "This program throws an error" is not exactly correct. Because when you say so, it is understood as the program is compiled and throw an error at runtime. However in this case compilation is failing.

  • 2
    Whilst unlikely, it's not *inconceivable* that (with const generics) in the future `string_literal[..3]` could be sized. – eggyal Aug 25 '21 at 14:08
  • @eggyal While not inconceivable, it _would_ require `string_literal[..3]` and `string_literal[..n]` to have different types. And so would `string_literal[..function()]` and `string_literal[..const_function()]`, etc. – user4815162342 Aug 25 '21 at 18:34
  • @user4815162342: agreed. The desugaring of indexing brackets would have to differ depending on whether the contained value is constant or not; and that’s unlikely to even be considered (let alone accepted) until traits can declare const fns. – eggyal Aug 25 '21 at 19:31