@@ -117,11 +117,12 @@ pub enum PathElem {
117
117
pub enum CtfeValidationMode {
118
118
/// Regular validation, nothing special happening.
119
119
Regular ,
120
- /// Validation of a `const`. `inner` says if this is an inner, indirect allocation (as opposed
121
- /// to the top-level const allocation).
122
- /// Being an inner allocation makes a difference because the top-level allocation of a `const`
123
- /// is copied for each use, but the inner allocations are implicitly shared.
124
- Const { inner : bool } ,
120
+ /// Validation of a `const`.
121
+ /// `inner` says if this is an inner, indirect allocation (as opposed to the top-level const
122
+ /// allocation). Being an inner allocation makes a difference because the top-level allocation
123
+ /// of a `const` is copied for each use, but the inner allocations are implicitly shared.
124
+ /// `allow_static_ptrs` says if pointers to statics are permitted (which is the case for promoteds in statics).
125
+ Const { inner : bool , allow_static_ptrs : bool } ,
125
126
}
126
127
127
128
/// State for tracking recursive validation of references
@@ -437,7 +438,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
437
438
if let Some ( GlobalAlloc :: Static ( did) ) = alloc_kind {
438
439
assert ! ( !self . ecx. tcx. is_thread_local_static( did) ) ;
439
440
assert ! ( self . ecx. tcx. is_static( did) ) ;
440
- if matches ! ( self . ctfe_mode, Some ( CtfeValidationMode :: Const { .. } ) ) {
441
+ if matches ! (
442
+ self . ctfe_mode,
443
+ Some ( CtfeValidationMode :: Const { allow_static_ptrs: false , .. } )
444
+ ) {
441
445
// See const_eval::machine::MemoryExtra::can_access_statics for why
442
446
// this check is so important.
443
447
// This check is reachable when the const just referenced the static,
@@ -742,9 +746,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
742
746
// Sanity check: `builtin_deref` does not know any pointers that are not primitive.
743
747
assert ! ( op. layout. ty. builtin_deref( true ) . is_none( ) ) ;
744
748
745
- // Special check preventing `UnsafeCell` in constants
749
+ // Special check preventing `UnsafeCell` in the inner part of constants
746
750
if let Some ( def) = op. layout . ty . ty_adt_def ( ) {
747
- if matches ! ( self . ctfe_mode, Some ( CtfeValidationMode :: Const { inner: true } ) )
751
+ if matches ! ( self . ctfe_mode, Some ( CtfeValidationMode :: Const { inner: true , .. } ) )
748
752
&& Some ( def. did ) == self . ecx . tcx . lang_items ( ) . unsafe_cell_type ( )
749
753
{
750
754
throw_validation_failure ! ( self . path, { "`UnsafeCell` in a `const`" } ) ;
0 commit comments