@@ -27,8 +27,9 @@ use rustc_target::abi::{
27
27
use std:: hash:: Hash ;
28
28
29
29
use super :: {
30
- AllocId , CheckInAllocMsg , GlobalAlloc , ImmTy , Immediate , InterpCx , InterpResult , MPlaceTy ,
31
- Machine , MemPlaceMeta , OpTy , Pointer , Projectable , Scalar , ValueVisitor ,
30
+ format_interp_error, AllocId , CheckInAllocMsg , GlobalAlloc , ImmTy , Immediate , InterpCx ,
31
+ InterpResult , MPlaceTy , Machine , MemPlaceMeta , OpTy , Pointer , Projectable , Scalar ,
32
+ ValueVisitor ,
32
33
} ;
33
34
34
35
// for the validation errors
@@ -460,46 +461,49 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
460
461
// Special handling for pointers to statics (irrespective of their type).
461
462
assert ! ( !self . ecx. tcx. is_thread_local_static( did) ) ;
462
463
assert ! ( self . ecx. tcx. is_static( did) ) ;
464
+ let is_mut =
465
+ matches ! ( self . ecx. tcx. def_kind( did) , DefKind :: Static ( Mutability :: Mut ) )
466
+ || !self
467
+ . ecx
468
+ . tcx
469
+ . type_of ( did)
470
+ . no_bound_vars ( )
471
+ . expect ( "statics should not have generic parameters" )
472
+ . is_freeze ( * self . ecx . tcx , ty:: ParamEnv :: reveal_all ( ) ) ;
463
473
// Mutability check.
464
474
if ptr_expected_mutbl == Mutability :: Mut {
465
- if matches ! (
466
- self . ecx. tcx. def_kind( did) ,
467
- DefKind :: Static ( Mutability :: Not )
468
- ) && self
469
- . ecx
470
- . tcx
471
- . type_of ( did)
472
- . no_bound_vars ( )
473
- . expect ( "statics should not have generic parameters" )
474
- . is_freeze ( * self . ecx . tcx , ty:: ParamEnv :: reveal_all ( ) )
475
- {
475
+ if !is_mut {
476
476
throw_validation_failure ! ( self . path, MutableRefToImmutable ) ;
477
477
}
478
478
}
479
- // We skip recursively checking other statics. These statics must be sound by
480
- // themselves, and the only way to get broken statics here is by using
481
- // unsafe code.
482
- // The reasons we don't check other statics is twofold. For one, in all
483
- // sound cases, the static was already validated on its own, and second, we
484
- // trigger cycle errors if we try to compute the value of the other static
485
- // and that static refers back to us.
486
- // We might miss const-invalid data,
487
- // but things are still sound otherwise (in particular re: consts
488
- // referring to statics).
489
- return Ok ( ( ) ) ;
479
+ match self . ctfe_mode {
480
+ Some ( CtfeValidationMode :: Static { .. } ) => {
481
+ // We skip recursively checking other statics. These statics must be sound by
482
+ // themselves, and the only way to get broken statics here is by using
483
+ // unsafe code.
484
+ // The reasons we don't check other statics is twofold. For one, in all
485
+ // sound cases, the static was already validated on its own, and second, we
486
+ // trigger cycle errors if we try to compute the value of the other static
487
+ // and that static refers back to us.
488
+ // This could miss some UB, but that's fine.
489
+ return Ok ( ( ) ) ;
490
+ }
491
+ Some ( CtfeValidationMode :: Const { .. } ) => {
492
+ // For consts on the other hand we have to recursively check;
493
+ // pattern matching assumes a valid value. However we better make
494
+ // sure this is not mutable.
495
+ if is_mut {
496
+ throw_validation_failure ! ( self . path, ConstRefToMutable ) ;
497
+ }
498
+ }
499
+ None => { }
500
+ }
490
501
}
491
502
GlobalAlloc :: Memory ( alloc) => {
492
503
if alloc. inner ( ) . mutability == Mutability :: Mut
493
504
&& matches ! ( self . ctfe_mode, Some ( CtfeValidationMode :: Const { .. } ) )
494
505
{
495
- // This is impossible: this can only be some inner allocation of a
496
- // `static mut` (everything else either hits the `GlobalAlloc::Static`
497
- // case or is interned immutably). To get such a pointer we'd have to
498
- // load it from a static, but such loads lead to a CTFE error.
499
- span_bug ! (
500
- self . ecx. tcx. span,
501
- "encountered reference to mutable memory inside a `const`"
502
- ) ;
506
+ throw_validation_failure ! ( self . path, ConstRefToMutable ) ;
503
507
}
504
508
if ptr_expected_mutbl == Mutability :: Mut
505
509
&& alloc. inner ( ) . mutability == Mutability :: Not
@@ -978,7 +982,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
978
982
// Complain about any other kind of error -- those are bad because we'd like to
979
983
// report them in a way that shows *where* in the value the issue lies.
980
984
Err ( err) => {
981
- bug ! ( "Unexpected error during validation: {}" , self . format_error( err) ) ;
985
+ bug ! (
986
+ "Unexpected error during validation: {}" ,
987
+ format_interp_error( self . tcx. dcx( ) , err)
988
+ ) ;
982
989
}
983
990
}
984
991
}
0 commit comments