Generics & references

    struct Test<T> {
        _phantom: std::marker::PhantomData<T>,
    }
    let string = Test::<String> {
        _phantom: std::marker::PhantomData,
    };
    let str = Test::<&str> {   // WHY DOES THIS COMPILE WITH OUT lifetime but below does not?
        _phantom: std::marker::PhantomData,
    };
    type TestOwned = Test<String>;
    // type TestRefDoesNotCompile = Test<&str>; --> WHY DOES THIS NOT COMPILE with a lifetime?
    type TestRef<'a> = Test<&'a str>;

let gets type inference, because it's a statement inside a function. You can also write:

let v: Vec<_> = vec!["a"];

without specifying the type exactly, or not specify the type at all.

type is an "item" that can exist outside of functions, where full types are required, and type inference is not used. It doesn't get special treatment inside of functions.

In some cases you'll also find old Rust syntax that allowed omission of lifetimes (lifetime elision) from types in some places, e.g. Cow<str> is allowed, and Cow<'_, str> is a "new" syntax since 2018.

1 Like

Another reason you can elide lifetimes (or use the wildcard '_ lifetime) in function bodies is that inferred local lifetimes don't have names.

1 Like