diff options
| author | Ralf Jung <post@ralfj.de> | 2025-06-26 09:49:13 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-06-26 10:20:48 +0200 |
| commit | 3790eff4d40288de2e467dab02608815102ada7f (patch) | |
| tree | 76cc6567628e6d6a8f63320f295d3ba55f9a59e6 /compiler/rustc_const_eval/src/interpret | |
| parent | bc4376fa73b636eb6f2c7d48b1f731d70f022c4b (diff) | |
| download | rust-3790eff4d40288de2e467dab02608815102ada7f.tar.gz rust-3790eff4d40288de2e467dab02608815102ada7f.zip | |
const validation: properly ignore zero-sized UnsafeCell
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/validity.rs | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 7d76d925ef2..a42a92abd43 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1086,8 +1086,13 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, ) -> InterpResult<'tcx> { // Special check for CTFE validation, preventing `UnsafeCell` inside unions in immutable memory. if self.ctfe_mode.is_some_and(|c| !c.allow_immutable_unsafe_cell()) { - if !val.layout.is_zst() && !val.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.typing_env) - { + // Unsized unions are currently not a thing, but let's keep this code consistent with + // the check in `visit_value`. + let zst = self + .ecx + .size_and_align_of(&val.meta(), &val.layout)? + .is_some_and(|(s, _a)| s.bytes() == 0); + if !zst && !val.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.typing_env) { if !self.in_mutable_memory(val) { throw_validation_failure!(self.path, UnsafeCellInImmutable); } @@ -1131,7 +1136,13 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, // Special check preventing `UnsafeCell` in the inner part of constants if self.ctfe_mode.is_some_and(|c| !c.allow_immutable_unsafe_cell()) { - if !val.layout.is_zst() + // Exclude ZST values. We need to compute the dynamic size/align to properly + // handle slices and trait objects. + let zst = self + .ecx + .size_and_align_of(&val.meta(), &val.layout)? + .is_some_and(|(s, _a)| s.bytes() == 0); + if !zst && let Some(def) = val.layout.ty.ty_adt_def() && def.is_unsafe_cell() { |
