@@ -14,7 +14,7 @@ use rustc_hir as hir;
14
14
use rustc_macros:: HashStable ;
15
15
use rustc_session:: CtfeBacktrace ;
16
16
use rustc_span:: { def_id:: DefId , Pos , Span } ;
17
- use std:: { any:: Any , fmt} ;
17
+ use std:: { any:: Any , fmt, mem } ;
18
18
19
19
#[ derive( Debug , Copy , Clone , PartialEq , Eq , HashStable , RustcEncodable , RustcDecodable ) ]
20
20
pub enum ErrorHandled {
@@ -449,9 +449,6 @@ impl fmt::Debug for UndefinedBehaviorInfo {
449
449
pub enum UnsupportedOpInfo {
450
450
/// Free-form case. Only for errors that are never caught!
451
451
Unsupported ( String ) ,
452
- /// When const-prop encounters a situation it does not support, it raises this error.
453
- /// This must not allocate for performance reasons (hence `str`, not `String`).
454
- ConstPropUnsupported ( & ' static str ) ,
455
452
/// Accessing an unsupported foreign static.
456
453
ReadForeignStatic ( DefId ) ,
457
454
/// Could not find MIR for a function.
@@ -470,9 +467,6 @@ impl fmt::Debug for UnsupportedOpInfo {
470
467
use UnsupportedOpInfo :: * ;
471
468
match self {
472
469
Unsupported ( ref msg) => write ! ( f, "{}" , msg) ,
473
- ConstPropUnsupported ( ref msg) => {
474
- write ! ( f, "Constant propagation encountered an unsupported situation: {}" , msg)
475
- }
476
470
ReadForeignStatic ( did) => {
477
471
write ! ( f, "tried to read from foreign (extern) static {:?}" , did)
478
472
}
@@ -514,6 +508,29 @@ impl fmt::Debug for ResourceExhaustionInfo {
514
508
}
515
509
}
516
510
511
+ /// A trait to work around not having trait object upcasting.
512
+ pub trait AsAny : Any {
513
+ fn as_any ( & self ) -> & dyn Any ;
514
+ }
515
+
516
+ impl < T : Any > AsAny for T {
517
+ #[ inline( always) ]
518
+ fn as_any ( & self ) -> & dyn Any {
519
+ self
520
+ }
521
+ }
522
+
523
+ /// A trait for machine-specific errors (or other "machine stop" conditions).
524
+ pub trait MachineStopType : AsAny + fmt:: Debug + Send { }
525
+ impl MachineStopType for String { }
526
+
527
+ impl dyn MachineStopType {
528
+ #[ inline( always) ]
529
+ pub fn downcast_ref < T : Any > ( & self ) -> Option < & T > {
530
+ self . as_any ( ) . downcast_ref ( )
531
+ }
532
+ }
533
+
517
534
pub enum InterpError < ' tcx > {
518
535
/// The program caused undefined behavior.
519
536
UndefinedBehavior ( UndefinedBehaviorInfo ) ,
@@ -527,7 +544,7 @@ pub enum InterpError<'tcx> {
527
544
ResourceExhaustion ( ResourceExhaustionInfo ) ,
528
545
/// Stop execution for a machine-controlled reason. This is never raised by
529
546
/// the core engine itself.
530
- MachineStop ( Box < dyn Any + Send > ) ,
547
+ MachineStop ( Box < dyn MachineStopType > ) ,
531
548
}
532
549
533
550
pub type InterpResult < ' tcx , T = ( ) > = Result < T , InterpErrorInfo < ' tcx > > ;
@@ -547,7 +564,7 @@ impl fmt::Debug for InterpError<'_> {
547
564
InvalidProgram ( ref msg) => write ! ( f, "{:?}" , msg) ,
548
565
UndefinedBehavior ( ref msg) => write ! ( f, "{:?}" , msg) ,
549
566
ResourceExhaustion ( ref msg) => write ! ( f, "{:?}" , msg) ,
550
- MachineStop ( _ ) => bug ! ( "unhandled MachineStop" ) ,
567
+ MachineStop ( ref msg ) => write ! ( f , "{:?}" , msg ) ,
551
568
}
552
569
}
553
570
}
@@ -558,8 +575,9 @@ impl InterpError<'_> {
558
575
/// waste of resources.
559
576
pub fn allocates ( & self ) -> bool {
560
577
match self {
561
- InterpError :: MachineStop ( _)
562
- | InterpError :: Unsupported ( UnsupportedOpInfo :: Unsupported ( _) )
578
+ // Zero-sized boxes do not allocate.
579
+ InterpError :: MachineStop ( b) => mem:: size_of_val :: < dyn MachineStopType > ( & * * b) > 0 ,
580
+ InterpError :: Unsupported ( UnsupportedOpInfo :: Unsupported ( _) )
563
581
| InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: ValidationFailure ( _) )
564
582
| InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: Ub ( _) ) => true ,
565
583
_ => false ,
0 commit comments