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

`}

`