Description
Discussion: #67134 (comment)
The situation is as follows:
- Sometimes code relies on a failing constant for safety (see Usage of errorneous constant can be omitted on nightly and beta #67083)
- Those failing constants may have a ZST type (e.g.
()
) - A MIR optimization may see the constant and optimize it out (this happened: [mir-opt] Handle return place in ConstProp and improve SimplifyLocals pass #66216)
- The constant not showing up in MIR can cause it to never get evaluated, thus never reporting its error
- The runtime code relying on safety by having a hard error during const eval is now being executed even though it's unsound
The proposed solution is to gather all unevaluated constants in a MIR right after mir building and put them in a Vec<(DefId, SubstsRef<'tcx>, Promoted)>
(or maybe a HashSet
?). This should be placed on the mir::Body
and inlining should also carry it down to the function that its being inlined into (and adjust substitutions on the SubstsRef
). In the end, instead of having the collector go through the MIR to find constants to evaluate, we go through the vector and evaluate all of them.
This will require more memory and some additional evaluation time, but it would be significantly less fragile than the current setup which relies on optimizations not removing even guaranteed dead code containing constants.