@@ -25,14 +25,19 @@ use super::{
25
25
} ;
26
26
27
27
macro_rules! throw_validation_failure {
28
- ( $what: expr, $where: expr $( , $expected: expr ) ?) => { {
29
- let mut msg = format!( "encountered {}" , $what) ;
28
+ ( $where: expr, { $( $what_fmt: expr ) ,+ } $( expected { $( $expected_fmt: expr ) ,+ } ) ?) => { {
29
+ let mut msg = String :: new( ) ;
30
+ msg. push_str( "encountered " ) ;
31
+ write!( & mut msg, $( $what_fmt) ,+) . unwrap( ) ;
30
32
let where_ = & $where;
31
33
if !where_. is_empty( ) {
32
34
msg. push_str( " at " ) ;
33
35
write_path( & mut msg, where_) ;
34
36
}
35
- $( write!( & mut msg, ", but expected {}" , $expected) . unwrap( ) ; ) ?
37
+ $(
38
+ msg. push_str( ", but expected " ) ;
39
+ write!( & mut msg, $( $expected_fmt) ,+) . unwrap( ) ;
40
+ ) ?
36
41
throw_ub!( ValidationFailure ( msg) )
37
42
} } ;
38
43
}
@@ -76,9 +81,8 @@ macro_rules! try_validation {
76
81
// allocation here as this can only slow down builds that fail anyway.
77
82
$( Err ( InterpErrorInfo { kind: $p, .. } ) ) |+ =>
78
83
throw_validation_failure!(
79
- format_args!( $( $what_fmt ) ,+) ,
80
- $where
81
- $( , format_args!( $( $expected_fmt ) ,+) ) ?
84
+ $where,
85
+ { $( $what_fmt ) ,+ } $( expected { $( $expected_fmt ) ,+ } ) ?
82
86
) ,
83
87
#[ allow( unreachable_patterns) ]
84
88
Err ( e) => Err :: <!, _>( e) ?,
@@ -366,9 +370,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
366
370
let size_and_align = match self . ecx . size_and_align_of ( place. meta , place. layout ) {
367
371
Ok ( res) => res,
368
372
Err ( err) => match err. kind {
369
- err_ub ! ( InvalidMeta ( msg) ) => throw_validation_failure ! (
370
- format_args!( "invalid {} metadata: {}" , kind, msg) ,
371
- self . path
373
+ err_ub ! ( InvalidMeta ( msg) ) => throw_validation_failure ! ( self . path,
374
+ { "invalid {} metadata: {}" , kind, msg }
372
375
) ,
373
376
_ => bug ! ( "unexpected error during ptr size_and_align_of: {}" , err) ,
374
377
} ,
@@ -393,37 +396,32 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
393
396
) ;
394
397
match err. kind {
395
398
err_ub ! ( DanglingIntPointer ( 0 , _) ) => {
396
- throw_validation_failure ! ( format_args!( "a NULL {}" , kind) , self . path)
399
+ throw_validation_failure ! ( self . path,
400
+ { "a NULL {}" , kind }
401
+ )
397
402
}
398
- err_ub ! ( DanglingIntPointer ( i, _) ) => throw_validation_failure ! (
399
- format_args!( "a {} to unallocated address {}" , kind, i) ,
400
- self . path
403
+ err_ub ! ( DanglingIntPointer ( i, _) ) => throw_validation_failure ! ( self . path,
404
+ { "a {} to unallocated address {}" , kind, i }
401
405
) ,
402
406
err_ub ! ( AlignmentCheckFailed { required, has } ) => throw_validation_failure ! (
403
- format_args!(
407
+ self . path,
408
+ {
404
409
"an unaligned {} (required {} byte alignment but found {})" ,
405
410
kind,
406
411
required. bytes( ) ,
407
412
has. bytes( )
408
- ) ,
409
- self . path
413
+ }
410
414
) ,
411
- err_unsup ! ( ReadBytesAsPointer ) => throw_validation_failure ! (
412
- format_args!( "a dangling {} (created from integer)" , kind) ,
413
- self . path
415
+ err_unsup ! ( ReadBytesAsPointer ) => throw_validation_failure ! ( self . path,
416
+ { "a dangling {} (created from integer)" , kind }
414
417
) ,
415
- err_ub ! ( PointerOutOfBounds { .. } ) => throw_validation_failure ! (
416
- format_args!(
417
- "a dangling {} (going beyond the bounds of its allocation)" ,
418
- kind
419
- ) ,
420
- self . path
418
+ err_ub ! ( PointerOutOfBounds { .. } ) => throw_validation_failure ! ( self . path,
419
+ { "a dangling {} (going beyond the bounds of its allocation)" , kind }
421
420
) ,
422
421
// This cannot happen during const-eval (because interning already detects
423
422
// dangling pointers), but it can happen in Miri.
424
- err_ub ! ( PointerUseAfterFree ( _) ) => throw_validation_failure ! (
425
- format_args!( "a dangling {} (use-after-free)" , kind) ,
426
- self . path
423
+ err_ub ! ( PointerUseAfterFree ( _) ) => throw_validation_failure ! ( self . path,
424
+ { "a dangling {} (use-after-free)" , kind }
427
425
) ,
428
426
_ => bug ! ( "Unexpected error during ptr inbounds test: {}" , err) ,
429
427
}
@@ -443,9 +441,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
443
441
// We also need to do it here instead of going on to avoid running
444
442
// into the `before_access_global` check during validation.
445
443
if !self . may_ref_to_static && self . ecx . tcx . is_static ( did) {
446
- throw_validation_failure ! (
447
- format_args!( "a {} pointing to a static variable" , kind) ,
448
- self . path
444
+ throw_validation_failure ! ( self . path,
445
+ { "a {} pointing to a static variable" , kind }
449
446
) ;
450
447
}
451
448
// `extern static` cannot be validated as they have no body.
@@ -516,10 +513,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
516
513
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
517
514
let is_bits = value. not_undef ( ) . map_or ( false , |v| v. is_bits ( ) ) ;
518
515
if !is_bits {
519
- throw_validation_failure ! (
520
- value,
521
- self . path,
522
- "initialized plain (non-pointer) bytes"
516
+ throw_validation_failure ! ( self . path,
517
+ { "{}" , value } expected { "initialized plain (non-pointer) bytes" }
523
518
)
524
519
}
525
520
} else {
@@ -563,7 +558,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
563
558
// FIXME: Check if the signature matches
564
559
Ok ( true )
565
560
}
566
- ty:: Never => throw_validation_failure ! ( "a value of the never type `!`" , self . path ) ,
561
+ ty:: Never => throw_validation_failure ! ( self . path , { "a value of the never type `!`" } ) ,
567
562
ty:: Foreign ( ..) | ty:: FnDef ( ..) => {
568
563
// Nothing to check.
569
564
Ok ( true )
@@ -622,26 +617,24 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
622
617
if lo == 1 && hi == max_hi {
623
618
// Only NULL is the niche. So make sure the ptr is NOT NULL.
624
619
if self . ecx . memory . ptr_may_be_null ( ptr) {
625
- throw_validation_failure ! (
626
- "a potentially NULL pointer" ,
627
- self . path,
628
- format_args!(
620
+ throw_validation_failure ! ( self . path,
621
+ { "a potentially NULL pointer" }
622
+ expected {
629
623
"something that cannot possibly fail to be {}" ,
630
624
wrapping_range_format( valid_range, max_hi)
631
- )
625
+ }
632
626
)
633
627
}
634
628
return Ok ( ( ) ) ;
635
629
} else {
636
630
// Conservatively, we reject, because the pointer *could* have a bad
637
631
// value.
638
- throw_validation_failure ! (
639
- "a pointer" ,
640
- self . path,
641
- format_args!(
632
+ throw_validation_failure ! ( self . path,
633
+ { "a pointer" }
634
+ expected {
642
635
"something that cannot possibly fail to be {}" ,
643
636
wrapping_range_format( valid_range, max_hi)
644
- )
637
+ }
645
638
)
646
639
}
647
640
}
@@ -651,10 +644,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
651
644
if wrapping_range_contains ( & valid_range, bits) {
652
645
Ok ( ( ) )
653
646
} else {
654
- throw_validation_failure ! (
655
- bits,
656
- self . path,
657
- format_args!( "something {}" , wrapping_range_format( valid_range, max_hi) )
647
+ throw_validation_failure ! ( self . path,
648
+ { "{}" , bits }
649
+ expected { "something {}" , wrapping_range_format( valid_range, max_hi) }
658
650
)
659
651
}
660
652
}
@@ -722,10 +714,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
722
714
Ok ( ( ) ) => { }
723
715
Err ( err) => match err. kind {
724
716
err_ub ! ( InvalidDiscriminant ( val) ) => {
725
- throw_validation_failure ! ( val, self . path, "a valid enum discriminant" )
717
+ throw_validation_failure ! ( self . path,
718
+ { "{}" , val } expected { "a valid enum discriminant" }
719
+ )
726
720
}
727
721
err_unsup ! ( ReadPointerAsBytes ) => {
728
- throw_validation_failure ! ( "a pointer" , self . path, "plain (non-pointer) bytes" )
722
+ throw_validation_failure ! ( self . path,
723
+ { "a pointer" } expected { "plain (non-pointer) bytes" }
724
+ )
729
725
}
730
726
// Propagate upwards (that will also check for unexpected errors).
731
727
_ => return Err ( err) ,
@@ -744,9 +740,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
744
740
// MyNewtype and then the scalar in there).
745
741
match op. layout . abi {
746
742
Abi :: Uninhabited => {
747
- throw_validation_failure ! (
748
- format_args!( "a value of uninhabited type {:?}" , op. layout. ty) ,
749
- self . path
743
+ throw_validation_failure ! ( self . path,
744
+ { "a value of uninhabited type {:?}" , op. layout. ty }
750
745
) ;
751
746
}
752
747
Abi :: Scalar ( ref scalar_layout) => {
@@ -840,7 +835,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
840
835
. unwrap ( ) ;
841
836
self . path . push ( PathElem :: ArrayElem ( i) ) ;
842
837
843
- throw_validation_failure ! ( "uninitialized bytes" , self . path )
838
+ throw_validation_failure ! ( self . path , { "uninitialized bytes" } )
844
839
}
845
840
// Propagate upwards (that will also check for unexpected errors).
846
841
_ => return Err ( err) ,
0 commit comments