rust type_error ai_generated true

error[E0277]: the size for values of type `str` cannot be known at compilation time

ID: rust/e0277-str-not-sized

Also available as: JSON · Markdown
95%Fix Rate
95%Confidence
120Evidence
2018-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1 active

Root Cause

The type `str` is a dynamically sized type (DST) -- its size is not known at compile time because strings can be any length. Rust requires all local variables, function parameters, and return types to be Sized by default. You cannot use `str` directly; you must use it behind a pointer: `&str` (borrowed string slice), `String` (owned heap string), or `Box<str>` (owned boxed slice). This is one of the most common errors for Rust beginners encountering the Sized trait bound system.

generic

Workarounds

  1. 95% success Use &str for borrowed string references (most common fix)
    // Before (error):
    fn greet(name: str) { // E0277: str is not Sized
        println!("Hello, {name}");
    }
    
    // After: use a reference
    fn greet(name: &str) {
        println!("Hello, {name}");
    }
    
    // For struct fields:
    struct Config<'a> {
        name: &'a str,  // Borrowed string slice with lifetime
    }
    
    let cfg = Config { name: "production" };

    Sources: https://doc.rust-lang.org/book/ch04-03-slices.html#string-slices

  2. 93% success Use String for owned string data
    // When you need ownership (e.g., storing in a struct without lifetimes):
    struct User {
        name: String,  // Owned, heap-allocated, Sized
    }
    
    impl User {
        fn new(name: &str) -> Self {
            User { name: name.to_string() }
        }
    }
    
    // For function parameters that need ownership:
    fn store_name(name: String) {
        // name is owned and can be stored
    }

    Sources: https://doc.rust-lang.org/book/ch08-02-strings.html

  3. 80% success Use Box<str> for owned string data with minimal overhead
    // Box<str> is a thin pointer + length, slightly smaller than String
    // (no capacity field). Useful for immutable owned strings:
    let boxed: Box<str> = "hello".into();
    let boxed: Box<str> = String::from("hello").into_boxed_str();
    
    // In generic contexts with ?Sized bound:
    fn print_it<T: AsRef<str> + ?Sized>(val: &T) {
        println!("{}", val.as_ref());
    }
    print_it("literal");        // &str
    print_it(&String::from("owned")); // &String

    Sources: https://doc.rust-lang.org/std/boxed/struct.Box.html

Dead Ends

Common approaches that don't work:

  1. Add #[repr(C)] or other layout attributes to make str Sized 95% fail

    repr attributes control memory layout of structs and enums, not the fundamental property of str being a dynamically-sized type. str is an unsized type at the language level -- it represents a UTF-8 byte sequence of unknown length. No attribute can change this; it is intrinsic to how str is defined in the language.

  2. Use str as a struct field type directly without indirection 90% fail

    Struct fields must be Sized (unless the very last field uses ?Sized). Declaring `field: str` makes the entire struct unsized, which means it cannot be stack-allocated, returned from functions, or used as a local variable. The struct becomes essentially unusable without Box or other indirection for the entire struct.

Error Chain

Leads to:
Preceded by:
Frequently confused with: