-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Should unions use type based const qualification? #90268
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
Yea, unions should not be "more powerful" than a plain transmute imo. cc @rust-lang/wg-const-eval |
I assume with transmute one can also produce a similar example as the OP? So in which sense are unions more powerful than transmute, @oli-obk? Why does this example behave any different than the following? use std::cell::Cell;
pub const CELL: Option<Cell<u32>> = Some(Cell::new(0));
fn main() {
let _ = &CELL;
} |
The union local initially starts without interior mutability qualif. This persist after the first assignment, since u32 does not have interior mutability The move from the cell variant is qualified based on the qualification of the local, so the overall constant is consider not to have interior mutability. The use of the constant in the main function is promoted and fails dynamic checks. |
I totally forgot promotion of Yeah, the analysis clearly is wrong for reading from union fields. But even for values like |
The example can be also modified by moving union access to the runtime code, in #![feature(untagged_unions)]
use std::cell::Cell;
pub union U { i: u32, c: Cell<u32> }
pub const CELL: U = {
U { i: 0 }
};
fn main() {
let cell: &'static U = &CELL;
unsafe { (cell.c).set(1) };
} $ rustc a.rs
$ ./a
Segmentation fault In the context of static analysis, I think it would make sense to use strictly |
But also, there's supposed to be a 2nd line of defense in our interning code that is somehow failing. |
Turns out interning relies in validity checking for this:
The example in the OP was caught by validity, so that is good. But the 2nd example was not caught, because we never actually hit an UnsafeCell -- we stop at the union boundary. So maybe the union part of the visitor should also have the kind of check UnsafeCell does?
|
@RalfJung do we have an established approach to testing that this second line of defense works? Carefully crafted constant with undefined behaviour might do its job in this case (not sure yet), but maybe we have better alternatives? |
We have -Zunleash-the-miri-inside-of-you but that only helps for |
For example, after laundering interior mutability through a union, a resulting constant undergoes promotion:
@rustbot label +A-const-eval +F-untagged_unions
The text was updated successfully, but these errors were encountered: