@@ -15,9 +15,7 @@ use ty::{Ty, layout};
15
15
use ty:: layout:: { Size , Align , LayoutError } ;
16
16
use rustc_target:: spec:: abi:: Abi ;
17
17
18
- use super :: {
19
- Pointer , Lock , AccessKind
20
- } ;
18
+ use super :: Pointer ;
21
19
22
20
use backtrace:: Backtrace ;
23
21
@@ -53,7 +51,7 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
53
51
#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
54
52
pub struct ConstEvalErr < ' tcx > {
55
53
pub span : Span ,
56
- pub error : :: mir:: interpret:: EvalError < ' tcx > ,
54
+ pub error : :: mir:: interpret:: EvalErrorKind < ' tcx , u64 > ,
57
55
pub stacktrace : Vec < FrameInfo > ,
58
56
}
59
57
@@ -112,7 +110,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
112
110
message : & str ,
113
111
lint_root : Option < ast:: NodeId > ,
114
112
) -> Result < DiagnosticBuilder < ' tcx > , ErrorHandled > {
115
- match self . error . kind {
113
+ match self . error {
116
114
EvalErrorKind :: Layout ( LayoutError :: Unknown ( _) ) |
117
115
EvalErrorKind :: TooGeneric => return Err ( ErrorHandled :: TooGeneric ) ,
118
116
EvalErrorKind :: Layout ( LayoutError :: SizeOverflow ( _) ) |
@@ -151,50 +149,74 @@ pub fn struct_error<'a, 'gcx, 'tcx>(
151
149
struct_span_err ! ( tcx. sess, tcx. span, E0080 , "{}" , msg)
152
150
}
153
151
154
- #[ derive( Debug , Clone , RustcEncodable , RustcDecodable ) ]
152
+ #[ derive( Debug , Clone ) ]
155
153
pub struct EvalError < ' tcx > {
156
154
pub kind : EvalErrorKind < ' tcx , u64 > ,
155
+ pub backtrace : Option < Box < Backtrace > > ,
156
+ }
157
+
158
+ impl < ' tcx > EvalError < ' tcx > {
159
+ pub fn print_backtrace ( & mut self ) {
160
+ if let Some ( ref mut backtrace) = self . backtrace {
161
+ eprintln ! ( "{}" , print_backtrace( & mut * backtrace) ) ;
162
+ }
163
+ }
164
+ }
165
+
166
+ fn print_backtrace ( backtrace : & mut Backtrace ) -> String {
167
+ use std:: fmt:: Write ;
168
+
169
+ backtrace. resolve ( ) ;
170
+
171
+ let mut trace_text = "\n \n An error occurred in miri:\n " . to_string ( ) ;
172
+ write ! ( trace_text, "backtrace frames: {}\n " , backtrace. frames( ) . len( ) ) . unwrap ( ) ;
173
+ ' frames: for ( i, frame) in backtrace. frames ( ) . iter ( ) . enumerate ( ) {
174
+ if frame. symbols ( ) . is_empty ( ) {
175
+ write ! ( trace_text, "{}: no symbols\n " , i) . unwrap ( ) ;
176
+ }
177
+ for symbol in frame. symbols ( ) {
178
+ write ! ( trace_text, "{}: " , i) . unwrap ( ) ;
179
+ if let Some ( name) = symbol. name ( ) {
180
+ write ! ( trace_text, "{}\n " , name) . unwrap ( ) ;
181
+ } else {
182
+ write ! ( trace_text, "<unknown>\n " ) . unwrap ( ) ;
183
+ }
184
+ write ! ( trace_text, "\t at " ) . unwrap ( ) ;
185
+ if let Some ( file_path) = symbol. filename ( ) {
186
+ write ! ( trace_text, "{}" , file_path. display( ) ) . unwrap ( ) ;
187
+ } else {
188
+ write ! ( trace_text, "<unknown_file>" ) . unwrap ( ) ;
189
+ }
190
+ if let Some ( line) = symbol. lineno ( ) {
191
+ write ! ( trace_text, ":{}\n " , line) . unwrap ( ) ;
192
+ } else {
193
+ write ! ( trace_text, "\n " ) . unwrap ( ) ;
194
+ }
195
+ }
196
+ }
197
+ trace_text
157
198
}
158
199
159
200
impl < ' tcx > From < EvalErrorKind < ' tcx , u64 > > for EvalError < ' tcx > {
160
201
fn from ( kind : EvalErrorKind < ' tcx , u64 > ) -> Self {
161
- match env:: var ( "MIRI_BACKTRACE" ) {
162
- Ok ( ref val) if !val. is_empty ( ) => {
163
- let backtrace = Backtrace :: new ( ) ;
202
+ let backtrace = match env:: var ( "RUST_CTFE_BACKTRACE" ) {
203
+ // matching RUST_BACKTRACE, we treat "0" the same as "not present".
204
+ Ok ( ref val) if val != "0" => {
205
+ let mut backtrace = Backtrace :: new_unresolved ( ) ;
164
206
165
- use std:: fmt:: Write ;
166
- let mut trace_text = "\n \n An error occurred in miri:\n " . to_string ( ) ;
167
- write ! ( trace_text, "backtrace frames: {}\n " , backtrace. frames( ) . len( ) ) . unwrap ( ) ;
168
- ' frames: for ( i, frame) in backtrace. frames ( ) . iter ( ) . enumerate ( ) {
169
- if frame. symbols ( ) . is_empty ( ) {
170
- write ! ( trace_text, "{}: no symbols\n " , i) . unwrap ( ) ;
171
- }
172
- for symbol in frame. symbols ( ) {
173
- write ! ( trace_text, "{}: " , i) . unwrap ( ) ;
174
- if let Some ( name) = symbol. name ( ) {
175
- write ! ( trace_text, "{}\n " , name) . unwrap ( ) ;
176
- } else {
177
- write ! ( trace_text, "<unknown>\n " ) . unwrap ( ) ;
178
- }
179
- write ! ( trace_text, "\t at " ) . unwrap ( ) ;
180
- if let Some ( file_path) = symbol. filename ( ) {
181
- write ! ( trace_text, "{}" , file_path. display( ) ) . unwrap ( ) ;
182
- } else {
183
- write ! ( trace_text, "<unknown_file>" ) . unwrap ( ) ;
184
- }
185
- if let Some ( line) = symbol. lineno ( ) {
186
- write ! ( trace_text, ":{}\n " , line) . unwrap ( ) ;
187
- } else {
188
- write ! ( trace_text, "\n " ) . unwrap ( ) ;
189
- }
190
- }
207
+ if val == "immediate" {
208
+ // Print it now
209
+ eprintln ! ( "{}" , print_backtrace( & mut backtrace) ) ;
210
+ None
211
+ } else {
212
+ Some ( Box :: new ( backtrace) )
191
213
}
192
- error ! ( "{}" , trace_text) ;
193
214
} ,
194
- _ => { } ,
195
- }
215
+ _ => None ,
216
+ } ;
196
217
EvalError {
197
218
kind,
219
+ backtrace,
198
220
}
199
221
}
200
222
}
@@ -250,29 +272,6 @@ pub enum EvalErrorKind<'tcx, O> {
250
272
required : Align ,
251
273
has : Align ,
252
274
} ,
253
- MemoryLockViolation {
254
- ptr : Pointer ,
255
- len : u64 ,
256
- frame : usize ,
257
- access : AccessKind ,
258
- lock : Lock ,
259
- } ,
260
- MemoryAcquireConflict {
261
- ptr : Pointer ,
262
- len : u64 ,
263
- kind : AccessKind ,
264
- lock : Lock ,
265
- } ,
266
- InvalidMemoryLockRelease {
267
- ptr : Pointer ,
268
- len : u64 ,
269
- frame : usize ,
270
- lock : Lock ,
271
- } ,
272
- DeallocatedLockedMemory {
273
- ptr : Pointer ,
274
- lock : Lock ,
275
- } ,
276
275
ValidationFailure ( String ) ,
277
276
CalledClosureAsFunction ,
278
277
VtableForArgumentlessMethod ,
@@ -336,16 +335,8 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
336
335
"pointer offset outside bounds of allocation" ,
337
336
InvalidNullPointerUsage =>
338
337
"invalid use of NULL pointer" ,
339
- MemoryLockViolation { .. } =>
340
- "memory access conflicts with lock" ,
341
- MemoryAcquireConflict { .. } =>
342
- "new memory lock conflicts with existing lock" ,
343
338
ValidationFailure ( ..) =>
344
339
"type validation failed" ,
345
- InvalidMemoryLockRelease { .. } =>
346
- "invalid attempt to release write lock" ,
347
- DeallocatedLockedMemory { .. } =>
348
- "tried to deallocate memory in conflict with a lock" ,
349
340
ReadPointerAsBytes =>
350
341
"a raw memory access tried to access part of a pointer value as raw bytes" ,
351
342
ReadBytesAsPointer =>
@@ -452,7 +443,13 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
452
443
453
444
impl < ' tcx > fmt:: Display for EvalError < ' tcx > {
454
445
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
455
- write ! ( f, "{:?}" , self . kind)
446
+ write ! ( f, "{}" , self . kind)
447
+ }
448
+ }
449
+
450
+ impl < ' tcx > fmt:: Display for EvalErrorKind < ' tcx , u64 > {
451
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
452
+ write ! ( f, "{:?}" , self )
456
453
}
457
454
}
458
455
@@ -465,22 +462,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
465
462
if access { "memory access" } else { "pointer computed" } ,
466
463
ptr. offset. bytes( ) , ptr. alloc_id, allocation_size. bytes( ) )
467
464
} ,
468
- MemoryLockViolation { ptr, len, frame, access, ref lock } => {
469
- write ! ( f, "{:?} access by frame {} at {:?}, size {}, is in conflict with lock {:?}" ,
470
- access, frame, ptr, len, lock)
471
- }
472
- MemoryAcquireConflict { ptr, len, kind, ref lock } => {
473
- write ! ( f, "new {:?} lock at {:?}, size {}, is in conflict with lock {:?}" ,
474
- kind, ptr, len, lock)
475
- }
476
- InvalidMemoryLockRelease { ptr, len, frame, ref lock } => {
477
- write ! ( f, "frame {} tried to release memory write lock at {:?}, size {}, but \
478
- cannot release lock {:?}", frame, ptr, len, lock)
479
- }
480
- DeallocatedLockedMemory { ptr, ref lock } => {
481
- write ! ( f, "tried to deallocate memory at {:?} in conflict with lock {:?}" ,
482
- ptr, lock)
483
- }
484
465
ValidationFailure ( ref err) => {
485
466
write ! ( f, "type validation failed: {}" , err)
486
467
}
0 commit comments