@@ -10,7 +10,7 @@ use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem};
10
10
use rustc_middle:: mir:: AssertMessage ;
11
11
use rustc_middle:: mir:: interpret:: ReportedErrorInfo ;
12
12
use rustc_middle:: query:: TyCtxtAt ;
13
- use rustc_middle:: ty:: layout:: { HasTypingEnv , TyAndLayout } ;
13
+ use rustc_middle:: ty:: layout:: { HasTypingEnv , TyAndLayout , ValidityRequirement } ;
14
14
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
15
15
use rustc_middle:: { bug, mir} ;
16
16
use rustc_span:: { Span , Symbol , sym} ;
@@ -23,8 +23,8 @@ use crate::fluent_generated as fluent;
23
23
use crate :: interpret:: {
24
24
self , AllocId , AllocInit , AllocRange , ConstAllocation , CtfeProvenance , FnArg , Frame ,
25
25
GlobalAlloc , ImmTy , InterpCx , InterpResult , OpTy , PlaceTy , Pointer , RangeSet , Scalar ,
26
- compile_time_machine, interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom ,
27
- throw_unsup, throw_unsup_format,
26
+ compile_time_machine, err_inval , interp_ok, throw_exhaust, throw_inval, throw_ub,
27
+ throw_ub_custom , throw_unsup, throw_unsup_format,
28
28
} ;
29
29
30
30
/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -462,6 +462,44 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
462
462
// (We know the value here in the machine of course, but this is the runtime of that code,
463
463
// not the optimization stage.)
464
464
sym:: is_val_statically_known => ecx. write_scalar ( Scalar :: from_bool ( false ) , dest) ?,
465
+
466
+ // We handle these here since Miri does not want to have them.
467
+ sym:: assert_inhabited
468
+ | sym:: assert_zero_valid
469
+ | sym:: assert_mem_uninitialized_valid => {
470
+ let ty = instance. args . type_at ( 0 ) ;
471
+ let requirement = ValidityRequirement :: from_intrinsic ( intrinsic_name) . unwrap ( ) ;
472
+
473
+ let should_panic = !ecx
474
+ . tcx
475
+ . check_validity_requirement ( ( requirement, ecx. typing_env ( ) . as_query_input ( ty) ) )
476
+ . map_err ( |_| err_inval ! ( TooGeneric ) ) ?;
477
+
478
+ if should_panic {
479
+ let layout = ecx. layout_of ( ty) ?;
480
+
481
+ let msg = match requirement {
482
+ // For *all* intrinsics we first check `is_uninhabited` to give a more specific
483
+ // error message.
484
+ _ if layout. is_uninhabited ( ) => format ! (
485
+ "aborted execution: attempted to instantiate uninhabited type `{ty}`"
486
+ ) ,
487
+ ValidityRequirement :: Inhabited => bug ! ( "handled earlier" ) ,
488
+ ValidityRequirement :: Zero => format ! (
489
+ "aborted execution: attempted to zero-initialize type `{ty}`, which is invalid"
490
+ ) ,
491
+ ValidityRequirement :: UninitMitigated0x01Fill => format ! (
492
+ "aborted execution: attempted to leave type `{ty}` uninitialized, which is invalid"
493
+ ) ,
494
+ ValidityRequirement :: Uninit => bug ! ( "assert_uninit_valid doesn't exist" ) ,
495
+ } ;
496
+
497
+ Self :: panic_nounwind ( ecx, & msg) ?;
498
+ // Skip the `return_to_block` at the end (we panicked, we do not return).
499
+ return interp_ok ( None ) ;
500
+ }
501
+ }
502
+
465
503
_ => {
466
504
// We haven't handled the intrinsic, let's see if we can use a fallback body.
467
505
if ecx. tcx . intrinsic ( instance. def_id ( ) ) . unwrap ( ) . must_be_overridden {
0 commit comments