temporaries

Crates.iotemporaries
lib.rstemporaries
version0.10.5
created_at2024-11-14 10:26:40.188506+00
updated_at2025-08-20 14:21:18.094814+00
descriptionMake temporary values useable in a fairly normal style through macros. This nicely wraps the hacks that work around temporaries’ earlier limitations.
homepage
repositoryhttps://sourceforge.net/p/temporaries/
max_upload_size
id1447644
size13,637
(daniel-pfeiffer)

documentation

README

Make temporary values useable in a fairly normal style through macros. This nicely wraps the hacks that work around temporaries’ earlier limitations.

[!NOTE] Rust 1.89 has mostly solved these problems. That makes this crate far less useful going forward. Furthermore Edition 2024 had already closed the wormhole magically allowing if_workaround. This still works on newer compilers, but only if the calling code remains on an older Edition.

What Problem does this Solve?

Normally let str = &String::from("str"); shouldn’t compile. The inner String object should be dropped at the end of the statement, leaving a dangling reference. However, in simple cases like this, Rust gives you a pass, by extending the lifetime. Alas this has not yet been generalised. You can often work around that, by storing the temporary value in a separate variable.

The same situation arises, when the temporary value is hidden. Only, then you have no influence to work around it. This is famously the case with format_args!, the efficient alternative to heap-allocated format!. This strongly limits its usefulness – or did, without these macros!

Returning a temporary value from a simple block also benefits from lifetime extension. Again this is not yet the case for more complex blocks, like if or match. Since Rust doesn’t have a ? : operator, that prevents dynamic choice involving temporaries. So, even in edition 2024 these fail to compile. I’m showing both explicit and hidden temporaries in the 1st case:

// `x` & `y` would live longer than the `String` and `format_args`’ hidden temporary.
let x = &vec![&String::from("x")];
let y = format_args!("1 + 2 = {}", 1 + 2);

// Consuming the value directly in `print!()` would be ok, were it not for the man in the middle, `if`.
print!("{}", if 1 < 1 {
    format_args!("1 + 2 = {}", 1 + 2)
} else {
    format_args!("1 + 3 = {}", 1 + 3)
});

The Solution

The let problem is solved by turning it into a match, making the value live as long as the following code. Multiple choice is achieved by breaking from a tuple. Both of these are not nice to look at. Therefore temporaries wraps them up in convenient macros.

This only applies to local processing. Returning a temporary value from a closure or function is alas not something a macro can achieve. That requires a language change, such as super let, which is under discussion.

Actually if_workaround should parse an if statement, but (with sane effort) that is not possible. While if statements put a block after an expression, macro rules oddly do not permit to express this normal Rust syntax.

This was inspired by this & this. There is a similar crate, which, unlike this one, needs a proc-macro, hoist_temporaries.

Commit count: 0

cargo fmt