@@ -12,8 +12,7 @@ use std::{fmt, env};
1212
1313use mir;
1414use ty:: { Ty , layout} ;
15- use ty:: layout:: { Size , Align } ;
16- use rustc_data_structures:: sync:: Lrc ;
15+ use ty:: layout:: { Size , Align , LayoutError } ;
1716use rustc_target:: spec:: abi:: Abi ;
1817
1918use super :: {
@@ -30,7 +29,26 @@ use syntax_pos::Span;
3029use syntax:: ast;
3130use syntax:: symbol:: Symbol ;
3231
33- pub type ConstEvalResult < ' tcx > = Result < & ' tcx ty:: Const < ' tcx > , Lrc < ConstEvalErr < ' tcx > > > ;
32+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
33+ pub enum ErrorHandled {
34+ /// Already reported a lint or an error for this evaluation
35+ Reported ,
36+ /// Don't emit an error, the evaluation failed because the MIR was generic
37+ /// and the substs didn't fully monomorphize it.
38+ TooGeneric ,
39+ }
40+
41+ impl ErrorHandled {
42+ pub fn assert_reported ( self ) {
43+ match self {
44+ ErrorHandled :: Reported => { } ,
45+ ErrorHandled :: TooGeneric => bug ! ( "MIR interpretation failed without reporting an error \
46+ even though it was fully monomorphized") ,
47+ }
48+ }
49+ }
50+
51+ pub type ConstEvalResult < ' tcx > = Result < & ' tcx ty:: Const < ' tcx > , ErrorHandled > ;
3452
3553#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
3654pub struct ConstEvalErr < ' tcx > {
@@ -50,33 +68,41 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
5068 pub fn struct_error ( & self ,
5169 tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
5270 message : & str )
53- -> Option < DiagnosticBuilder < ' tcx > >
71+ -> Result < DiagnosticBuilder < ' tcx > , ErrorHandled >
5472 {
5573 self . struct_generic ( tcx, message, None )
5674 }
5775
5876 pub fn report_as_error ( & self ,
5977 tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
6078 message : & str
61- ) {
79+ ) -> ErrorHandled {
6280 let err = self . struct_error ( tcx, message) ;
63- if let Some ( mut err) = err {
64- err. emit ( ) ;
81+ match err {
82+ Ok ( mut err) => {
83+ err. emit ( ) ;
84+ ErrorHandled :: Reported
85+ } ,
86+ Err ( err) => err,
6587 }
6688 }
6789
6890 pub fn report_as_lint ( & self ,
6991 tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
7092 message : & str ,
7193 lint_root : ast:: NodeId ,
72- ) {
94+ ) -> ErrorHandled {
7395 let lint = self . struct_generic (
7496 tcx,
7597 message,
7698 Some ( lint_root) ,
7799 ) ;
78- if let Some ( mut lint) = lint {
79- lint. emit ( ) ;
100+ match lint {
101+ Ok ( mut lint) => {
102+ lint. emit ( ) ;
103+ ErrorHandled :: Reported
104+ } ,
105+ Err ( err) => err,
80106 }
81107 }
82108
@@ -85,15 +111,12 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
85111 tcx : TyCtxtAt < ' a , ' gcx , ' tcx > ,
86112 message : & str ,
87113 lint_root : Option < ast:: NodeId > ,
88- ) -> Option < DiagnosticBuilder < ' tcx > > {
114+ ) -> Result < DiagnosticBuilder < ' tcx > , ErrorHandled > {
89115 match self . error . kind {
90- :: mir:: interpret:: EvalErrorKind :: TypeckError |
91- :: mir:: interpret:: EvalErrorKind :: TooGeneric |
92- :: mir:: interpret:: EvalErrorKind :: CheckMatchError |
93- :: mir:: interpret:: EvalErrorKind :: Layout ( _) => return None ,
94- :: mir:: interpret:: EvalErrorKind :: ReferencedConstant ( ref inner) => {
95- inner. struct_generic ( tcx, "referenced constant has errors" , lint_root) ?. emit ( ) ;
96- } ,
116+ EvalErrorKind :: Layout ( LayoutError :: Unknown ( _) ) |
117+ EvalErrorKind :: TooGeneric => return Err ( ErrorHandled :: TooGeneric ) ,
118+ EvalErrorKind :: Layout ( LayoutError :: SizeOverflow ( _) ) |
119+ EvalErrorKind :: TypeckError => return Err ( ErrorHandled :: Reported ) ,
97120 _ => { } ,
98121 }
99122 trace ! ( "reporting const eval failure at {:?}" , self . span) ;
@@ -117,7 +140,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
117140 for FrameInfo { span, location, .. } in & self . stacktrace {
118141 err. span_label ( * span, format ! ( "inside call to `{}`" , location) ) ;
119142 }
120- Some ( err)
143+ Ok ( err)
121144 }
122145}
123146
@@ -279,10 +302,9 @@ pub enum EvalErrorKind<'tcx, O> {
279302 TypeckError ,
280303 /// Resolution can fail if we are in a too generic context
281304 TooGeneric ,
282- CheckMatchError ,
283305 /// Cannot compute this constant because it depends on another one
284306 /// which already produced an error
285- ReferencedConstant ( Lrc < ConstEvalErr < ' tcx > > ) ,
307+ ReferencedConstant ,
286308 GeneratorResumedAfterReturn ,
287309 GeneratorResumedAfterPanic ,
288310 InfiniteLoop ,
@@ -407,9 +429,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
407429 "encountered constants with type errors, stopping evaluation" ,
408430 TooGeneric =>
409431 "encountered overly generic constant" ,
410- CheckMatchError =>
411- "match checking failed" ,
412- ReferencedConstant ( _) =>
432+ ReferencedConstant =>
413433 "referenced constant has errors" ,
414434 Overflow ( mir:: BinOp :: Add ) => "attempt to add with overflow" ,
415435 Overflow ( mir:: BinOp :: Sub ) => "attempt to subtract with overflow" ,
0 commit comments