@@ -14,7 +14,7 @@ use rustc_hir as hir;
1414use rustc_macros:: HashStable ;
1515use rustc_session:: CtfeBacktrace ;
1616use rustc_span:: { def_id:: DefId , Pos , Span } ;
17- use std:: { any:: Any , fmt} ;
17+ use std:: { any:: Any , fmt, mem } ;
1818
1919#[ derive( Debug , Copy , Clone , PartialEq , Eq , HashStable , RustcEncodable , RustcDecodable ) ]
2020pub enum ErrorHandled {
@@ -449,9 +449,6 @@ impl fmt::Debug for UndefinedBehaviorInfo {
449449pub enum UnsupportedOpInfo {
450450 /// Free-form case. Only for errors that are never caught!
451451 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 ) ,
455452 /// Accessing an unsupported foreign static.
456453 ReadForeignStatic ( DefId ) ,
457454 /// Could not find MIR for a function.
@@ -470,9 +467,6 @@ impl fmt::Debug for UnsupportedOpInfo {
470467 use UnsupportedOpInfo :: * ;
471468 match self {
472469 Unsupported ( ref msg) => write ! ( f, "{}" , msg) ,
473- ConstPropUnsupported ( ref msg) => {
474- write ! ( f, "Constant propagation encountered an unsupported situation: {}" , msg)
475- }
476470 ReadForeignStatic ( did) => {
477471 write ! ( f, "tried to read from foreign (extern) static {:?}" , did)
478472 }
@@ -514,6 +508,29 @@ impl fmt::Debug for ResourceExhaustionInfo {
514508 }
515509}
516510
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+
517534pub enum InterpError < ' tcx > {
518535 /// The program caused undefined behavior.
519536 UndefinedBehavior ( UndefinedBehaviorInfo ) ,
@@ -527,7 +544,7 @@ pub enum InterpError<'tcx> {
527544 ResourceExhaustion ( ResourceExhaustionInfo ) ,
528545 /// Stop execution for a machine-controlled reason. This is never raised by
529546 /// the core engine itself.
530- MachineStop ( Box < dyn Any + Send > ) ,
547+ MachineStop ( Box < dyn MachineStopType > ) ,
531548}
532549
533550pub type InterpResult < ' tcx , T = ( ) > = Result < T , InterpErrorInfo < ' tcx > > ;
@@ -547,7 +564,7 @@ impl fmt::Debug for InterpError<'_> {
547564 InvalidProgram ( ref msg) => write ! ( f, "{:?}" , msg) ,
548565 UndefinedBehavior ( ref msg) => write ! ( f, "{:?}" , msg) ,
549566 ResourceExhaustion ( ref msg) => write ! ( f, "{:?}" , msg) ,
550- MachineStop ( _ ) => bug ! ( "unhandled MachineStop" ) ,
567+ MachineStop ( ref msg ) => write ! ( f , "{:?}" , msg ) ,
551568 }
552569 }
553570}
@@ -558,8 +575,9 @@ impl InterpError<'_> {
558575 /// waste of resources.
559576 pub fn allocates ( & self ) -> bool {
560577 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 ( _) )
563581 | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: ValidationFailure ( _) )
564582 | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: Ub ( _) ) => true ,
565583 _ => false ,
0 commit comments