Repository navigation
Closed
Labels
A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)A-fmtArea: `core::fmt`Area: `core::fmt`A-temporary-lifetime-extensionArea: temporary lifetime extensionArea: temporary lifetime extensionC-bugCategory: This is a bug.Category: This is a bug.F-super_letit's super, let's go!it's super, let's go!I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.P-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Description
Note that unlike the other similar issues, this bug does not involve if let, and therefore will not be fixed by #145342.
I tried this code:
#[derive(Debug)]
struct Thing;
#[derive(Debug)]
struct Ref<'a>(&'a Thing);
impl Drop for Ref<'_> {
fn drop(&mut self) {}
}
fn new_thing() -> Thing {
Thing
}
fn new_ref(x: &Thing) -> Ref<'_> {
Ref(x)
}
pub fn foo() {
let _x = format_args!("{:?}, {:?}", 1, new_ref(&new_thing()));
}The code compiled in version 1.88.0. However, in version 1.89.0, I get the following compile error:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:19:53
|
19 | let _x = format_args!("{:?}, {:?}", 1, new_ref(&new_thing()));
| ---------^^^^^^^^^^^- - temporary value is freed at the end of this statement
| | |
| | creates a temporary value which is freed while still in use
| a temporary with access to the borrow is created here ...
20 | }
| - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `Ref`
|
= note: consider using a `let` binding to create a longer lived value
For more information about this error, try `rustc --explain E0716`.
I'm not sure how important this is though, since as far as I can tell, there is no way to actually be able to use the value of _x in version 1.88.0.
Presumably regressed in #140748
@rustbot labels +regression-from-stable-to-stable +F-super_let +A-destructors
Meta
Regression from stable rust version 1.88.0 to 1.89.0.
Metadata
Metadata
Assignees
Labels
A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)A-fmtArea: `core::fmt`Area: `core::fmt`A-temporary-lifetime-extensionArea: temporary lifetime extensionArea: temporary lifetime extensionC-bugCategory: This is a bug.Category: This is a bug.F-super_letit's super, let's go!it's super, let's go!I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.P-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Activity
rustbot commentedon Aug 15, 2025
theemathas commentedon Aug 15, 2025
@dianne's explanation of the issue, copied from #145342 (comment):
dianne commentedon Aug 15, 2025
Additional diagnosis: this is maybe to be expected from the current expansion of
format_args!. The innernew_thing()temp doesn't get lifetime-extended, whereas the outernew_ref(&that_temp)does. It's like normalletin that way, when in an extending expression in a parentletinitializer (as in all these examples); pulling thesuper lets out of the block gives uswhich results in the same error.
With just one format argument, we run into a similar issue:
The format arguments can be assigned to
_x, but_xcan't be used because the temporaries aren't lifetime-extended.So my feeling is this may be a limitation of
format_args!'s expansion and oflet's lifetime extension rules, rather than a bug in the implementation ofsuper let. This didn't come up in the issue with assigning format arguments inif let, because temporaries fromif let's scrutinee live into the success block.dianne commentedon Aug 16, 2025
Another case of
format_args!being inconsistent with lifetime extension (same underlying cause) (playground):apiraino commentedon Aug 18, 2025
Assigning priority (discussion on Zulip).
@rustbot label -I-prioritize +P-medium
theemathas commentedon Aug 26, 2025
To make it more fun, the effect of an "optimization" is visible to users:
m-ou-se commentedon Aug 26, 2025
Yup, this is expected. It is technically a breaking change that it went from 'using it is an error' to 'defining it is an error', but it's extremely unlikely to result in any real life regressions.
What is not expected is that it behaves differently with one or with two+ arguments. I'll fix that.
m-ou-se commentedon Aug 26, 2025
Opened #145880 for that.