Repository navigation
Closed as not planned
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.T-langRelevant to the language teamRelevant to the language team
Description
I don't know what the correct behavior is. However, this combination of behaviors with these variations in the code seem rather inconsistent.
The below code compiles, seemingly due to const promotion or temporary lifetime extension:
#![allow(unreachable_code, unused)]
const A: () = {
let _x: &i32 = 'a: {
break 'a &one();
panic!()
};
};
const fn one() -> i32 {
1
}Adding an irrelevant if true {} makes it not compile, even without the &'static annotation:
#![allow(unreachable_code, unused)]
const A: () = {
let _x = 'a: {
if true {}
break 'a &one();
panic!()
};
};
const fn one() -> i32 {
1
}error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:6:19
|
4 | let _x = 'a: {
| -- borrow later stored here
5 | if true { }
6 | break 'a &one();
| ^^^^^- temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
|
= note: consider using a `let` binding to create a longer lived value
For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error
Adding a break inside the condition makes the error blame the panic:
#![allow(unreachable_code, unused)]
const A: () = {
let _x = 'a: {
if true {
break 'a &1;
}
break 'a &one();
panic!()
};
};
const fn one() -> i32 {
1
}error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:8:19
|
8 | break 'a &one();
| ^^^^^- temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
9 | panic!()
| -------- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error
Putting the initial code inside a fn instead of a const makes it not compile, even without the &'static annotation:
#![allow(unreachable_code, unused)]
fn foo() {
let _x: &i32 = 'a: {
break 'a &one();
panic!()
};
}
const fn one() -> i32 {
1
}error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:5:19
|
4 | let _x: &i32 = 'a: {
| -- borrow later stored here
5 | break 'a &one();
| ^^^^^- temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
|
= note: consider using a `let` binding to create a longer lived value
For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error
Putting the initial code inside if false makes it not compile, even without the &'static annotation:
#![allow(unreachable_code, unused)]
const A: () = if false {
let _x: &i32 = 'a: {
break 'a &one();
panic!()
};
};
const fn one() -> i32 {
1
}playground)
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:5:19
|
4 | let _x: &i32 = 'a: {
| -- borrow later stored here
5 | break 'a &one();
| ^^^^^- temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
|
= note: consider using a `let` binding to create a longer lived value
For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error
@rustbot labels +A-const-eval
CC @traviscross
Meta
All code snippets tested on the playground with version 1.89.0.
Metadata
Metadata
Assignees
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.T-langRelevant to the language teamRelevant to the language team
Activity
traviscross commentedon Aug 17, 2025
This is due to #121557. Correspondingly, your second, third, and fifth example indeed regressed in Rust 1.79. The fourth one fails because we don't promote calls to arbitrary constant functions except inside initializers as noted in #144939 (comment).
theemathas commentedon Aug 17, 2025
That's wild.
Why does the third example have such a weird error message though?
theemathas commentedon Aug 17, 2025
Filed a separate diagnostic issue at #145530. Closing this issue, since it's working as intended, albeit strangely.
RalfJung commentedon Aug 18, 2025
Yeah, I'd love to clean this up, but it requires a non-trivial edition transition and I don't think I'll have the time and energy to implement that. See #124328. If someone is willing to figure out how to invoke the borrow checker twice on two different variants of a MIR body to provide a migration lint, I'm happy to explain the general strategy of how this could work. :D