-
Notifications
You must be signed in to change notification settings - Fork 13.4k
ICE from using super let
and &raw
in const
#142229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Uh, yes we should entirely forbid It is bad enough that we do "lifetime/scope extension" in consts at all, which has caused enormous amounts of headache for very little benefit. But that is at least very syntactically restricted, and in particular does not allow raw pointers. Please let us not extend this to arbitrary user-defined expressions. Cc @rust-lang/wg-const-eval @m-ou-se |
If lifetime/scope extension works in consts, I also think |
Be careful when you use "just" for something that's not trivial at all. ;) Lifetime extension as of today is quite limited, and for consts, that is crucial. We do not want more lifetime extension in consts. I barely managed to carve out a sound way of having |
To demonstrate the problem, consider code like this: pub const C: *mut i32 = {
super let mut x = 1;
&raw mut x
}; Now imagine The first thing that happens is that we violate the definition of consts, that every use of *C = 4;
assert_eq!(*C, 1); // this assert will fail It gets worse, however. If The ICE is triggered by a safety net that I added specifically because ensuring sane behavior of consts relies on a bunch of subtle invariants spread across the entire language. Purely on the conceptual level, there's also the concern that the only sensible behavior of the constant above is to introduce a global mutable allocation, but global mutable state is an enormous foot-gun and I feel very strongly that we should require very explicit opt-in for creating such state (e.g. via Note that I am talking only about the top-level scope of a |
#![feature(super_let)]
pub const C: *mut i32 = {
super let mut x = 1;
&raw mut x
}; Currently, this code fails to compile with the following error
|
#![feature(super_let)]
pub const C: &i32 = {
super let x = 1;
&x
}; This code currently compiles fine. |
Currently, in nightly, the following code compiles without unstable features, and it macro-expands to code that uses use std::pin::{pin, Pin};
pub const C: () = ignore(pin!(1));
const fn ignore(_: Pin<&mut i32>) {} |
I would support us disallowing |
Here's a variant which avoids the error (and then ICEs): #![feature(super_let)]
pub const C: *mut i32 = {
super let mut x = 1;
&raw const x as *mut i32
}; At least under Tree Borrows, mutating
So a The |
I think ICEs can only occur with raw pointers, but problematic patterns can occur even with just references. #128543 has some context for the "safety net" I mentioned before. FWIW, we do document that
This could be used to justify why writing to the |
This ICE also occurs in const blocks, such as in the following code: #![feature(super_let)]
fn main() {
let _ = const {
super let x = 1;
&raw const x
};
} |
Yeah const blocks are exactly like items in almost every regard, so that's the same issue. |
To refresh my memory of the problem space here, I have written up a summary of the problem with lifetime extension. One conclusion is that the ICE can only occur with What we should do more broadly, I am not sure. We could just remove the check that causes the ICE, but I am not a fan of the semantic footgun this unveils. |
I have been thinking about this, and, if And once that would be in place, we might not need forbid |
Yeah, if that's possible that would avoid all ICEs, and also some of the semantic headache -- at least all problematic cases would involve mutating through a pointer derived from an |
Code
Meta
Reproducible on the playground with
1.89.0-nightly (2025-06-08 6ccd4476036edfce364e)
Error output
Backtrace
The text was updated successfully, but these errors were encountered: