@@ -53,7 +53,7 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
5353#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
5454pub struct ConstEvalErr < ' tcx > {
5555 pub span : Span ,
56- pub error : :: mir:: interpret:: EvalError < ' tcx > ,
56+ pub error : :: mir:: interpret:: EvalErrorKind < ' tcx , u64 > ,
5757 pub stacktrace : Vec < FrameInfo > ,
5858}
5959
@@ -112,7 +112,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
112112 message : & str ,
113113 lint_root : Option < ast:: NodeId > ,
114114 ) -> Result < DiagnosticBuilder < ' tcx > , ErrorHandled > {
115- match self . error . kind {
115+ match self . error {
116116 EvalErrorKind :: Layout ( LayoutError :: Unknown ( _) ) |
117117 EvalErrorKind :: TooGeneric => return Err ( ErrorHandled :: TooGeneric ) ,
118118 EvalErrorKind :: Layout ( LayoutError :: SizeOverflow ( _) ) |
@@ -151,50 +151,74 @@ pub fn struct_error<'a, 'gcx, 'tcx>(
151151 struct_span_err ! ( tcx. sess, tcx. span, E0080 , "{}" , msg)
152152}
153153
154- #[ derive( Debug , Clone , RustcEncodable , RustcDecodable ) ]
154+ #[ derive( Debug , Clone ) ]
155155pub struct EvalError < ' tcx > {
156156 pub kind : EvalErrorKind < ' tcx , u64 > ,
157+ pub backtrace : Option < Box < Backtrace > > ,
158+ }
159+
160+ impl < ' tcx > EvalError < ' tcx > {
161+ pub fn print_backtrace ( & mut self ) {
162+ if let Some ( ref mut backtrace) = self . backtrace {
163+ error ! ( "{}" , print_backtrace( & mut * backtrace) ) ;
164+ }
165+ }
166+ }
167+
168+ fn print_backtrace ( backtrace : & mut Backtrace ) -> String {
169+ use std:: fmt:: Write ;
170+
171+ backtrace. resolve ( ) ;
172+
173+ let mut trace_text = "\n \n An error occurred in miri:\n " . to_string ( ) ;
174+ write ! ( trace_text, "backtrace frames: {}\n " , backtrace. frames( ) . len( ) ) . unwrap ( ) ;
175+ ' frames: for ( i, frame) in backtrace. frames ( ) . iter ( ) . enumerate ( ) {
176+ if frame. symbols ( ) . is_empty ( ) {
177+ write ! ( trace_text, "{}: no symbols\n " , i) . unwrap ( ) ;
178+ }
179+ for symbol in frame. symbols ( ) {
180+ write ! ( trace_text, "{}: " , i) . unwrap ( ) ;
181+ if let Some ( name) = symbol. name ( ) {
182+ write ! ( trace_text, "{}\n " , name) . unwrap ( ) ;
183+ } else {
184+ write ! ( trace_text, "<unknown>\n " ) . unwrap ( ) ;
185+ }
186+ write ! ( trace_text, "\t at " ) . unwrap ( ) ;
187+ if let Some ( file_path) = symbol. filename ( ) {
188+ write ! ( trace_text, "{}" , file_path. display( ) ) . unwrap ( ) ;
189+ } else {
190+ write ! ( trace_text, "<unknown_file>" ) . unwrap ( ) ;
191+ }
192+ if let Some ( line) = symbol. lineno ( ) {
193+ write ! ( trace_text, ":{}\n " , line) . unwrap ( ) ;
194+ } else {
195+ write ! ( trace_text, "\n " ) . unwrap ( ) ;
196+ }
197+ }
198+ }
199+ trace_text
157200}
158201
159202impl < ' tcx > From < EvalErrorKind < ' tcx , u64 > > for EvalError < ' tcx > {
160203 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 ( ) ;
204+ let backtrace = match env:: var ( "RUST_CTFE_BACKTRACE" ) {
205+ // matching RUST_BACKTRACE, we treat "0" the same as "not present".
206+ Ok ( ref val) if val != "0" => {
207+ let mut backtrace = Backtrace :: new_unresolved ( ) ;
164208
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- }
209+ if val == "immediate" {
210+ // Print it now
211+ error ! ( "{}" , print_backtrace( & mut backtrace) ) ;
212+ None
213+ } else {
214+ Some ( Box :: new ( backtrace) )
191215 }
192- error ! ( "{}" , trace_text) ;
193216 } ,
194- _ => { } ,
195- }
217+ _ => None ,
218+ } ;
196219 EvalError {
197220 kind,
221+ backtrace,
198222 }
199223 }
200224}
@@ -452,7 +476,13 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
452476
453477impl < ' tcx > fmt:: Display for EvalError < ' tcx > {
454478 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
455- write ! ( f, "{:?}" , self . kind)
479+ write ! ( f, "{}" , self . kind)
480+ }
481+ }
482+
483+ impl < ' tcx > fmt:: Display for EvalErrorKind < ' tcx , u64 > {
484+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
485+ write ! ( f, "{:?}" , self )
456486 }
457487}
458488
0 commit comments