Namely, we can have promoteds with interior mutable types but in an immutable allocation.
#67000 makes this explicit by introducing the ignore_interior_mut_in_const_validation field on the const interner.
We should instead rewrite such promoteds to just contain the parts of the promoted that is accessed. So
let x: &'static i32 = &[(Cell::new(42), 1), Cell::new(42), 2)][runtime_index].1;
currently produces
const PROMOTED: &[(Cell<i32>, i32); 2] = &[(Cell::new(42), 1), Cell::new(42), 2)];
let x: &'static i32 = &PROMOTED[runtime_index].1;
And we should be producing
const PROMOTED: &[i32; 2] = &[1, 2];
let x: &'static i32 = &PROMOTED[runtime_index];
This is definitely a nontrivial transformation, especially since it needs to be done on the generic promoted and not the computed final value (generic e.g. if we had T::CELL_VALUE instead of Cell::new(42)).
The reason it needs to be done on the MIR is that we also need to change the projection for obtaining the value of x, which we have no control over if we did it on the final constant.
Namely, we can have promoteds with interior mutable types but in an immutable allocation.
#67000 makes this explicit by introducing the
ignore_interior_mut_in_const_validationfield on the const interner.We should instead rewrite such promoteds to just contain the parts of the promoted that is accessed. So
currently produces
And we should be producing
This is definitely a nontrivial transformation, especially since it needs to be done on the generic promoted and not the computed final value (generic e.g. if we had
T::CELL_VALUEinstead ofCell::new(42)).The reason it needs to be done on the MIR is that we also need to change the projection for obtaining the value of
x, which we have no control over if we did it on the final constant.