@@ -47,7 +47,7 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
4747#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
4848pub struct ConstEvalErr < ' tcx > {
4949 pub span : Span ,
50- pub error : crate :: mir:: interpret:: InterpError < ' tcx , u64 > ,
50+ pub error : crate :: mir:: interpret:: InterpError < ' tcx > ,
5151 pub stacktrace : Vec < FrameInfo < ' tcx > > ,
5252}
5353
@@ -185,10 +185,17 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
185185/// macro for this.
186186#[ derive( Debug , Clone ) ]
187187pub struct InterpErrorInfo < ' tcx > {
188- pub kind : InterpError < ' tcx , u64 > ,
188+ pub kind : InterpError < ' tcx > ,
189189 backtrace : Option < Box < Backtrace > > ,
190190}
191191
192+
193+ impl < ' tcx > fmt:: Display for InterpErrorInfo < ' tcx > {
194+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
195+ write ! ( f, "{}" , self . kind)
196+ }
197+ }
198+
192199impl < ' tcx > InterpErrorInfo < ' tcx > {
193200 pub fn print_backtrace ( & mut self ) {
194201 if let Some ( ref mut backtrace) = self . backtrace {
@@ -202,8 +209,8 @@ fn print_backtrace(backtrace: &mut Backtrace) {
202209 eprintln ! ( "\n \n An error occurred in miri:\n {:?}" , backtrace) ;
203210}
204211
205- impl < ' tcx > From < InterpError < ' tcx , u64 > > for InterpErrorInfo < ' tcx > {
206- fn from ( kind : InterpError < ' tcx , u64 > ) -> Self {
212+ impl < ' tcx > From < InterpError < ' tcx > > for InterpErrorInfo < ' tcx > {
213+ fn from ( kind : InterpError < ' tcx > ) -> Self {
207214 let backtrace = match env:: var ( "RUST_CTFE_BACKTRACE" ) {
208215 // Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present".
209216 Ok ( ref val) if val != "0" => {
@@ -226,8 +233,6 @@ impl<'tcx> From<InterpError<'tcx, u64>> for InterpErrorInfo<'tcx> {
226233 }
227234}
228235
229- pub type AssertMessage < ' tcx > = InterpError < ' tcx , mir:: Operand < ' tcx > > ;
230-
231236#[ derive( Clone , RustcEncodable , RustcDecodable , HashStable ) ]
232237pub enum PanicMessage < O > {
233238 Panic {
@@ -244,10 +249,68 @@ pub enum PanicMessage<O> {
244249 OverflowNeg ,
245250 DivisionByZero ,
246251 RemainderByZero ,
252+ GeneratorResumedAfterReturn ,
253+ GeneratorResumedAfterPanic ,
254+ }
255+
256+ /// Type for MIR `Assert` terminator error messages.
257+ pub type AssertMessage < ' tcx > = PanicMessage < mir:: Operand < ' tcx > > ;
258+
259+ impl < O > PanicMessage < O > {
260+ /// Getting a description does not require `O` to be printable, and does not
261+ /// require allocation.
262+ /// The caller is expected to handle `Panic` and `BoundsCheck` separately.
263+ pub fn description ( & self ) -> & ' static str {
264+ use PanicMessage :: * ;
265+ match self {
266+ Overflow ( mir:: BinOp :: Add ) =>
267+ "attempt to add with overflow" ,
268+ Overflow ( mir:: BinOp :: Sub ) =>
269+ "attempt to subtract with overflow" ,
270+ Overflow ( mir:: BinOp :: Mul ) =>
271+ "attempt to multiply with overflow" ,
272+ Overflow ( mir:: BinOp :: Div ) =>
273+ "attempt to divide with overflow" ,
274+ Overflow ( mir:: BinOp :: Rem ) =>
275+ "attempt to calculate the remainder with overflow" ,
276+ OverflowNeg =>
277+ "attempt to negate with overflow" ,
278+ Overflow ( mir:: BinOp :: Shr ) =>
279+ "attempt to shift right with overflow" ,
280+ Overflow ( mir:: BinOp :: Shl ) =>
281+ "attempt to shift left with overflow" ,
282+ Overflow ( op) =>
283+ bug ! ( "{:?} cannot overflow" , op) ,
284+ DivisionByZero =>
285+ "attempt to divide by zero" ,
286+ RemainderByZero =>
287+ "attempt to calculate the remainder with a divisor of zero" ,
288+ GeneratorResumedAfterReturn =>
289+ "generator resumed after completion" ,
290+ GeneratorResumedAfterPanic =>
291+ "generator resumed after panicking" ,
292+ Panic { .. } | BoundsCheck { .. } =>
293+ bug ! ( "Unexpected PanicMessage" ) ,
294+ }
295+ }
296+ }
297+
298+ impl < O : fmt:: Debug > fmt:: Debug for PanicMessage < O > {
299+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
300+ use PanicMessage :: * ;
301+ match self {
302+ Panic { ref msg, line, col, ref file } =>
303+ write ! ( f, "the evaluated program panicked at '{}', {}:{}:{}" , msg, file, line, col) ,
304+ BoundsCheck { ref len, ref index } =>
305+ write ! ( f, "index out of bounds: the len is {:?} but the index is {:?}" , len, index) ,
306+ _ =>
307+ write ! ( f, "{}" , self . description( ) ) ,
308+ }
309+ }
247310}
248311
249312#[ derive( Clone , RustcEncodable , RustcDecodable , HashStable ) ]
250- pub enum InterpError < ' tcx , O > {
313+ pub enum InterpError < ' tcx > {
251314 /// This variant is used by machines to signal their own errors that do not
252315 /// match an existing variant.
253316 MachineError ( String ) ,
@@ -311,7 +374,7 @@ pub enum InterpError<'tcx, O> {
311374 HeapAllocZeroBytes ,
312375 HeapAllocNonPowerOfTwoAlignment ( u64 ) ,
313376 Unreachable ,
314- Panic ( PanicMessage < O > ) ,
377+ Panic ( PanicMessage < u64 > ) ,
315378 ReadFromReturnPointer ,
316379 PathNotFound ( Vec < String > ) ,
317380 UnimplementedTraitSelection ,
@@ -322,28 +385,21 @@ pub enum InterpError<'tcx, O> {
322385 /// Cannot compute this constant because it depends on another one
323386 /// which already produced an error
324387 ReferencedConstant ,
325- GeneratorResumedAfterReturn ,
326- GeneratorResumedAfterPanic ,
327388 InfiniteLoop ,
328389}
329390
330391pub type InterpResult < ' tcx , T = ( ) > = Result < T , InterpErrorInfo < ' tcx > > ;
331392
332- impl < ' tcx > fmt:: Display for InterpErrorInfo < ' tcx > {
333- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
334- write ! ( f, "{}" , self . kind)
335- }
336- }
337-
338- impl < ' tcx > fmt:: Display for InterpError < ' tcx , u64 > {
393+ impl < ' tcx > fmt:: Display for InterpError < ' tcx > {
339394 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
395+ // Forward `Display` to `Debug`
340396 write ! ( f, "{:?}" , self )
341397 }
342398}
343399
344- impl < ' tcx , O : fmt :: Debug > fmt:: Debug for InterpError < ' tcx , O > {
400+ impl < ' tcx > fmt:: Debug for InterpError < ' tcx > {
345401 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
346- use self :: InterpError :: * ;
402+ use InterpError :: * ;
347403 match * self {
348404 PointerOutOfBounds { ptr, msg, allocation_size } => {
349405 write ! ( f, "{} failed: pointer must be in-bounds at offset {}, \
@@ -457,10 +513,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
457513 write ! ( f, "encountered overly generic constant" ) ,
458514 ReferencedConstant =>
459515 write ! ( f, "referenced constant has errors" ) ,
460- GeneratorResumedAfterReturn =>
461- write ! ( f, "generator resumed after completion" ) ,
462- GeneratorResumedAfterPanic =>
463- write ! ( f, "generator resumed after panicking" ) ,
464516 InfiniteLoop =>
465517 write ! ( f, "duplicate interpreter state observed here, const evaluation will never \
466518 terminate") ,
@@ -479,33 +531,8 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
479531 AbiViolation ( ref msg) |
480532 Intrinsic ( ref msg) =>
481533 write ! ( f, "{}" , msg) ,
482-
483- Panic ( PanicMessage :: Panic { ref msg, line, col, ref file } ) =>
484- write ! ( f, "the evaluated program panicked at '{}', {}:{}:{}" , msg, file, line, col) ,
485- Panic ( PanicMessage :: BoundsCheck { ref len, ref index } ) =>
486- write ! ( f, "index out of bounds: the len is {:?} but the index is {:?}" , len, index) ,
487- Panic ( PanicMessage :: Overflow ( mir:: BinOp :: Add ) ) =>
488- write ! ( f, "attempt to add with overflow" ) ,
489- Panic ( PanicMessage :: Overflow ( mir:: BinOp :: Sub ) ) =>
490- write ! ( f, "attempt to subtract with overflow" ) ,
491- Panic ( PanicMessage :: Overflow ( mir:: BinOp :: Mul ) ) =>
492- write ! ( f, "attempt to multiply with overflow" ) ,
493- Panic ( PanicMessage :: Overflow ( mir:: BinOp :: Div ) ) =>
494- write ! ( f, "attempt to divide with overflow" ) ,
495- Panic ( PanicMessage :: Overflow ( mir:: BinOp :: Rem ) ) =>
496- write ! ( f, "attempt to calculate the remainder with overflow" ) ,
497- Panic ( PanicMessage :: OverflowNeg ) =>
498- write ! ( f, "attempt to negate with overflow" ) ,
499- Panic ( PanicMessage :: Overflow ( mir:: BinOp :: Shr ) ) =>
500- write ! ( f, "attempt to shift right with overflow" ) ,
501- Panic ( PanicMessage :: Overflow ( mir:: BinOp :: Shl ) ) =>
502- write ! ( f, "attempt to shift left with overflow" ) ,
503- Panic ( PanicMessage :: Overflow ( op) ) =>
504- bug ! ( "{:?} cannot overflow" , op) ,
505- Panic ( PanicMessage :: DivisionByZero ) =>
506- write ! ( f, "attempt to divide by zero" ) ,
507- Panic ( PanicMessage :: RemainderByZero ) =>
508- write ! ( f, "attempt to calculate the remainder with a divisor of zero" ) ,
534+ Panic ( ref msg) =>
535+ write ! ( f, "{:?}" , msg) ,
509536 }
510537 }
511538}
0 commit comments