Auto merge of #119614 - RalfJung:const-refs-to-static, r=oli-obk · rust-lang/rust@6cc4843 (original) (raw)
`@@ -51,13 +51,10 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
`
51
51
`/// The virtual call stack.
`
52
52
`pub(super) stack: Vec<Frame<'mir, 'tcx>>,
`
53
53
``
54
``
`-
/// We need to make sure consts never point to anything mutable, even recursively. That is
`
55
``
`-
/// relied on for pattern matching on consts with references.
`
56
``
`-
/// To achieve this, two pieces have to work together:
`
57
``
`-
/// * Interning makes everything outside of statics immutable.
`
58
``
`-
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
`
59
``
`-
/// This boolean here controls the second part.
`
60
``
`-
pub(super) can_access_statics: CanAccessStatics,
`
``
54
`+
/// Pattern matching on consts with references would be unsound if those references
`
``
55
`+
/// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees,
`
``
56
`+
/// we ensure that only immutable global memory can be accessed.
`
``
57
`+
pub(super) can_access_mut_global: CanAccessMutGlobal,
`
61
58
``
62
59
`/// Whether to check alignment during evaluation.
`
63
60
`pub(super) check_alignment: CheckAlignment,
`
`@@ -73,26 +70,26 @@ pub enum CheckAlignment {
`
73
70
`}
`
74
71
``
75
72
`#[derive(Copy, Clone, PartialEq)]
`
76
``
`-
pub(crate) enum CanAccessStatics {
`
``
73
`+
pub(crate) enum CanAccessMutGlobal {
`
77
74
`No,
`
78
75
`Yes,
`
79
76
`}
`
80
77
``
81
``
`-
impl From for CanAccessStatics {
`
``
78
`+
impl From for CanAccessMutGlobal {
`
82
79
`fn from(value: bool) -> Self {
`
83
80
`if value { Self::Yes } else { Self::No }
`
84
81
`}
`
85
82
`}
`
86
83
``
87
84
`impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
`
88
85
`pub(crate) fn new(
`
89
``
`-
can_access_statics: CanAccessStatics,
`
``
86
`+
can_access_mut_global: CanAccessMutGlobal,
`
90
87
`check_alignment: CheckAlignment,
`
91
88
`) -> Self {
`
92
89
`CompileTimeInterpreter {
`
93
90
`num_evaluated_steps: 0,
`
94
91
`stack: Vec::new(),
`
95
``
`-
can_access_statics,
`
``
92
`+
can_access_mut_global,
`
96
93
` check_alignment,
`
97
94
`}
`
98
95
`}
`
`@@ -680,7 +677,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
`
680
677
`machine: &Self,
`
681
678
`alloc_id: AllocId,
`
682
679
`alloc: ConstAllocation<'tcx>,
`
683
``
`-
static_def_id: Option,
`
``
680
`+
_static_def_id: Option,
`
684
681
`is_write: bool,
`
685
682
`) -> InterpResult<'tcx> {
`
686
683
`let alloc = alloc.inner();
`
`@@ -692,22 +689,15 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
`
692
689
`}
`
693
690
`} else {
`
694
691
`// Read access. These are usually allowed, with some exceptions.
`
695
``
`-
if machine.can_access_statics == CanAccessStatics::Yes {
`
``
692
`+
if machine.can_access_mut_global == CanAccessMutGlobal::Yes {
`
696
693
`` // Machine configuration allows us read from anything (e.g., static initializer).
``
697
694
`Ok(())
`
698
``
`-
} else if static_def_id.is_some() {
`
699
``
`-
// Machine configuration does not allow us to read statics
`
700
``
`` -
// (e.g., const initializer).
``
701
``
`-
// See const_eval::machine::MemoryExtra::can_access_statics for why
`
702
``
`-
// this check is so important: if we could read statics, we could read pointers
`
703
``
`-
// to mutable allocations inside statics. These allocations are not themselves
`
704
``
`` -
// statics, so pointers to them can get around the check in validity.rs.
``
705
``
`-
Err(ConstEvalErrKind::ConstAccessesStatic.into())
`
``
695
`+
} else if alloc.mutability == Mutability::Mut {
`
``
696
`` +
// Machine configuration does not allow us to read statics (e.g., const
``
``
697
`+
// initializer).
`
``
698
`+
Err(ConstEvalErrKind::ConstAccessesMutGlobal.into())
`
706
699
`} else {
`
707
700
`// Immutable global, this read is fine.
`
708
``
`-
// But make sure we never accept a read from something mutable, that would be
`
709
``
`-
// unsound. The reason is that as the content of this allocation may be different
`
710
``
`-
// now and at run-time, so if we permit reading now we might return the wrong value.
`
711
701
`assert_eq!(alloc.mutability, Mutability::Not);
`
712
702
`Ok(())
`
713
703
`}
`