@@ -47,7 +47,7 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
47
47
#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
48
48
pub struct ConstEvalErr < ' tcx > {
49
49
pub span : Span ,
50
- pub error : crate :: mir:: interpret:: InterpError < ' tcx , u64 > ,
50
+ pub error : crate :: mir:: interpret:: InterpError < ' tcx > ,
51
51
pub stacktrace : Vec < FrameInfo < ' tcx > > ,
52
52
}
53
53
@@ -185,10 +185,17 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
185
185
/// macro for this.
186
186
#[ derive( Debug , Clone ) ]
187
187
pub struct InterpErrorInfo < ' tcx > {
188
- pub kind : InterpError < ' tcx , u64 > ,
188
+ pub kind : InterpError < ' tcx > ,
189
189
backtrace : Option < Box < Backtrace > > ,
190
190
}
191
191
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
+
192
199
impl < ' tcx > InterpErrorInfo < ' tcx > {
193
200
pub fn print_backtrace ( & mut self ) {
194
201
if let Some ( ref mut backtrace) = self . backtrace {
@@ -202,8 +209,8 @@ fn print_backtrace(backtrace: &mut Backtrace) {
202
209
eprintln ! ( "\n \n An error occurred in miri:\n {:?}" , backtrace) ;
203
210
}
204
211
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 {
207
214
let backtrace = match env:: var ( "RUST_CTFE_BACKTRACE" ) {
208
215
// Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present".
209
216
Ok ( ref val) if val != "0" => {
@@ -226,8 +233,6 @@ impl<'tcx> From<InterpError<'tcx, u64>> for InterpErrorInfo<'tcx> {
226
233
}
227
234
}
228
235
229
- pub type AssertMessage < ' tcx > = InterpError < ' tcx , mir:: Operand < ' tcx > > ;
230
-
231
236
#[ derive( Clone , RustcEncodable , RustcDecodable , HashStable ) ]
232
237
pub enum PanicMessage < O > {
233
238
Panic {
@@ -244,10 +249,68 @@ pub enum PanicMessage<O> {
244
249
OverflowNeg ,
245
250
DivisionByZero ,
246
251
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
+ }
247
310
}
248
311
249
312
#[ derive( Clone , RustcEncodable , RustcDecodable , HashStable ) ]
250
- pub enum InterpError < ' tcx , O > {
313
+ pub enum InterpError < ' tcx > {
251
314
/// This variant is used by machines to signal their own errors that do not
252
315
/// match an existing variant.
253
316
MachineError ( String ) ,
@@ -311,7 +374,7 @@ pub enum InterpError<'tcx, O> {
311
374
HeapAllocZeroBytes ,
312
375
HeapAllocNonPowerOfTwoAlignment ( u64 ) ,
313
376
Unreachable ,
314
- Panic ( PanicMessage < O > ) ,
377
+ Panic ( PanicMessage < u64 > ) ,
315
378
ReadFromReturnPointer ,
316
379
PathNotFound ( Vec < String > ) ,
317
380
UnimplementedTraitSelection ,
@@ -322,28 +385,21 @@ pub enum InterpError<'tcx, O> {
322
385
/// Cannot compute this constant because it depends on another one
323
386
/// which already produced an error
324
387
ReferencedConstant ,
325
- GeneratorResumedAfterReturn ,
326
- GeneratorResumedAfterPanic ,
327
388
InfiniteLoop ,
328
389
}
329
390
330
391
pub type InterpResult < ' tcx , T = ( ) > = Result < T , InterpErrorInfo < ' tcx > > ;
331
392
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 > {
339
394
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
395
+ // Forward `Display` to `Debug`
340
396
write ! ( f, "{:?}" , self )
341
397
}
342
398
}
343
399
344
- impl < ' tcx , O : fmt :: Debug > fmt:: Debug for InterpError < ' tcx , O > {
400
+ impl < ' tcx > fmt:: Debug for InterpError < ' tcx > {
345
401
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
346
- use self :: InterpError :: * ;
402
+ use InterpError :: * ;
347
403
match * self {
348
404
PointerOutOfBounds { ptr, msg, allocation_size } => {
349
405
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> {
457
513
write ! ( f, "encountered overly generic constant" ) ,
458
514
ReferencedConstant =>
459
515
write ! ( f, "referenced constant has errors" ) ,
460
- GeneratorResumedAfterReturn =>
461
- write ! ( f, "generator resumed after completion" ) ,
462
- GeneratorResumedAfterPanic =>
463
- write ! ( f, "generator resumed after panicking" ) ,
464
516
InfiniteLoop =>
465
517
write ! ( f, "duplicate interpreter state observed here, const evaluation will never \
466
518
terminate") ,
@@ -479,33 +531,8 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
479
531
AbiViolation ( ref msg) |
480
532
Intrinsic ( ref msg) =>
481
533
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) ,
509
536
}
510
537
}
511
538
}
0 commit comments