Shortcut for Option str defined using format?

I'd like to avoid temporary value getting freed at the end of the format statement:

let live: Option<&str> = Some(&*format!("{} is alive!", "it"));

without having to type as much (what works) as Option types are so common in my code I see this happening a lot, especially in unit tests/fixtures:

let keep_alive: &str = &format!("{} is alive!", "it");
let live = Some(keep_alive);

The simple answer is probably "no", but could you also offer wisdom as to why Rust couldn't safely just assume the lifetimes of &*format!(..) and live in the first statement must be equal, and hence not worry so much? Or, said another way, why was it decided for Option to limit the scope of its arguments?

It's more the case of certain expressions that do support temporary lifetime extension behaving exceptional. I wouldn't see the Some(… ) constructor as limiting anything since temporaries being dropped at the end of the statement is the norm. Instead it is more a case of certain expressions extending the lifetime (as the name suggests). In any case, reading through the reference I linked, it seems as if using Some { 0: … } notation might actually solve your issue.

2 Likes

To give some reasoning (my personal guesswork/intuition): Note that Some(…) is essentially an ordinary function call. (You can also use e. g. Some as an impl Fn, etc...) And ordinary function calls might be able to accept short-lived things and return long-lived things.

As far as I understand, temporary lifetime extension is only supposed to apply to certain instances of Rust code that definitely won't compile at all without the lifetime extension. (Otherwise it would be confusing if a temporary isn't dropped when you expected it to be dropped.)

And also the rules are kept simple by being syntactic rules only, e. g. you wouldn't go as far as to consider analysis results of the borrow checker to determine whether lifetime extension is necessary, as that's way too complex and unpredictable for the programmer.

This should alltogether explain why Some(…) doesn't support temporary lifetime extension.

2 Likes

I feel like you are making this more complicated than it needs to be:

Then why don't you hold on to it by-value?

let live: Option<String> = Some(format!("{} is alive!", "it"));

Then if you need to, you can get an Option<&str> out of it by calling live.as_deref(). Consequently, there is no need for tricks, special cases, or anything beyond that single method call.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.